由于经常在公司代码持续集成平台构建代码时候忘记更新版本号,经常浪费一次宝贵的(长长的)构建时间,现在Mac用的工具是 Cornerstone,可以支持 commit 前后执行脚本。所以写了这个脚本,在commit之后执行,用于自动更新版本号到svn。
Usage:
Usage:
1,保证在 terminal 下面可以正常使用 svn 命令提交目标项目代码
2,修改配置常量 TARGET_SRC_ROOT,TARGET_PROJECT_NAMES,TARGET_PLIST_FILES3,根据自己项目需要修改 generate_version_code 逻辑
4,在Cornerstone 的 commit 界面将本脚本设置为提交后执行
# -*- coding: utf-8 -*-
import os
import xml.etree.cElementTree as etree
import datetime
TARGET_SRC_ROOT = "../src"
TARGET_PROJECT_NAMES = ["Demo"]
TARGET_PLIST_FILES = ["Info1.plist", "Info2.plist"]
def get_version_value_node(root):
dict_node = root.find("dict")
if not dict_node:
return False
version_key_node = None
version_value_node = None
for key_value_node in dict_node:
text = key_value_node.text
if text == "CFBundleVersion":
version_key_node = key_value_node
continue
if version_key_node is not None:
version_value_node = key_value_node
break
if version_value_node is None:
return
return version_value_node
def replace_version_code(file_path, old_version_code, new_version_code):
file_content = None
with open(file_path, "rb") as file:
file_content = file.read()
if not isinstance(file_content, str):
return False
file_content = file_content.replace(old_version_code, new_version_code)
with open(file_path, "wb") as file:
file.write(file_content)
return True
# 根据旧的版本号生成新的版本号
# 项目要求格式是 YYMMDD + Build,如 16010102
# 表示 2016 年 1 月 1 日 第二次构建的版本
def generate_version_code(old_version_code):
if not isinstance(old_version_code, str):
return None
if len(old_version_code) != 8:
return None
date_code = old_version_code[0:6]
build_code = old_version_code[6:]
int_build_code = int(build_code)
today = datetime.date.today()
new_date_code = today.strftime("%Y%m%d")
new_date_code = new_date_code[2:]
if new_date_code == date_code:
int_build_code += 1
else:
int_build_code = 1
new_build_code = str(int_build_code).zfill(2)
new_version_code = new_date_code + new_build_code
return new_version_code
def update_version(plist_file_path):
if not isinstance(plist_file_path, str):
return False
xml_tree = etree.ElementTree(file=plist_file_path)
if not xml_tree:
return False
root = xml_tree.getroot()
version_value_node = get_version_value_node(root)
if version_value_node is None:
return False
version_code = version_value_node.text
if not isinstance(version_code, str):
return False
new_version_code = generate_version_code(version_code)
result = replace_version_code(plist_file_path, version_code, new_version_code)
return result
def file_log(message):
current_dir = os.path.realpath(os.path.dirname(__file__))
path = os.path.join(current_dir, "log.txt")
with open(path, "a+") as f:
f.write(message)
f.write("\r\n")
def commit_files(plist_files):
commit_command = """svn ci -m "* auto update version script" """
for plist_file in plist_files:
commit_command += '"' + plist_file + '" '
os.system(commit_command)
file_log("exec command " + commit_command)
def main():
current_dir = os.path.realpath(os.path.dirname(__file__))
plist_files = []
for project_name in TARGET_PROJECT_NAMES:
path = os.path.join(TARGET_SRC_ROOT, project_name)
path = os.path.join(current_dir, path)
for plist_file in TARGET_PLIST_FILES:
plist_path = os.path.join(path, plist_file)
plist_path = os.path.abspath(plist_path)
update_version(plist_path)
plist_files.append(plist_path)
commit_files(plist_files)
if __name__ == '__main__':
main()