abe_setup.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #!/usr/bin/env python3
  2. DEBUG = 1
  3. def main():
  4. global DEBUG
  5. p = parser()
  6. args = p.parse_args()
  7. DEBUG = args.debug
  8. DEBUG = DEBUG - (1 if args.quiet else 0)
  9. print(args) if DEBUG>1 else None
  10. if args.source_url and args.source_url.find('://') < 0 and args.source_url.find( ':' ) > 0:
  11. args.source_url = 'ssh://' + args.source_url.replace( ':', '/', 1)
  12. for ret in recurse_abe_submodules( args.output_dir, args.source_url, args.tag, clone_repo_cached(cache_dir=args.cache_dir)):
  13. pass
  14. def parser():
  15. import argparse
  16. p = argparse.ArgumentParser()
  17. p.add_argument('-d', '--debug', action='count', default=1)
  18. p.add_argument('-q', '--quiet', action='store_true')
  19. p.add_argument('-o', '--output_dir', default='.')
  20. p.add_argument('-c', '--cache_dir', default=None)
  21. p.add_argument('-t', '--tag', default='master')
  22. p.add_argument('-s', '--source_url', default=None)
  23. return p
  24. def recurse_abe_submodules(path, remote, ref=None, func=None):
  25. if func != None:
  26. yield func( path, remote, ref)
  27. subm = get_abe_submodules( path )
  28. import os
  29. import urllib.parse
  30. url = urllib.parse.urlparse(remote)
  31. for su in subm:
  32. newpath = os.path.normpath(os.path.join( path, su.subdir))
  33. newurl = url._replace(path=su.remote).geturl()
  34. print(f"Repo: \"{path}\" has Submodule: \"{newpath}\" Type: \"{su.subtype}\" From: \"{newurl}\"") if DEBUG else None
  35. for ret in recurse_abe_submodules( newpath, newurl, su.ref, func):
  36. yield ret
  37. def cache_path(cache, remote):
  38. import os.path
  39. for url in remote:
  40. return os.path.join( cache, str(url).replace('/','_').replace( '@', '_at_'))
  41. def real_relpath(dest, source='.'):
  42. import os.path
  43. real_dest = os.path.realpath(dest)
  44. real_source = os.path.realpath(source)
  45. return os.path.relpath(real_dest, real_source)
  46. from git import RemoteProgress
  47. class ProgressPrinter(RemoteProgress):
  48. def update(self,op_code,cur_count,max_count=None,message=''):
  49. cur_count_int = round(cur_count)
  50. max_count_int = round(max_count or 100)
  51. print(f"\033[2K{cur_count_int}/{max_count_int}", str(round(100*cur_count / (max_count or 100)))+'%', end="\r")
  52. def clone_repo_cached( cache_dir=None, bare=False):
  53. def clone_repo(path, remote, ref=None, cache_dir=cache_dir, bare=bare):
  54. print('Repo:', path) if DEBUG>1 else None
  55. from git import Repo
  56. repo = Repo.init(path, bare=bare)
  57. if 'origin' in repo.remotes:
  58. origin = repo.remotes['origin']
  59. else:
  60. origin = repo.create_remote('origin', remote)
  61. if cache_dir != None:
  62. cache_repo_path = cache_path(cache_dir, origin.urls)
  63. print('Cacheing from:', cache_repo_path) if DEBUG else None
  64. clone_repo_cached(cache_dir=None, bare=True)( cache_repo_path, remote, ref)
  65. if 'cache' in repo.remotes:
  66. cache = repo.remotes['cache']
  67. else:
  68. cache = repo.create_remote('cache', real_relpath( cache_repo_path, path))
  69. cache.set_url("no_push" , '--push')
  70. cache.fetch(refspec="+refs/remotes/origin/*:refs/remotes/origin/*",progress=ProgressPrinter())
  71. print()
  72. else:
  73. origin.fetch(progress=ProgressPrinter())
  74. print()
  75. if not bare:
  76. print('Refs:', origin.refs) if DEBUG>1 else None
  77. print('Heads:', repo.heads) if DEBUG>1 else None
  78. if ref in repo.tags:
  79. tracking_ref = repo.tags[ref]
  80. active_branch = repo.create_head('local_tag_branch/'+ref, tracking_ref)
  81. elif ref in repo.heads:
  82. tracking_ref = origin.refs[ref]
  83. active_branch = repo.heads[ref]
  84. active_branch.set_tracking_branch(tracking_ref)
  85. elif ref in origin.refs:
  86. tracking_ref = origin.refs[ref]
  87. active_branch = repo.create_head(ref, tracking_ref)
  88. active_branch.set_tracking_branch(tracking_ref)
  89. elif ref in origin.refs:
  90. tracking_ref = origin.refs[ref]
  91. active_branch = repo.create_head(ref, tracking_ref)
  92. active_branch.set_tracking_branch(tracking_ref)
  93. else:
  94. try:
  95. tracking_ref = ref
  96. active_branch = repo.create_head('local_commit_branch/'+tracking_ref, tracking_ref)
  97. except Exception:
  98. raise Exception(f"Branch/Tag/Commit {ref} not found")
  99. print('Active Branch:', active_branch) if DEBUG else None
  100. print('Tracking Ref:', tracking_ref, '\n') if DEBUG else None
  101. active_branch.checkout()
  102. repo.head.reset( tracking_ref, index=True, working_tree=False)
  103. return repo
  104. return clone_repo
  105. from enum import Enum
  106. class AbeSubType(Enum):
  107. SUBMODULE = 1
  108. BOOTLOADER = 2
  109. BSP = 3
  110. class AbeSubmodule():
  111. subtype = AbeSubType.SUBMODULE
  112. def __init__(self, sub_info, subtype=None):
  113. if subtype != None:
  114. self.subtype = subtype
  115. self.subdir = sub_info[0]
  116. self.remote = sub_info[1]
  117. self.ref = sub_info[2]
  118. if self.subtype == AbeSubType.BSP:
  119. self.remote = 'bsp/' + self.remote
  120. if self.subtype == AbeSubType.BOOTLOADER:
  121. self.remote = 'bootloader/' + self.remote
  122. def __repr__(self):
  123. return f"AbeSubmodule(['{self.subdir}','{self.remote}','{self.ref}'], {self.subtype})"
  124. def get_abe_submodules(repo_dir):
  125. import os
  126. import itertools
  127. subfile_generators = []
  128. subfile_path = os.path.join(repo_dir, '.abe', 'submodules')
  129. if os.path.isfile(subfile_path):
  130. subfile_generators.append(parse_abe_subfile(subfile_path, subtype=AbeSubType.SUBMODULE))
  131. bspfile_path = os.path.join(repo_dir, '.abe', 'bsps')
  132. if os.path.isfile(bspfile_path):
  133. subfile_generators.append(parse_abe_subfile(bspfile_path, subtype=AbeSubType.BSP))
  134. bootloaderfile_path = os.path.join(repo_dir, '.abe', 'bootloaders')
  135. if os.path.isfile(bootloaderfile_path):
  136. subfile_generators.append(parse_abe_subfile(bootloaderfile_path, subtype=AbeSubType.BOOTLOADER))
  137. return itertools.chain(*subfile_generators)
  138. def parse_abe_subfile(subfile_path, subtype=AbeSubType.SUBMODULE):
  139. with open(subfile_path) as subfile:
  140. for line in subfile.readlines():
  141. strline = line.strip()
  142. if strline.startswith('#'):
  143. continue
  144. sline = strline.split()
  145. if len(sline) < 3:
  146. continue
  147. print('Submodule:', sline) if DEBUG>1 else None
  148. sub = AbeSubmodule(sline, subtype)
  149. yield sub
  150. if __name__=='__main__':
  151. main()