有时候会有这样的情况,策划拿着应用过来提一个bug,但我们却不好确定策划的手机上装的应用对应的是那个代码版本。
为了解决这个问题,我们希望能在应用上显示出当前应用所对应的代码版本,即svn版本。
构想了下,希望最后达到的效果有:
自动化,不需要每次编译版本的时候有人为的步骤,比如编版本的时候人为修改某个值或者点击某个脚本。
跨平台,对外发布的win32/iOS/Android版本都能正确表现
全面性,无论用Windows上用vs开发/Mac OS上用XCode/Eclipse来进行开发,无论是Debug调试时还是发布各种平台包时,都能显示当前使用的代码版本。
思路如下
1. svn版本的自动取得和存储:
在svn管理的代码目录下运行svn info,可以看到一系列信息,其中和版本信息有关的有两个:Revision和Last Changed Rev。
Revision是本地的版本号,Last Changed Rev是限定在选定当前目录下的修改版本号。根据需要,这里选择取用Last Changed Rev
用脚本可以取得版本号数据,并保存在程序可以取用到的目录。
2. 自动化:
可以通过各种IDE的build event来做,也可以通过svn客户端的某些功能,比如TortoiseSVN的Hook scripts[1],但实际使用发现:
1). TortoiseSVN的Hook scripts 如果在顶层目录update,不会触发内部源码目录的update Hook。
2). Mac上的Versions未发现类似功能
且我不希望这个版本号数据文件被放到svn来管理。于是决定用各个IDE的编译事件。
a. VS的设置方法如图: VS_Setting.png
PreBuildScript.bat
@echo off set src_dir=%~dp0.. echo %src_dir% set keyword="Last Changed Rev" for /f "delims=" %%i in ('svn info %src_dir% ^| findstr /C:%keyword%') do set rev=%%i echo %rev% set rev=%rev:~18% @echo on echo %rev% > %src_dir%/CMWar_2dx/Resources/gen/Rev.gen
b. XCode的设置,可以使用Build > Pre-actions[2],但发现如果在Build里面设置,在直接点Run调试的时候不执行,设置多个地方感觉很不优雅,最终决定在Build Phases中设置
设置方法参考链接[3]中添加脚本一节,特别注意,"Run Script 栏,将其移动到列表的第二个位置",这个决定了脚本执行的时机是在编译前还是编译后。
XCodePreBuildScript.sh
#XCodePreBuildScript.sh #Ruoqian, Chen<[email protected]> #2014/7/25 path=$(dirname $0) #gen rev src_dir=$path/../CMWar_2dx echo src_dir $src_dir rev=`svn info $src_dir | awk -F ':' '{ if($1 ~ /^Last Changed Rev$/) {print $2} }' | tr -d " "` res_dir=$src_dir/CMWar_2dx/Resources/ echo rev $rev echo $rev > $res_dir/gen/Rev.gen #for xcode update bug #find $res_dir -type d -exec touch -cm {} \; touch -cm $res_dir/ini $res_dir/gen $res_dir/script
c. Eclipse版本,由于项目是2dx的游戏,Builder中调用了build_native.sh来执行编译,在合适的地方加入以下代码就好
GEN_PATH="$APP_ANDROID_ROOT"/assets/gen if [ ! -d "$GEN_PATH" ]; then mkdir "$GEN_PATH" fi version=`svn info ../../CMWar_2dx | awk -F ':' '{ if($1 ~ /^Last Changed Rev$/) {print $2} }' | tr -d " "` echo $version > "$GEN_PATH"/Rev.gen
3. 由于各IDE编译前将版本信息写入了Rev.gen,程序中只需要读取Rev.gen的数据并显示就好了。这样就达到了自动化显示当前代码版本号的目的。但SVN发生Update等操作时候,代码目录的Last Changed Rev会随之变化,编
译后Rev.gen自然会随之变化,达到了自动化变更的目的。
其他细节:
a) 之所以需要加一级目录gen,主要原因是为了XCode打包不认不在工程中管理的文件或文件夹,而Rev.gen我们并不希望进入版本库,只好加在XCode工程中加入一个引用型的文件夹gen,并把文件夹本身纳入版本管理
b) XCode5以后的打包优化策略[2][3],使得我们需要touch一下,才能使得最新生成的Rev.gen被打包进版本
c) 由于合作开发者有可能误将Rev.gen上传,将Rev.gen的忽略设置提交到SVN可以避免此问题
d) 由于编译后会在本地产生对应代码版本的Rev.gen信息,可以利用这里的信息,对比SVN版本,来判断当前代码版本是否被编译过,即可以用来实现自动发布Release脚本中的检查。
set /p build_ver= < ..\..\CMWar_2dx\CMWar_2dx\Resources\gen\Rev.gen if not "%rev%"=="%build_ver%" ( echo "Build Ver != rev" pause exit )
本文的txt版本和文中涉及的脚本文件均已打包上传到 http://download.csdn.net/detail/piao_polar/7678339
参:
[1] http://www.cnblogs.com/loongwong/archive/2012/07/13/2590927.html
[2] http://blog.mutoo.im/2013/12/xcode-5-does-not-copy-bundle-resources-in-folder.html
[3] http://quick.cocos.org/?p=22
自动化的在程序中显示SVN版本