A VCS repository archival tool
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

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