repo.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. # -*- coding: utf-8 -*-
  2. """
  3. walle-web
  4. :copyright: © 2015-2019 walle-web.io
  5. :created time: 2019-02-24 10:47:53
  6. :author: wushuiyong@walle-web.io
  7. """
  8. import os
  9. import re
  10. import os.path as osp
  11. import getpass
  12. import git as PyGit
  13. from git import Repo as PyRepo
  14. from walle.model.record import RecordModel
  15. class Repo:
  16. '''
  17. @todo
  18. 需要把websocket接入
  19. '''
  20. path = None
  21. def __init__(self, path=None):
  22. self.path = path
  23. def log(self, wenv):
  24. '''
  25. @param wenv:
  26. @param stage:
  27. @param sequence:
  28. @param user_id:
  29. @param task_id:
  30. @param status:
  31. @param host:
  32. @param user:
  33. @param command:
  34. @param success:
  35. @param error:
  36. @return:
  37. '''
  38. RecordModel().save_record(stage=wenv['stage'], sequence=wenv['sequence'], user_id=wenv['user_id'],
  39. task_id=wenv['task_id'], status=exitcode, host='127.0.0.1', user=getpass.getuser(),
  40. command=result.command, success=stdout,
  41. error=stderr)
  42. def websocket(self):
  43. ws_dict = {
  44. 'user': getpass.getuser(),
  45. 'host': '127.0.0.1',
  46. 'cmd': command,
  47. 'status': exitcode,
  48. 'stage': wenv['stage'],
  49. 'sequence': wenv['sequence'],
  50. 'success': stdout,
  51. 'error': stderr,
  52. }
  53. if wenv['console']:
  54. emit('console', {'event': 'task:console', 'data': ws_dict}, room=wenv['task_id'])
  55. pass
  56. def is_git_dir(self):
  57. '''
  58. 判断是否为git目录
  59. @param path:
  60. @return:
  61. '''
  62. d = self.path + '/.git'
  63. if osp.isdir(d):
  64. if osp.isdir(osp.join(d, 'objects')) and osp.isdir(osp.join(d, 'refs')):
  65. headref = osp.join(d, 'HEAD')
  66. return osp.isfile(headref) or \
  67. (osp.islink(headref) and
  68. os.readlink(headref).startswith('refs'))
  69. elif (osp.isfile(osp.join(d, 'gitdir')) and
  70. osp.isfile(osp.join(d, 'commondir')) and
  71. osp.isfile(osp.join(d, 'gitfile'))):
  72. return False
  73. return False
  74. def init(self, url):
  75. # 创建目录
  76. if not os.path.exists(self.path):
  77. os.makedirs(self.path)
  78. # git clone
  79. if self.is_git_dir():
  80. return self.pull()
  81. else:
  82. return self.clone(url)
  83. def clone(self, url):
  84. '''
  85. 检出项目
  86. @param branch:
  87. @param kwargs:
  88. @return:
  89. '''
  90. return PyRepo.clone_from(url, self.path)
  91. def pull(self):
  92. '''
  93. 更新项目
  94. @param branch:
  95. @param kwargs:
  96. @return:
  97. '''
  98. repo = PyRepo(self.path)
  99. return repo.remote().pull()
  100. def checkout_2_branch(self, branch):
  101. '''
  102. 切换到某个分支
  103. @param branch:
  104. @return:
  105. '''
  106. PyRepo(self.path).git.checkout(branch)
  107. def checkout_2_commit(self, branch, commit):
  108. '''
  109. 切换分支的某个commit
  110. @param branch:
  111. @param commit:
  112. @return:
  113. '''
  114. self.checkout_2_branch(branch=branch)
  115. PyRepo(self.path).git.reset('--hard', commit)
  116. def checkout_2_tag(self, tag):
  117. '''
  118. 切换到tag
  119. @param tag:
  120. @return:
  121. '''
  122. PyRepo(self.path).git.checkout(tag)
  123. def branches(self):
  124. '''
  125. 获取所有分支
  126. @param branch:
  127. @param kwargs:
  128. @return:
  129. '''
  130. # 去除 origin/HEAD -> 当前指向
  131. # 去除远端前缀
  132. branches = PyRepo(self.path).remote().refs
  133. # fixbug https://github.com/meolu/walle-web/issues/705
  134. return [str(branch).strip().lstrip('origin').lstrip('/') for branch in branches if
  135. not str(branch).strip().startswith('origin/HEAD')]
  136. def tags(self):
  137. '''
  138. 获取所有tag
  139. @param branch:
  140. @param kwargs:
  141. @return:
  142. '''
  143. return [str(tag) for tag in PyRepo(self.path).tags]
  144. def commits(self, branch):
  145. '''
  146. 获取分支的commits
  147. @param branch:
  148. @param kwargs:
  149. @return:
  150. '''
  151. self.checkout_2_branch(branch)
  152. commit_log = PyGit.Git(self.path).log('--pretty=%h #@_@# %an #@_@# %s', max_count=50)
  153. commit_list = commit_log.split('\n')
  154. commits = []
  155. for commit in commit_list:
  156. if not re.search('^.+ #@_@# .+ #@_@# .*$', commit):
  157. continue
  158. commit_dict = commit.split(' #@_@# ')
  159. from flask import current_app
  160. current_app.logger.info(commit_dict)
  161. commits.append({
  162. 'id': commit_dict[0],
  163. 'name': commit_dict[1],
  164. 'message': commit_dict[2],
  165. })
  166. return commits