repo_sync.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #!/usr/bin/env python
  2. # -*- encoding: utf-8 -*-
  3. '''
  4. @Contact : liuyuqi.gov@msn.cn
  5. @Time : 2023/04/27 03:09:58
  6. @License : Copyright © 2017-2022 liuyuqi. All Rights Reserved.
  7. @Desc : sync utils
  8. '''
  9. import os,csv,re
  10. import logging
  11. from .platform import gen_extractor_classes
  12. from .repo import Repo
  13. from repo_sync.utils.colors import bcolors
  14. class RepoSync(object):
  15. '''
  16. SyncUtils class
  17. '''
  18. repo_list_path = 'repo_list.csv'
  19. def __init__(self, params: dict, debug=False):
  20. self.args = None
  21. self.logger = None
  22. self.init_logger(debug)
  23. self.params = params
  24. self.params['logger'] = self.logger
  25. self.platforms = []
  26. self.repos = []
  27. for p in gen_extractor_classes():
  28. self.platforms.append(p)
  29. if params.get('repo_path', None) is not None:
  30. self.repo_path = params.get('repo_path', None)
  31. self.get_local_repo_list(params.get('repo_path', None))
  32. def get_local_repo_list(self, repo_path):
  33. """get git repo list from a folder"""
  34. if os.path.isdir(repo_path) and os.path.exists(os.path.join(repo_path, '.git')):
  35. self._find_git_repo(
  36. path=repo_path, repo_name=repo_path.split(os.path.sep)[-1])
  37. else:
  38. for dir in os.listdir(repo_path):
  39. current_path = os.path.join(repo_path, dir)
  40. if os.path.isdir(current_path) and os.path.exists(os.path.join(current_path, '.git')):
  41. self._find_git_repo(path=current_path, repo_name=dir)
  42. with open(self.repo_list_path, 'w') as f:
  43. if len(self.repos) == 0:
  44. print(f"{bcolors.WARNING}repo list is empty, please delete repo_list.csv and try again{bcolors.ENDC}")
  45. return
  46. writer = csv.DictWriter(
  47. f, fieldnames=self.repos[0].__dict__.keys(), lineterminator='\n'
  48. )
  49. writer.writeheader()
  50. for repo in self.repos:
  51. writer.writerow(repo.__dict__)
  52. def _find_git_repo(self, path: str, repo_name:str =None):
  53. try:
  54. with open('{}/.git/config'.format(path), 'r') as f:
  55. # get the remote url
  56. repo =Repo()
  57. try:
  58. url = re.findall(r'url\s+=\ (.*)', f.read())[0]
  59. repo.name = repo_name # url.split('/')[-1].replace('.git', '')
  60. repo.url = url
  61. except Exception as e:
  62. repo.name = repo_name
  63. repo.local_path = path
  64. self.repos.append(repo)
  65. except Exception as e:
  66. print(f"{bcolors.OKGREEN}skip {path} because of {e}{bcolors.ENDC}")
  67. def run(self):
  68. '''
  69. run repo
  70. '''
  71. command = self.params.get('command')
  72. platform = self.params.get('platform', 'github')
  73. current_platform = None
  74. for p in self.platforms:
  75. if p.suitable(platform):
  76. current_platform = p
  77. if current_platform is not None:
  78. username = self.params.get(f'{platform}_username', None)
  79. token = self.params.get(f'{platform}_token', None)
  80. host = self.params.get(f'{platform}_host', None)
  81. if command == 'clone':
  82. current_platform(username, token, host, self.params).clone(self.repo_path)
  83. return
  84. if os.path.exists(self.repo_list_path):
  85. with open(self.repo_list_path, 'r', encoding='utf8') as f:
  86. reader = csv.DictReader(f)
  87. for row in reader:
  88. repo = Repo()
  89. repo.__dict__ = row
  90. if command == 'create':
  91. current_platform(username, token, host, self.params).create_repo(repo.name)
  92. if command == 'push':
  93. current_platform(username, token, host, self.params).push(repo.local_path)
  94. elif command == 'delete':
  95. current_platform(username, token, host, self.params).delete(repo.name)
  96. elif command == 'pull':
  97. current_platform(username, token, host, self.params).pull(repo.local_path)
  98. else:
  99. logging.info(
  100. 'repo list is not exist, please run list_local command first'
  101. )
  102. def init_logger(self, debug:bool):
  103. '''
  104. init logger
  105. '''
  106. self.logger = logging.getLogger(__name__)
  107. if debug:
  108. self.logger.setLevel(logging.DEBUG)
  109. else:
  110. self.logger.setLevel(logging.INFO)
  111. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  112. console_handler = logging.StreamHandler()
  113. console_handler.setLevel(logging.DEBUG)
  114. console_handler.setFormatter(formatter)
  115. self.logger.addHandler(console_handler)
  116. def update(self):
  117. '''
  118. update repo_sync software, download and install the latest version
  119. '''
  120. pass