123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- # -*- coding:utf-8 -*-
- # 请使用Python 2.7版本运行;
- from __future__ import unicode_literals
- import os
- import re # 正则表达式;
- import sys
- #reload(sys)
- #sys.setdefaultencoding('utf-8')
- 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;
- import shutil
- def copyfile(src_file, dest_file):
- shutil.copy(src_file, dest_file)
- def copyfolder(src_foler, dest_folder):
- if src_folder.endswith(".apk"):
- copyfile(src_foler, dest_folder)
- else:
- src_files = os.listdir(src_foler)
- # 目标路径是否存在,不存在创建;
- if not os.path.exists(dest_folder):
- os.mkdirs(dest_folder)
- for name in src_files:
- copyfile(src_foler+"\\"+name, dest_folder+"\\"+name)
- # 不使用重定向;
- def cmdExecute2(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(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
- 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 revisionInfo(self, revision, url):
- cmd = 'svn info -r %s %s' % (revision, url)
- return cmdExecute(cmd)
- def revisionLog(self, revision, url):
- cmd = 'svn log -r %s %s' % (revision, url)
- return 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 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)
- else:
- cmd = 'svn export %s %s' % (url, dir)
- return 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 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 cmdExecute(cmd)
- def add(self, file):
- # file中文必须是unicode的转gbk;
- cmd = 'svn add %s' % (file)
- return cmdExecute(cmd)
- def commit(self, file, desc):
- # file/desc中文必须是unicode的转gbk;
- cmd = "svn commit -m %s %s" % (desc, file)
- return cmdExecute(cmd)
-
- def status(self, file):
- cmd = "svn status %s"%(file)
- msg = cmdExecute(cmd)
- if msg.startswith("?"): # 不在控制;
- return 0
- elif msg.startswith("A"): # 预加入;
- return 1
- elif msg.startswith("M"): # 已修改;
- return 2
- elif msg.startswith("C"): # 冲突;
- return 3
- elif msg.startswith("K"): # 被锁定;
- return 4
- if __name__ == "__main__":
- print "start main"
- lsvn = localSVN()
- # 注意:中文字符串,必须加u表示unicode;
- debug_dir = u"F:\\Moka-Code\\APK自动编译相关\\debug"
- release_dir = u"F:\\Moka-Code\\APK自动编译相关\\release"
- excelPath = u"F:\\Moka-Code\\APK自动编译相关\\apk-release.xlsx"
- # url地址;
- debug_url = u"https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/01debug/general"
- release_url = u"https://odm-design-center-hz.tclking.com/svn/scbc_apps/trunk/app/apk/02release/general"
- '无则下载有则更新'
- if os.path.exists(debug_dir + "\\.svn"):
- lsvn.update(debug_dir)
- else:
- lsvn.checkout(debug_dir, debug_url)
- '无则下载有则更新'
- if os.path.exists(release_dir + "\\.svn"):
- lsvn.update(release_dir)
- else:
- lsvn.checkout(release_dir, release_url)
- '读取excel表记录'
- excel = ExcelParser(excelPath)
- excel.readExcel()
- print excel.xlsData
- for item in excel.xlsData:
- if item['sqa_result'] == u"释放":
- '获取apk名称'
- apk_name = item['url'][debug_url.__len__() + 1:]
- '更新到释放的版本'
- lsvn.update(debug_dir + "\\" + apk_name, item['apk_revision'])
- '复制到release目录'
- copyfolder(debug_dir + "\\" + apk_name, release_dir + "\\" + apk_name)
- '获取日志'
- log = lsvn.revisionLog(item['apk_revision'], item['url']).decode('gbk')
- listInfo = log.split("\r\n")
- message = listInfo[3]
- '获取状态'
- ret = lsvn.status(release_dir + "\\" + apk_name)
- if ret == 0:
- '添加并提交'
- lsvn.add(release_dir + "\\" + apk_name)
- lsvn.commit(release_dir + "\\" + apk_name, message)
- elif ret == 1 or ret == 2:
- lsvn.commit(release_dir + "\\" + apk_name, message)
- else:
- print "不受控,无法提交"
- # endif
- # endfor
|