2.2 人机界面设计
不需要。
2.3 存储设计
见构建信息显示系统。
2.4 系统接口设计
构建系统和操作系统的接口在OSScheduler。在Linux下可以实现成一个调用ant LogAdmin的shell 可执行文件,并配置crond每晚某个时刻执行这个可执行文件。
3、实现
在这节中充分利用本文章系列中篇中所有的技术,并显示了部分源代码。
3.1 部署图
在实现时,第一个要考虑的就是类如何与源文件对应,这些源文件又是如何组织的,表示这些信息的图表称为部署图。图表的格式不一定要很标准,这要能表达意思就行。

从每晚构建部署图可以看出,这些类被分别组织在两个不同的目录下:work_nightly和work_nightlybuild。work_nightly目录存放的是跨项目的构建信息,称为每晚构建平台构建系统中的构建管理子系统,除了包括实现BuildAdmin,BuildInfoLog和LogAdmin的源代码外,还有应用服务器目录Tomcat412,编译和测试程序时常用jar类库目录lib,测试b/s架构的程序的配置信息目录cactusconf和生成ant配置文件依赖性图解的vizant目录。work_nightlybuild是一个支持每晚构建项目的目录,在这里是构建信息显示系统项目,这个目录包括了类ProjectBuild和ProjectBuildAbstract的源代码,同时还具有一个web项目该有的的文件和目录。值得指出的是为了不至于有多份实现BuildInfoLog类的源代码,在具体项目中包括了一个指向构建管理子系统顶级目录的文件称为指针文件。类ProjectBuild、ProjectBuildAbstract和指针文件组成了构建系统中的项目构建子系统。
3.2 存储接口BuildInfoLog
文件BuildInfoLog.properties实现存储接口,内容如下:
###=================================###
logTopDir= "adminLogs"
statCVSTopDir="statCVSes"
testTopDir="tests"
distTopDir="/usr/tomcat412/webapp/"
nightly_Build_Tags=" nightBuildLog"
projectLogTopDir="projectLogs"
testCoverTopDir="testCovers"
webAppDir="/usr/tomcat412/webapp/"
nightlyWebAppName="nightlybuild"
###=============================###
这个文件实现的目录结构如下,这个目录结构在构建信息显示系统的web应用程序中创建。

3.3 类LogAdmin
<project name="BuildAdminSystem" default="execute" basedir="." >
<!-- 定义方法 -->
<target name="init" >
<tstamp>
<format property="DSTAMP" pattern="yyyyMMdd_HHmmss" locale="cn"/>
</tstamp>
<!-- 继承BuildInfoLog -->
<property file="BuildInfoLog.properties"/>
</target>
<target name="execute" depends="init" >
<echo>
###########################
LogAdmin.xml:target execute
the BuildAdmin.xml´s output will put into file:
${webAppDir}${nightlyWebAppName}/${logTopDir}/${logNamePrefix}-${DSTAMP}.txt
###########################
</echo>
<!-- 跨类的方法调用ant task -->
<ant antfile="BuildAdmin.xml"
inheritAll="false"
output="${webAppDir}${nightlyWebAppName}/${logTopDir}/${logNamePrefix}-${DSTAMP}.txt" >
<!-- 传递参数 -->
<property name="tagTime" value="${DSTAMP}"/>
</ant>
</target>
</project>
3.4 类BuildAdmin
<project name="BuildAdminSystem" default="execute" basedir="." >
<!-- 定义方法 -->
<target name="init" >
<!-- 继承BuildInfoLog -->
<property file="BuildInfoLog.properties"/>
<property name="cvsroot" value=":pserver:anonymous@10.1.36.135:/data/src" />
<property name="buildtemp.dir" value="../buildtemp" />
<property name="lib.dir" location="lib" />
<property name="AJPPORT" value="9887" />
<property name="HTTPPORT" value="9888" />
<property name="HTTPSPORT" value="9889" />
<property name="statcvs.jar"
location="${lib.dir}/statcvs-0.1.3.jar"/>
<taskdef name="statcvs" classname="net.sf.statcvs.ant.StatCvsTask">
<classpath>
<pathelement path="${statcvs.jar}"/>
</classpath>
</taskdef>
</target>
<target name="execute" >
<!-- you can add another module here -->
<antcall target="build_One_Module">
<param name="module" value="nightlybuild"/>
</antcall>
<!-- you can add another module here -->
<!--
<antcall target="build_One_Module">
<param name="module" value="testcvs"/>
</antcall>
-->
</target>
<!-- 方法调用之一depends -->
<target name="build_One_Module" depends="init">
<!-- 方法调用之一antcall -->
<antcall target="cvs_Check_Out">
<!-- the CVS module name which includes a build.xml itself -->
<!-- 传递参数 -->
<param name="module" value="${module}"/>
</antcall>
<!-- 生成构建标签 -->
<property name="nightly_Build_Tag" value="${module}-${tagTime}" />
<echo>
###############################################
BuildAdmin.xml:target build_One_Module:
nightly_Build_Tag is set to ${nightly_Build_Tag}
###############################################
</echo>
<echo>
###############################################
BuildAdmin.xml:target build_One_Module:
append ${nightly_Build_Tag} to file
${webAppDir}/${nightlyWebAppName}/${nightly_Build_Tags}
###############################################
</echo>
<!-- 记录构建标签 -->
<echo append="true" file="${webAppDir}/${nightlyWebAppName}/${nightly_Build_Tags}" >
${nightly_Build_Tag}
</echo>
<!-- 生成项目度量信息 -->
<antcall target="statCVS">
<param name="module" value="${module}"/>
<param name="build_tag" value="${nightly_Build_Tag}" />
</antcall>
<echo>
###############################################
BuildAdmin.xml:target build_One_Module:
the software is checked out in ${buildtemp.dir}/tmp/${module}
let´s begin to build it and the output will be put into
${webAppDir}${nightlyWebAppName}/${projectLogTopDir}/${nightly_Build_Tag}.txt
###############################################
</echo>
<ant dir="${buildtemp.dir}/tmp/${module}"
target="execute"
inheritAll="false"
output="${webAppDir}${nightlyWebAppName}/${projectLogTopDir}/${nightly_Build_Tag}.txt" >
<property name="nightly_Build_Tag" value="${nightly_Build_Tag}" />
<property name="AJPPORT" value="${AJPPORT}" />
<property name="HTTPPORT" value="${HTTPPORT}" />
<property name="HTTPSPORT" value="${HTTPSPORT}" />
</ant>
<!--
<ant dir="../work_nightlybuild"
antfile="ProjectBuild.xml"
target="execute"
inheritAll="false"
output="${webAppDir}${nightlyWebAppName}/${projectLogTopDir}/${nightly_Build_Tag}.txt" >
<property name="nightly_Build_Tag" value="${nightly_Build_Tag}" />
<property name="AJPPORT" value="${AJPPORT}" />
<property name="HTTPPORT" value="${HTTPPORT}" />
<property name="HTTPSPORT" value="${HTTPSPORT}" />
</ant>
-->
</target>
<target name="cvs_Check_Out" >
<!-- cvs checkout -->
<echo>
###############################################
BuildAdmin.xml:target cvs_Check_Out:
the software will be checked out in ${buildtemp.dir}/tmp/${module}
###############################################
</echo>
<delete dir="${buildtemp.dir}/tmp/${module}" />
<mkdir dir="${buildtemp.dir}/tmp"/>
<cvs cvsRoot="${cvsroot}"
package="${module}"
dest="${buildtemp.dir}/tmp"
/>
<cvs dest="${buildtemp.dir}/tmp/${module}" command="log" output="${buildtemp.dir}/tmp/${module}/cvs.log"/>
</target>
<!-- 生成项目度量信息 -->
<target name="statCVS" depends="init" >
<echo>
###############################################
BuildAdmin.xml:target statCVS:
the software will be measureed in ${webAppDir}${nightlyWebAppName}/${statCVSTopDir}/${build_tag}
###############################################
</echo>
<delete dir="${webAppDir}${nightlyWebAppName}/${statCVSTopDir}/${build_tag}" />
<mkdir dir="${webAppDir}${nightlyWebAppName}/${statCVSTopDir}/${build_tag}"/>
<statcvs
projectName="${module}"
projectDirectory="${buildtemp.dir}/tmp/${module}"
cvsLogFile="${buildtemp.dir}/tmp/${location}/cvs.log"
outputDirectory="${webAppDir}${nightlyWebAppName}/${statCVSTopDir}/${build_tag}"
/>
</target>
</project>