Терминальный проект КиберПлат [open source]
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
5.2KB

  1. import io
  2. import os
  3. import argparse
  4. import git # GitPython module
  5. import hashlib
  6. from shutil import copyfile
  7. import pathlib
  8. class PublicFiles(object):
  9. def __init__(self, git_path="."):
  10. files = []
  11. f = open(git_path + '/filelist.txt', 'r')
  12. x = f.readlines()
  13. for l in x:
  14. files.append(l.strip().lower())
  15. self.files = set(files)
  16. self.git_path = git_path
  17. def is_public(self, file):
  18. if file in self.files:
  19. return True
  20. ff = file.split("/")
  21. for i in range(2, len(ff) + 1):
  22. path = "/".join(ff[0:i])
  23. path = path + "/" if self.is_dir(path) else path
  24. if path in self.files:
  25. return True
  26. return False
  27. def is_dir(self, p):
  28. return os.path.isdir(self.git_path + p)
  29. class FileList(object):
  30. def __init__(self, source_path="."):
  31. self.git_repo = git.Repo(source_path, search_parent_directories=True)
  32. self.home_path = source_path.replace(".\\", "/").replace("\\", "/").strip("/")
  33. self.files = {}
  34. for (dirpath, dirnames, filenames) in os.walk(source_path):
  35. path = dirpath.replace(".\\", "/").replace("\\", "/")
  36. for f in filenames:
  37. if path == ".":
  38. self.append_file("/" + f)
  39. else:
  40. self.append_file(path + "/" + f)
  41. def git_sha(self):
  42. return self.git_repo.head.reference.commit.hexsha
  43. def append_file(self, f):
  44. wo_home = self.remove_home_part(f)
  45. self.files[wo_home.lower()] = wo_home
  46. def remove_home_part(self, f):
  47. if f[:len(self.home_path)].lower() == self.home_path.lower():
  48. return f[len(self.home_path):]
  49. return f
  50. def get_files(self):
  51. return set(self.files.keys())
  52. def original_name(self, f):
  53. if f in self.files:
  54. return self.files[f].replace("/", "\\")
  55. else:
  56. return f.replace("/", "\\")
  57. def absolute_path(self, f):
  58. return os.path.abspath(self.home_path + self.original_name(f))
  59. def is_dir(self, p):
  60. return os.path.isdir(self.absolute_path(p))
  61. def remove_file(self, f):
  62. f = self.original_name(f)
  63. print("Remove: {}".format(f))
  64. try:
  65. self.git_repo.index.remove([self.absolute_path(f)])
  66. os.remove(self.absolute_path(f))
  67. except git.exc.GitCommandError:
  68. os.remove(self.absolute_path(f))
  69. def file_content_hash(self, filename):
  70. try:
  71. with open(self.absolute_path(filename), 'rb') as f:
  72. h = hashlib.sha1()
  73. for chunk in iter(lambda: f.read(io.DEFAULT_BUFFER_SIZE), b""):
  74. h.update(chunk)
  75. return h.hexdigest()
  76. except IOError:
  77. return "no-file"
  78. def main(gpl_path, internal_path):
  79. public_files = PublicFiles(gpl_path)
  80. gpl_files = FileList(gpl_path)
  81. internal_files = FileList(internal_path)
  82. removed_counter = 0
  83. updated_counter = 0
  84. dont_changed_counter = 0
  85. print("GPL head: {}".format(gpl_files.git_sha()))
  86. print("Internal head: {}".format(internal_files.git_sha()))
  87. print()
  88. for i in internal_files.get_files():
  89. if public_files.is_public(i):
  90. if gpl_files.file_content_hash(i) != internal_files.file_content_hash(i):
  91. print("Updating {}".format(internal_files.original_name(i)))
  92. dst = gpl_files.absolute_path(internal_files.original_name(i))
  93. pathlib.Path(os.path.dirname(dst)).mkdir(parents=True, exist_ok=True)
  94. copyfile(internal_files.absolute_path(i), dst)
  95. gpl_files.git_repo.index.add([dst])
  96. updated_counter += 1
  97. else:
  98. dont_changed_counter += 1
  99. for f in gpl_files.get_files():
  100. # Удаляем файлы GPL отсутствующие в Internal
  101. if f not in internal_files.files and f not in public_files.files:
  102. gpl_files.remove_file(f)
  103. removed_counter += 1
  104. # Удаляем файлы не подходящие по списку
  105. elif not public_files.is_public(f):
  106. gpl_files.remove_file(f)
  107. removed_counter += 1
  108. print()
  109. print("Files not changed: {}".format(dont_changed_counter))
  110. print("Files removed: {}".format(removed_counter))
  111. print("Files updated: {}".format(updated_counter))
  112. if removed_counter or updated_counter:
  113. message = "refs #1 Syncronizing with {branch} commit: {c}".format(branch="release", c=internal_files.git_sha())
  114. print("Sources changed. Please review changes, commit and push.")
  115. print("Cooment: {}".format(message))
  116. # commit = gpl_files.git_repo.index.commit(message)
  117. #print("Commit GPL repo: {}".format(commit.hexsha))
  118. if __name__ == '__main__':
  119. parser = argparse.ArgumentParser(description='Terminal Client GLP source updater')
  120. parser.add_argument('--gpl', type=str, default= '.', help='GPL source git repo path')
  121. parser.add_argument('--internal', type=str, required=True, help='Internal source git repo path')
  122. args = vars(parser.parse_args())
  123. main(args['gpl'], args['internal'])