编者语:在这本书中,Pragmatic Project Automation, Mike Clark 为你提供了无所不有的方法来自动化你的软件项目:用Ant来一步式构建(one-step builds),用CruiseControl 按计划时间来持续构建(scheduling continuous builds),按一下按钮就可以发布软件,轻易地安装和布署应用,通过email,RSS,你的手机,甚至是熔岩灯(lava lamps)来监控构建和程序运行。方法包含示例使初学者也很容易实践,即使是熟手也有更多高级的主题能教她们一些新东西。在这篇文章里,他描绘了自动化你的项目能带来的好处的概要。
你即将要在明天早上交付一个用于关键性演示的软件版本。穿着西装的销售人员嘴里吹着泡炫耀你公司的新的辅助应用给一些十分重要的有钱人。正象你正在键盘上寻找感觉,你的老板却站到你的旁边提醒你这个演示可能会得到这个项目或者让项目完蛋。不要有任何压力!
一步构建和测试
在你为那些“必须有”的演示特征输入最后一行代码后,差不多都中午了。你最喜爱的IDE 显示你的代码编译通过并通过了单元测试。但是当他结合到系统的其余部分,你的代码是否能象预期的那样正常工作呢?为了弄清楚它,你更新了你本地的工作区,为了同步现在版本控制系统中的文件。然后你运行了项目的一步式构建过程:
$ ant
这个命令编译了所有的代码文件,运行了下面Ant构建文件中的配置的所有的单元测试。
清单1:
<project name="whizbang" default="test" basedir=".">
<property name="build.prod.dir" location="build/prod"/>
<property name="build.test.dir" location="build/test"/>
<property name="src.dir" location="src"/>
<property name="test.dir" location="test"/>
<property name="vendor.lib.dir" location="vendor/lib"/>
<path id="project.classpath">
<pathelement location="${build.prod.dir}" />
<pathelement location="${build.test.dir}" />
<fileset dir="${vendor.lib.dir}">
<include name="*.jar"/>
</fileset>
</path>
<target name="prepare">
<mkdir dir="${build.prod.dir}"/>
<mkdir dir="${build.test.dir}"/>
</target>
<target name="compile" depends="prepare">
<javac srcdir="${src.dir}" destdir="${build.prod.dir}">
<classpath refid="project.classpath" />
</javac>
</target>
<target name="compile-tests" depends="compile">
<javac srcdir="${test.dir}" destdir="${build.test.dir}">
<classpath refid="project.classpath" />
</javac>
</target>
<target name="test" depends="compile-tests">
<junit haltonfailure="true">
<classpath refid="project.classpath" />
<formatter type="brief" usefile="false" />
<batchtest>
<fileset dir="${build.test.dir}"
includes="**/*Test.class" />
</batchtest>
</junit>
</target>
</project>
当你写代码时,你在你的IDE中频繁地点击方便的构建按钮来确认所有的东西都编译了。你也已经热衷于当你的JUnit测试通过后,看到一个快乐的绿色条(单元测试成功的标志),然后你使用JUnit测试运行器(JUnit test runner)整合到你的IDE中。但不是团队里的每个人都象你那样喜欢这个IDE,而且你也不想在每次有人想做一个构建时就不得不启动IDE。使用构建文件来和你的IDE分离,每个团队里的人都能一步式地持续构建和测试项目。(项目使用Maven 来创建一步式构建。)
你不要惊讶,构建成功了,你再次意识到你是世界上最伟大的程序员。 不仅是在代码里做这个构建过程带给你的信心,他也让你对项目可在你的IDE外构建有信心。
感觉非常好,你上传了已经更改的文件并避开了那些麻烦。为了准备演示,你仍旧有许多要做的,你需要更早的离开第一次去参加你儿子的tee-ball游戏比赛。时钟滴答的响着…
泡泡危机
午饭后回办公室的路上,你注意到项目的红色熔岩灯在沸腾(这种灯灯罩里有特殊液体材料)。哦!当你想离开去吃饭的时候,绿色的灯正欢快的冒着泡(说明程序一切正常)。你离开后,你项目的按计划进行的构建过程在机器上努力的尝试构建和测试现在版本控制资源(version control repository)上的代码。但发生了可怕的错误。
让你的项目连续地运行构建是很容易的,因为实际上你可以在命令行中一步就创建一个构建。这意味着你可以很容易的让一台计算机整日地为你运行构建。否则,你就不得不放一个开发人员不时地用命令行构建文件。取而代之,你用CruiseControl 设定在你的项目专用构建机器上在一定的时间间隔内自动地创建构建,如下面的config.xml文件所示:
清单2:
<cruisecontrol>
<project name="whizbang" buildafterfailed="false">
<bootstrappers>
<currentbuildstatusbootstrapper
file="logs/whizbang/currentbuildstatus.txt" />
</bootstrappers>
<modificationset quietperiod="30">
<cvs localworkingcopy="checkout/whizbang" />
</modificationset>
<schedule interval="300">
<ant buildfile="cc-build.xml" />
</schedule>
<log dir="logs/whizbang">
<merge dir="checkout/whizbang/junit-results" />
</log>
<publishers>
<currentbuildstatuspublisher
file="logs/whizbang/currentbuildstatus.txt" />
<!-- email publisher -->
<!-- RSS publisher -->
<!-- lava lamp publisher -->
</publishers>
</project>
</cruisecontrol>
这个config.xml文件使CruiseControl 每5分钟被唤醒一次,检测你项目的CVS资源,看看是否需要构建。只有当你的团队中有人更改了一个已经存在的文件,或者加入了一个新文件到版本控制资源里的时候,CruiseControl 才尝试去创建一个构建。他依赖于怎样用一个Ant或者Maven构建文件为你的项目去创建一个构建。你可以用CruiseControl 设定去运行一个叫cc-build.xml 的Ant构建文件,内容如下:
清单3:
<project name="cc-build" default="build" basedir="checkout">
<target name="build">
<delete dir="whizbang" />
<cvs command="co whizbang" />
<ant antfile="build.xml" dir="whizbang" />
</target>
</project>
cc-build.xml文件通过删除你项目在上次构建时的拷贝和从CVS资源上下载一个项目新的拷贝引导运行构建过程。然后他自动运行同样的你在命令行中编译和测试项目的bulid.xml文件。在运行build文件后,CruiseControl 发布构建结果给所有注册了的发行人。(使用Maven的项目也用了CruiseControl ,不过它被谁设定用一些你不喜欢使用的其它的版本控制系统去监视变化)
每5分钟把这些工作全都做一遍是个轻松的工作,这就是为什么你喜欢让CruiseControl 来为你做这些。当你最初设置它的时候,看起来非常麻烦,但你已经学会感激能适时回馈给你信息的价值。5分钟的计划任务不过是编译了所有的代码和运行了单元测试,作了一个快捷的健全性的检测。你也用CruiseControl 设置去运行一整套系统在不那么频繁的时间间隔里执行测试。如果5分钟构建失败了,那问题不会存在超过了5分钟。这就让你比较容易的查找和修复问题,从而节约了你宝贵的时间。如果在最近的5分钟里,没有变化被提交,那么CruiseControl 保持休眠。
看,构建失败了!CruiseControl 点燃了红色熔岩灯是件好事,因为你可能忽略了你装满了邮件的收件箱里的构建失败的email。着急找到问题的根源,你打开了构建状态web页发现匆忙间你忘了上传一个新文件。这很难为情,但至少你现在能更早的修复构建在演示前在问题复杂起来导致一个噩梦般的调试会议之前。