很多人在说到Daily Build的时候总是喜欢背书。背书就背书吧,总比混迹软件行业连书都没看过的强。很久以前遇到一个奇葩。每次到代码提交测的通知就着急忙慌的催促组员赶紧干活,开始严重加班,晚饭都不吃。。。偶尔还需要开通宵。但是即使如此,最后也不会得到什么好的反馈。那个team就是这样循环往复的做着项目,直到永恒。如果项目的相关人员能背背敏捷什么的开发书籍,想必情况总能有所改善。
相信以上情况各位多少都遇到过,那么Daily Build为什么会对这样的情况有所改善呢?
- 快速定位错误。那天的Daily Build出问题了就是那天继承到系统中得代码出的问题。有check in到SVN的代码必须是可以编译的这样的约定也无济于事,一个疏忽就扒瞎。Daily Build才是对代码可运行的最好保证。
- 给客户想要的软件。及早的把可运行的代码给客户看。用户可以及时看到可用的功能,可以及早的提出开发和需求理解不一致的内容。这个客户不一定是特质甲方。也可以理解为给开发部门提出需求的产品等其他部门。一般来说,如果最后给“客户”一个“出乎意料”的软件,这有可能不是客户想要的。
- 开发进度约%60。软件开发这个东西就是不能像盖楼一样看到明显的结果。%60是个多少?Daily Build可以让需要了解进度的人非常清楚的了解开发的进度。
- Daily Build对软件的质量也有很大的帮助。每天一个可运行的版本出来,测试就可以开始测了。尽早的测出bug来,尽早的修改。这些都会在不大量增加工作量的前提下保证代码质量。比在最后的最后通宵熬夜效果好到不知道多少。
XCODEBUILD
下面Daily Build iOS项目。Xcode有一个command tool的工具xcodebuild。用这个工具可以用来使用命令行编译Xcode项目。
然后先看看这个xcodebuild都能做些什么。输入man xcodebuild命令:
功能很强大!不过我们目前要用到的还只是其中的一小部分。一点点的看。
切换到你项目所在的目录
1cd /Users/username/Desktop/MyiOSApp/
试试这句
1xcodebuild -configuration Distribution clean build
最后看到这句** BUILD SUCCEEDED **就算是命令执行成功了。你可以在你的目录下发现一个新建的文件夹build,在这个文件夹里就可以找到编译并且打包好的你的app:YourProjectName.app。没错这个打好得包是app格式的。我们要得时ipa的包,肿么办呢。往下看。
1xcodebuild -scheme MyiOSApp archive -archivePath /Users/username/Desktop/MyiOSApp.xcarchive
xcodebuild命令,这里使用-scheme来打包成xcarchive。然后。
123xcodebuild -exportArchive -exportFormat ipa -archivePath
/Users/username/Desktop/MyiOSApp.xcarchive -exportPath
/Users/username/Desktop/MyiOSApp.ipa
这个命令执行完成之后,你就会在刚刚生成的build文件夹里找到你的app的ipa包了。
自动化起来
用shell把xcodebuild命令串起来?No,用Python。使用Python可以做shell能做的,还可以做shell不能的。而且python简单易学,谁拿过来都可以分分钟学会。最关键的一点,很多的linux系统都已经预装了python。mac也不例外。现在mac默认安装的时Python2.7的环境。所以,下面的代码都是基于Python2.7的。
上面讲了“大象装冰箱”的三步走。一一的用Python代码实现出来。
准备工作
下面用接收命令行的方式传入三步走中需要指定的内容。Python在执行的时候是这样的:
1python yourFileName.py command line
我们要传入的参数包括scheme的名称,项目所在的目录等。还有别的,目前所用到的主要是这两个。例如:
1python yourFileName.py --scheme=[your scheme name] -x [project path] [out put path.format]
有了命令了,就应该解析了:
1opts, args = getopt.getopt(sys.argv[
1
:], x, [scheme=])
参数从第二个开始算sys.argv[1:],因为第一个是yourFileName.py。getopt方法会把长参数名都拿出来给opts数组。opts数组中得每一个元素都是一个tuple的结构,第一个元素是长参数的名称,第二个元素是长参数对应的值。-x后面的参数都放在args数组中。args的每一个元素都是一个字符串,相当于[project path] [out put path.format]字符串按照空格split成的字符串数组。
走三步,1.cd。。。
跳转到项目所在的目录。参考这么一句import os os.system(ls)可以执行ls命令。但是,这个却不能执行“cd”命令。因为那个不能修改python主进程的工作目录。用这个:
123import
os
directory = your ios project path
os.chdir(directory)
2. archive
123import
subprocess
archiveCmd = xcodebuild -scheme + targetName + archive -archivePath + directory + targetName + .xcarchive
subprocess.Popen(archiveCmd, shell=True)
第一句就是拼一个字符串。一个xcodebuild的命令字符串,然后放到subprocess中执行。
3. 打包成ipa
12ipaCmd = xcodebuild -exportArchive -exportFormat ipa + -archivePath + directory + / + targetName + .xcarchive + -exportPath + directory + / + targetName + .ipa
subprocess.Popen(ipaCmd, shell=True)
和第二部一样,拼一个字符串把上一步中打好包的xcarchive重新打包成ipa并输出。
so far so good?
这几条命令分开执行,确实都不会有任何的问题。会在项目的目录下生成一个build的目录,在里面可以找到我们在前面两部的命令中得到的xcarchive文件和最后输出的ipa文件。很好,都放在python的文件中按照我们预定的方式执行一次。python yourFileName.py -scheme yourSchemeName -x youriOSPeojectPath。执行之后会输出满屏幕的xcodebuild的输出内容。但是看看项目文件夹下,没有ipa文件!
原来,subprocess执行命令的时候,xcodebuild命令没有执行完成就已经返回了。也就是ipa打包的命令执行的时候上一步的命令还没有执行完,xcarchive还没有生成。这一点很好解决,python给subprocess提供了一个wait方法。等命令全部执行完了再执行下一步。
12process = subprocess.Popen(archiveCmd, shell=True)
process.wait()
so far so good!
这个时候就算是全部的问题都解决了。代码在这里。Python语言本身非常的灵活。在这一代码上可以很容易扩展出其他的功能。比如定时执行,编译或者打包不成功发送通知邮件等。