app-auto-release.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. # -*- coding:utf-8 -*-
  2. # 请使用Python 2.7版本运行;
  3. from __future__ import unicode_literals
  4. import os
  5. import re # 正则表达式;
  6. import sys
  7. import time
  8. import datetime
  9. import shutil
  10. from basessh2 import baseSSH2
  11. import subprocess
  12. import xlrd
  13. import xlwt
  14. from xlwt import XFStyle, Pattern
  15. import win_subprocess #此版本对应宽字节,subprocess为acssi;
  16. class ExcelParser:
  17. def __init__(self, excelPath):
  18. self.__xlspath = excelPath
  19. self.xlsData = []
  20. def readExcel(self, excelPath=None):
  21. if excelPath is not None:
  22. if type(excelPath) == str:
  23. self.__xlspath = excelPath.decode('utf-8')
  24. '文件是否存在'
  25. if not os.path.exists(self.__xlspath):
  26. return False
  27. '打开excel文件'
  28. wb = xlrd.open_workbook(filename=self.__xlspath)
  29. if wb is None:
  30. return False
  31. '获取所有sheet'
  32. sheet = None
  33. for item in wb.sheet_names():
  34. sheet = wb.sheet_by_name(item)
  35. self.paserExcel(sheet)
  36. def paserExcel(self, sheet):
  37. if sheet.name == "release":
  38. for i in range(1, sheet.nrows):
  39. rowDict = {}
  40. '获取每行内容:url\版本号\debug svn revision\src svn revision\是否释放'
  41. rowData = tuple(sheet.row_values(i))
  42. if rowData.__len__() == 5:
  43. if rowData[0].__len__() > 0:
  44. # 需要去除空格;
  45. rowDict['url'] = rowData[0].strip()
  46. rowDict['apk_version'] = str(rowData[1]).strip()
  47. rowDict['apk_revision'] = str(rowData[2]).strip('.0')
  48. rowDict['src_revision'] = str(rowData[3]).strip('.0')
  49. rowDict['sqa_result'] = rowData[4].strip('.0')
  50. self.xlsData.append(rowDict)
  51. # endif
  52. # endif
  53. # endfor
  54. else:
  55. print u"未找到对应的sheet名称:release"
  56. # 远程服务器SVN操作;
  57. class remoteSVN:
  58. def __init__(self, host, user, pwd):
  59. self.__user = user
  60. self.__pwd = pwd
  61. self.__host = host
  62. self.__ssh2 = baseSSH2()
  63. self.__ssh2.init_ssh2(user, pwd, host)
  64. # 获取指定版本信息;
  65. def getRevisionInfo(self, revision, url):
  66. cmd = 'svn info -r %s %s' % (revision, url)
  67. return self.__ssh2.execute_cmd(cmd)
  68. # 获取指定版本log;
  69. def getRevisionLog(self, revision, url):
  70. cmd = 'svn log -r %s %s' % (revision, url)
  71. return self.__ssh2.execute_cmd(cmd)
  72. # 更新指定目录;
  73. def update(self, dir, revision=''):
  74. if revision.__len__() > 0:
  75. cmd = 'svn up -r %s %s' % (revision, dir)
  76. else:
  77. cmd = 'svn up %s' % (dir)
  78. return self.__ssh2.execute_cmd(cmd)
  79. # 提交指定目录;
  80. def commit(self):
  81. pass
  82. # 本地SVN操作,必须安装命令行;
  83. class localSVN:
  84. def __init__(self):
  85. print 'local svn'
  86. # 不使用重定向;
  87. def __cmdExecute2(self, cmd):
  88. # 定义文件名称;
  89. file_name = str(time.time())
  90. # 输出到文件中;
  91. cmd = cmd + ' >> ' + file_name
  92. print u'执行cmd:', cmd
  93. proc = subprocess.Popen(cmd, shell=True)
  94. # 等待完成;
  95. proc.wait()
  96. # 读取文件内容;
  97. data = ''
  98. with open(file_name, mode="rb") as f:
  99. data = f.read()
  100. os.remove(file_name)
  101. print u"cmd结果:", data
  102. return data
  103. def __cmdExecute(self, cmd):
  104. print u'执行cmd:', cmd
  105. proc = win_subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  106. # 等待完成;
  107. stdout, stderr = proc.communicate()
  108. if proc.returncode == 0:
  109. print u'执行成功'
  110. # 返回执行结果;
  111. # print u"__cmdExecute结果:%s" % stdout
  112. return stdout
  113. def revisionInfo(self, revision, url):
  114. cmd = 'svn info -r %s %s' % (revision, url)
  115. return self.__cmdExecute(cmd)
  116. def revisionLog(self, revision, url):
  117. cmd = 'svn log -r %s %s' % (revision, url)
  118. return self.__cmdExecute(cmd)
  119. def checkout(self, dir, url, revision=''):
  120. # dir中文必须是unicode的转gbk;
  121. if revision.__len__() > 0:
  122. cmd = 'svn co -r %s %s %s' % (revision, url, dir)
  123. else:
  124. cmd = 'svn co %s %s' % (url, dir)
  125. return self.__cmdExecute(cmd)
  126. def export(self, dir, url, revision=''):
  127. # dir中文必须是unicode的转gbk;
  128. if revision.__len__() > 0:
  129. cmd = 'svn export -r %s %s %s' % (revision, url, dir.encode("gbk"))
  130. else:
  131. cmd = 'svn export %s %s' % (url, dir.encode("gbk"))
  132. return self.__cmdExecute(cmd)
  133. def update(self, dir, revision=''): # revision只有根目录才有效,即有.svn的目录才有效;
  134. dir = dir.replace('\\', '/')
  135. # dir中文必须是unicode的转gbk;
  136. if revision.__len__() > 0:
  137. cmd = 'svn up %s -r %s' % (dir, revision)
  138. else:
  139. cmd = 'svn up %s' % (dir)
  140. return self.__cmdExecute(cmd)
  141. def revert(self, dir, revision=''):
  142. # dir中文必须是unicode的转gbk;
  143. if revision.__len__() > 0:
  144. cmd = 'svn revert -r %s %s' % (revision, dir)
  145. else:
  146. cmd = 'svn revert %s' % (dir)
  147. return self.__cmdExecute(cmd.encode("gbk"))
  148. def add(self, file):
  149. # file中文必须是unicode的转gbk;
  150. cmd = 'svn add %s' % (file.encode("gbk"))
  151. return self.__cmdExecute(cmd)
  152. def commit(self, file, desc):
  153. # file/desc中文必须是unicode的转gbk;
  154. cmd = "svn commit -m %s %s" % (desc.encode("gbk"), file.encode("gbk"))
  155. return self.__cmdExecute(cmd)
  156. if __name__ == "__main__":
  157. print "start main"
  158. if 1:
  159. 'checkout或更新代码'
  160. lsvn = localSVN()
  161. # 注意:中文字符串,必须加u表示unicode;
  162. debug_dir = u"F:\\Moka-Code\\APK自动编译相关\\debug"
  163. debug_url = u"https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/01debug/general"
  164. release_dir = u"F:\\Moka-Code\\APK自动编译相关\\release"
  165. release_url = u"https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/02release/general"
  166. '先Clean'
  167. if os.path.exists(debug_dir + "\\.svn"):
  168. lsvn.update(debug_dir)
  169. else:
  170. lsvn.checkout(debug_dir, debug_url)
  171. '先Clean'
  172. if os.path.exists(release_dir + "\\.svn"):
  173. lsvn.update(release_dir)
  174. else:
  175. lsvn.checkout(release_dir, release_url)
  176. '读取excel表记录'
  177. excel = ExcelParser(u"F:\\Moka-Code\\APK自动编译相关\\apk-release.xlsx")
  178. excel.readExcel()
  179. print excel.xlsData
  180. for item in excel.xlsData:
  181. if item['sqa_result'] == u"释放":
  182. '获取apk名称'
  183. apk_name = item['url'][debug_url.__len__() + 1:-1]
  184. '更新到释放的版本'
  185. # lsvn.revert(debug_dir+"\\"+apk_name, item['apk_revision'])
  186. lsvn.update(debug_dir + "\\" + apk_name, item['apk_revision'])
  187. # endif
  188. # endfor
  189. # endfor
  190. if 0:
  191. rsvn = remoteSVN("10.201.44.65", "app", "app2021")
  192. # bolean, data = getRevisionLog('10168', 'https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/01debug/general/TVMeetingMode')
  193. # bolean,data = update('/home/data/ApkAutoCompile/cacheAPK/general$', '10168')
  194. bolean, data = rsvn.update('/home/data/ApkAutoCompile/cacheAPK/general$')
  195. print data
  196. if 0:
  197. lsvn = localSVN()
  198. # data = lsvn.checkout(u'F:\\Moka-Code\\APK自动编译相关\\general','https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/01debug/general','10168')
  199. # data = lsvn.export(u'F:\\Moka-Code\\APK自动编译相关\\general','https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/01debug/general')
  200. # time.sleep(10)
  201. # data = lsvn.update(u'F:\\Moka-Code\\APK自动编译相关\\general', '10168')
  202. # data = lsvn.update(u'F:\\Moka-Code\\APK自动编译相关\\general', '')
  203. data = lsvn.add(u'F:\\Moka-Code\\APK自动编译相关\\general\\1.txt')
  204. data = lsvn.commit(u'F:\\Moka-Code\\APK自动编译相关\\general\\1.txt', u'测试')
  205. print data