A VCS repository archival tool
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

56 řádky
1.8 KiB

  1. import codearchiver.core
  2. import datetime
  3. import logging
  4. import os.path
  5. import shutil
  6. import subprocess
  7. logger = logging.getLogger(__name__)
  8. class Git(codearchiver.core.Module):
  9. @staticmethod
  10. def matches(inputUrl):
  11. return inputUrl.url.endswith('.git')
  12. def __init__(self, inputUrl, extraBranches = {}):
  13. super().__init__(inputUrl)
  14. self._extraBranches = extraBranches
  15. def process(self):
  16. directory = self._url.rsplit('/', 1)[1]
  17. if os.path.exists(directory):
  18. logger.fatal(f'{directory!r} already exists')
  19. return
  20. startTime = datetime.datetime.utcnow()
  21. bundle = f'{self._url.replace("/", "_")}.{startTime:%Y%m%dT%H%M%SZ}.bundle'
  22. if os.path.exists(bundle):
  23. logger.fatal(f'{bundle!r} already exists')
  24. return
  25. logger.info(f'Cloning {self._url} into {directory}')
  26. subprocess.run(['git', 'clone', '--verbose', '--mirror', self._url, directory], check = True)
  27. if self._extraBranches:
  28. for branch, commit in self._extraBranches.items():
  29. logger.info(f'Fetching commit {commit} as {branch}')
  30. r = subprocess.run(['git', 'fetch', '--verbose', 'origin', commit], cwd = directory)
  31. if r.returncode == 0:
  32. r2 = subprocess.run(['git', 'update-ref', f'refs/codearchiver/{branch}', commit, ''], cwd = directory)
  33. if r2.returncode != 0:
  34. logger.error(f'Failed to update-ref refs/codearchiver/{branch} to {commit}')
  35. else:
  36. logger.error(f'Failed to fetch {commit}')
  37. logger.info(f'Bundling into {bundle}')
  38. subprocess.run(['git', 'bundle', 'create', f'../{bundle}', '--all'], cwd = directory, check = True)
  39. logger.info(f'Removing clone')
  40. shutil.rmtree(directory)
  41. return codearchiver.core.Result(id = f'git-{bundle[:-7]}', files = [bundle])
  42. def __repr__(self):
  43. return f'{type(self).__module__}.{type(self).__name__}({self._inputUrl!r}, extraBranches = {self._extraBranches!r})'