git.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. # -*- coding: utf-8 -*-
  2. import collections
  3. import subprocess
  4. import re
  5. from . import sphinx
  6. VersionRef = collections.namedtuple('VersionRef', [
  7. 'name',
  8. 'source',
  9. 'refname',
  10. 'version',
  11. 'release',
  12. ])
  13. def get_refs(gitroot):
  14. cmd = ("git", "for-each-ref", "--format", "%(refname)", "refs")
  15. output = subprocess.check_output(cmd, cwd=gitroot).decode()
  16. for line in output.splitlines():
  17. refname = line.strip()
  18. # Parse refname
  19. matchobj = re.match(r"^refs/(heads|tags|remotes/[^/]+)/(\S+)$", refname)
  20. if not matchobj:
  21. continue
  22. source = matchobj.group(1)
  23. name = matchobj.group(2)
  24. yield (name, source, refname)
  25. def get_conf(gitroot, refname, confpath):
  26. objectname = "{}:{}".format(refname, confpath)
  27. cmd = ("git", "show", objectname)
  28. return subprocess.check_output(cmd, cwd=gitroot).decode()
  29. def find_versions(gitroot, confpath, tag_whitelist, branch_whitelist, remote_whitelist):
  30. for name, source, refname in get_refs(gitroot):
  31. if source == 'tags':
  32. if tag_whitelist is None or not re.match(tag_whitelist, name):
  33. continue
  34. elif source == 'heads':
  35. if branch_whitelist is None or not re.match(branch_whitelist, name):
  36. continue
  37. elif remote_whitelist is not None and re.match(remote_whitelist, source):
  38. if branch_whitelist is None or not re.match(branch_whitelist, name):
  39. continue
  40. else:
  41. continue
  42. conf = get_conf(gitroot, refname, confpath)
  43. config = sphinx.parse_conf(conf)
  44. version = config['version']
  45. release = config['release']
  46. yield VersionRef(name, source, refname, version, release)
  47. def shallow_clone(src, dst, branch):
  48. cmd = ("git", "clone", "--no-hardlinks", "--single-branch", "--depth", "1",
  49. "--branch", branch, src, dst)
  50. subprocess.check_call(cmd)