|
@@ -0,0 +1,235 @@
|
|
|
+# -*- coding:utf-8 -*-
|
|
|
+# 请使用Python 2.7版本运行;
|
|
|
+from __future__ import unicode_literals
|
|
|
+import os
|
|
|
+import re # 正则表达式;
|
|
|
+import sys
|
|
|
+import time
|
|
|
+import datetime
|
|
|
+import shutil
|
|
|
+from basessh2 import baseSSH2
|
|
|
+import subprocess
|
|
|
+import xlrd
|
|
|
+import xlwt
|
|
|
+from xlwt import XFStyle, Pattern
|
|
|
+import win_subprocess #此版本对应宽字节,subprocess为acssi;
|
|
|
+
|
|
|
+class ExcelParser:
|
|
|
+ def __init__(self, excelPath):
|
|
|
+ self.__xlspath = excelPath
|
|
|
+ self.xlsData = []
|
|
|
+
|
|
|
+ def readExcel(self, excelPath=None):
|
|
|
+ if excelPath is not None:
|
|
|
+ if type(excelPath) == str:
|
|
|
+ self.__xlspath = excelPath.decode('utf-8')
|
|
|
+
|
|
|
+ '文件是否存在'
|
|
|
+ if not os.path.exists(self.__xlspath):
|
|
|
+ return False
|
|
|
+
|
|
|
+ '打开excel文件'
|
|
|
+ wb = xlrd.open_workbook(filename=self.__xlspath)
|
|
|
+ if wb is None:
|
|
|
+ return False
|
|
|
+
|
|
|
+ '获取所有sheet'
|
|
|
+ sheet = None
|
|
|
+ for item in wb.sheet_names():
|
|
|
+ sheet = wb.sheet_by_name(item)
|
|
|
+ self.paserExcel(sheet)
|
|
|
+
|
|
|
+ def paserExcel(self, sheet):
|
|
|
+ if sheet.name == "release":
|
|
|
+ for i in range(1, sheet.nrows):
|
|
|
+ rowDict = {}
|
|
|
+ '获取每行内容:url\版本号\debug svn revision\src svn revision\是否释放'
|
|
|
+ rowData = tuple(sheet.row_values(i))
|
|
|
+ if rowData.__len__() == 5:
|
|
|
+ if rowData[0].__len__() > 0:
|
|
|
+ # 需要去除空格;
|
|
|
+ rowDict['url'] = rowData[0].strip()
|
|
|
+ rowDict['apk_version'] = str(rowData[1]).strip()
|
|
|
+ rowDict['apk_revision'] = str(rowData[2]).strip('.0')
|
|
|
+ rowDict['src_revision'] = str(rowData[3]).strip('.0')
|
|
|
+ rowDict['sqa_result'] = rowData[4].strip('.0')
|
|
|
+ self.xlsData.append(rowDict)
|
|
|
+ # endif
|
|
|
+ # endif
|
|
|
+ # endfor
|
|
|
+ else:
|
|
|
+ print u"未找到对应的sheet名称:release"
|
|
|
+
|
|
|
+
|
|
|
+# 远程服务器SVN操作;
|
|
|
+class remoteSVN:
|
|
|
+ def __init__(self, host, user, pwd):
|
|
|
+ self.__user = user
|
|
|
+ self.__pwd = pwd
|
|
|
+ self.__host = host
|
|
|
+ self.__ssh2 = baseSSH2()
|
|
|
+ self.__ssh2.init_ssh2(user, pwd, host)
|
|
|
+
|
|
|
+ # 获取指定版本信息;
|
|
|
+ def getRevisionInfo(self, revision, url):
|
|
|
+ cmd = 'svn info -r %s %s' % (revision, url)
|
|
|
+ return self.__ssh2.execute_cmd(cmd)
|
|
|
+
|
|
|
+ # 获取指定版本log;
|
|
|
+ def getRevisionLog(self, revision, url):
|
|
|
+ cmd = 'svn log -r %s %s' % (revision, url)
|
|
|
+ return self.__ssh2.execute_cmd(cmd)
|
|
|
+
|
|
|
+ # 更新指定目录;
|
|
|
+ def update(self, dir, revision=''):
|
|
|
+ if revision.__len__() > 0:
|
|
|
+ cmd = 'svn up -r %s %s' % (revision, dir)
|
|
|
+ else:
|
|
|
+ cmd = 'svn up %s' % (dir)
|
|
|
+ return self.__ssh2.execute_cmd(cmd)
|
|
|
+
|
|
|
+ # 提交指定目录;
|
|
|
+ def commit(self):
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+# 本地SVN操作,必须安装命令行;
|
|
|
+class localSVN:
|
|
|
+ def __init__(self):
|
|
|
+ print 'local svn'
|
|
|
+
|
|
|
+ # 不使用重定向;
|
|
|
+ def __cmdExecute2(self, cmd):
|
|
|
+ # 定义文件名称;
|
|
|
+ file_name = str(time.time())
|
|
|
+ # 输出到文件中;
|
|
|
+ cmd = cmd + ' >> ' + file_name
|
|
|
+ print u'执行cmd:', cmd
|
|
|
+ proc = subprocess.Popen(cmd, shell=True)
|
|
|
+ # 等待完成;
|
|
|
+ proc.wait()
|
|
|
+ # 读取文件内容;
|
|
|
+ data = ''
|
|
|
+ with open(file_name, mode="rb") as f:
|
|
|
+ data = f.read()
|
|
|
+
|
|
|
+ os.remove(file_name)
|
|
|
+ print u"cmd结果:", data
|
|
|
+ return data
|
|
|
+
|
|
|
+ def __cmdExecute(self, cmd):
|
|
|
+ print u'执行cmd:', cmd
|
|
|
+ proc = win_subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
|
+ # 等待完成;
|
|
|
+ stdout, stderr = proc.communicate()
|
|
|
+ if proc.returncode == 0:
|
|
|
+ print u'执行成功'
|
|
|
+ # 返回执行结果;
|
|
|
+ # print u"__cmdExecute结果:%s" % stdout
|
|
|
+ return stdout
|
|
|
+
|
|
|
+ def revisionInfo(self, revision, url):
|
|
|
+ cmd = 'svn info -r %s %s' % (revision, url)
|
|
|
+ return self.__cmdExecute(cmd)
|
|
|
+
|
|
|
+ def revisionLog(self, revision, url):
|
|
|
+ cmd = 'svn log -r %s %s' % (revision, url)
|
|
|
+ return self.__cmdExecute(cmd)
|
|
|
+
|
|
|
+ def checkout(self, dir, url, revision=''):
|
|
|
+ # dir中文必须是unicode的转gbk;
|
|
|
+ if revision.__len__() > 0:
|
|
|
+ cmd = 'svn co -r %s %s %s' % (revision, url, dir)
|
|
|
+ else:
|
|
|
+ cmd = 'svn co %s %s' % (url, dir)
|
|
|
+ return self.__cmdExecute(cmd)
|
|
|
+
|
|
|
+ def export(self, dir, url, revision=''):
|
|
|
+ # dir中文必须是unicode的转gbk;
|
|
|
+ if revision.__len__() > 0:
|
|
|
+ cmd = 'svn export -r %s %s %s' % (revision, url, dir.encode("gbk"))
|
|
|
+ else:
|
|
|
+ cmd = 'svn export %s %s' % (url, dir.encode("gbk"))
|
|
|
+ return self.__cmdExecute(cmd)
|
|
|
+
|
|
|
+ def update(self, dir, revision=''): # revision只有根目录才有效,即有.svn的目录才有效;
|
|
|
+ dir = dir.replace('\\', '/')
|
|
|
+ # dir中文必须是unicode的转gbk;
|
|
|
+ if revision.__len__() > 0:
|
|
|
+ cmd = 'svn up %s -r %s' % (dir, revision)
|
|
|
+ else:
|
|
|
+ cmd = 'svn up %s' % (dir)
|
|
|
+ return self.__cmdExecute(cmd)
|
|
|
+
|
|
|
+ def revert(self, dir, revision=''):
|
|
|
+ # dir中文必须是unicode的转gbk;
|
|
|
+ if revision.__len__() > 0:
|
|
|
+ cmd = 'svn revert -r %s %s' % (revision, dir)
|
|
|
+ else:
|
|
|
+ cmd = 'svn revert %s' % (dir)
|
|
|
+ return self.__cmdExecute(cmd.encode("gbk"))
|
|
|
+
|
|
|
+ def add(self, file):
|
|
|
+ # file中文必须是unicode的转gbk;
|
|
|
+ cmd = 'svn add %s' % (file.encode("gbk"))
|
|
|
+ return self.__cmdExecute(cmd)
|
|
|
+
|
|
|
+ def commit(self, file, desc):
|
|
|
+ # file/desc中文必须是unicode的转gbk;
|
|
|
+ cmd = "svn commit -m %s %s" % (desc.encode("gbk"), file.encode("gbk"))
|
|
|
+ return self.__cmdExecute(cmd)
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ print "start main"
|
|
|
+ if 1:
|
|
|
+ 'checkout或更新代码'
|
|
|
+ lsvn = localSVN()
|
|
|
+ # 注意:中文字符串,必须加u表示unicode;
|
|
|
+ debug_dir = u"F:\\Moka-Code\\APK自动编译相关\\debug"
|
|
|
+ debug_url = u"https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/01debug/general"
|
|
|
+ release_dir = u"F:\\Moka-Code\\APK自动编译相关\\release"
|
|
|
+ release_url = u"https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/02release/general"
|
|
|
+ '先Clean'
|
|
|
+ if os.path.exists(debug_dir + "\\.svn"):
|
|
|
+ lsvn.update(debug_dir)
|
|
|
+ else:
|
|
|
+ lsvn.checkout(debug_dir, debug_url)
|
|
|
+
|
|
|
+ '先Clean'
|
|
|
+ if os.path.exists(release_dir + "\\.svn"):
|
|
|
+ lsvn.update(release_dir)
|
|
|
+ else:
|
|
|
+ lsvn.checkout(release_dir, release_url)
|
|
|
+
|
|
|
+ '读取excel表记录'
|
|
|
+ excel = ExcelParser(u"F:\\Moka-Code\\APK自动编译相关\\apk-release.xlsx")
|
|
|
+ excel.readExcel()
|
|
|
+ print excel.xlsData
|
|
|
+ for item in excel.xlsData:
|
|
|
+ if item['sqa_result'] == u"释放":
|
|
|
+ '获取apk名称'
|
|
|
+ apk_name = item['url'][debug_url.__len__() + 1:-1]
|
|
|
+ '更新到释放的版本'
|
|
|
+ # lsvn.revert(debug_dir+"\\"+apk_name, item['apk_revision'])
|
|
|
+ lsvn.update(debug_dir + "\\" + apk_name, item['apk_revision'])
|
|
|
+ # endif
|
|
|
+ # endfor
|
|
|
+
|
|
|
+ # endfor
|
|
|
+ if 0:
|
|
|
+ rsvn = remoteSVN("10.201.44.65", "app", "app2021")
|
|
|
+ # bolean, data = getRevisionLog('10168', 'https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/01debug/general/TVMeetingMode')
|
|
|
+ # bolean,data = update('/home/data/ApkAutoCompile/cacheAPK/general$', '10168')
|
|
|
+ bolean, data = rsvn.update('/home/data/ApkAutoCompile/cacheAPK/general$')
|
|
|
+ print data
|
|
|
+ if 0:
|
|
|
+ lsvn = localSVN()
|
|
|
+ # 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')
|
|
|
+ # data = lsvn.export(u'F:\\Moka-Code\\APK自动编译相关\\general','https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/01debug/general')
|
|
|
+ # time.sleep(10)
|
|
|
+ # data = lsvn.update(u'F:\\Moka-Code\\APK自动编译相关\\general', '10168')
|
|
|
+ # data = lsvn.update(u'F:\\Moka-Code\\APK自动编译相关\\general', '')
|
|
|
+ data = lsvn.add(u'F:\\Moka-Code\\APK自动编译相关\\general\\1.txt')
|
|
|
+ data = lsvn.commit(u'F:\\Moka-Code\\APK自动编译相关\\general\\1.txt', u'测试')
|
|
|
+ print data
|