原理介绍
先说一个普通的ant文件结构,包括project/property/target/task等元素,下面是一个样例:
<?xml version="1.0" encoding="UTF-8"?>
<project name="test" all="all" basedir=".">
<property name="source.dir" location="source" />
<target name="all" depends="clean,compile,package,deploy" />
<target name="clean">
<delete file="${tmp.dir}" />
</target>
<target name="compile">
</target>
<target name="package">
</target>
...
</project>
其中delete元素就是一个task,在ant内置的task中有一个可以执行外部构建文件的task叫ant(参考地址:http://ant.apache.org/manual/Tasks/ant.html)我们可以这样去包装构建文件:
file: test_project/build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="test" all="all" basedir=".">
<property environment="env" />
<!-- properties configuration -->
<property name="ci.root" location="${env.JENKINS_CI}" />
<property name="jenkins.tools.root" location="${env.JENKINS_TOOLS}"
<property name="jdk.root" location="${env.JAVA_HOME}" />
<property name="ant.root" location="${env.ANT_HOME}" />
<property name="abs-tasks.root" location="${jenkins.tools.root}/abs-tasks" />
<property name="abs-libs.root" location="${jenkins.tools.root}/abs-libs" />
<property name="ant-contrib.entry.jar" location="${abs-libs.root}/ant-contrib.jar" />
<!-- taskdef define section -->
<!--ant-contrib taskdefs.-->
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="${ant-contrib.entry.jar}" />
</classpath>
</taskdef>
<!-- abs-task-framework macro -->
<macrodef name="abs-task">
<attribute name="task" />
<element name="properties" optional="true" />
<sequential>
<ant antfile="${abs.tasks.root}/@{task}/run.xml" inheritRefs="true">
<properties />
</ant>
</sequential>
</macrodef>
<!-- more taskdef ... -->
<target name="clean">
<!-- clean tasks... -->
</target>
<target name="compile">
<abs-task name="customtask">
<properties>
<property name="executable.file" value="scripts/demo_vs.bat" />
</properties>
</abs-task>
</target>
<target name="package">
<path id="artifact.files">
<fileset dir="${artifact.dir}">
<include name="**/*.exe" />
<include name="**/etc/*.ini" />
</fileset>
</path>
<abs-task name="package">
<properties>
<propety name="artifact.pathrefid" value="artifact.files" />
</properties>
</abs-task>
</target>
</project>
file: abs-tasks/customtask/run.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="customtask" default="customtask">
<dirname property="task.basedir" file="${ant.file.customtask}" />
<import file="${task.basedir}/macro/customtask_macro.xml" optional="true" />
<target name="customtask">
<customtask-macro executableFile="${executable.file}" />
</target>
</project>
file: abs-tasks/package/run.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="package" default="package">
<dirname property="task.basedir" file="${ant.file.package}" />
<import file="${task.basedir}/macro/package_macro.xml" optional="true" />
<target name="package">
<package-macro artifactPathRefId="${artifact.pathrefid}" />
</target>
</project>
将最开始的代码进行拆分然后包装成abs-tasks扩展task,这样就可以实现构建task的重用。
<ant antfile="${abs.tasks.root}/@{task}/run.xml" inheritRefs="true">
<properties />
</ant>
这个原理其实就是ant -f run.xml -Dk1=v1 -Dk2=v2
重构包装
将build.xml文件中的proerties/taskdef define抽取出来单独存放,目录结构可以这个
- jenkins-tools
- abs-config
ci-common-properties.xml
ci-common-taskdefs.xml
ci-common-config.xml
standerdData.xml #用于描述项目目录结构规范,可以自定义一些属性方便构建使用
- abs-tasks
- sourcemonitor # 这个有构建和报告展示功能
- run.xml
- macro
- customtask-macro.xml
- convertor # 后面会讲
- report.xsl
- ci-summary.xsl
- ci-module.xsl
- customtask #这个只有构建功能
- run.xml
- macro
- package-macro.xml
- package.xml
file: xxx_project/build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="xxx_project" default="build" basedir=".">
<property environment="env" />
<property name="abs-config.dir" location="${env.JENKINS_TOOLS}/abs-config" />
<import file="${abs-config.dir}/ci-common-config.xml" />
<import file="${abs-config.dir}/standardData.xml" />
<target name="build" depends="build.steps,build.after-steps" />
<target name="build.steps" depends="compile" />
<target name="build.after-steps" depends="artifact" />
<target name="compile" depends="setup.normal">
<abs-task name="customtask">
<properties>
<property name="executable.file" value="xxx" />
</properties>
</abs-task>
<abs-task name="sourcemonitor">
<properties>
<property name="xxx" value="xxx" />
</properties>
</abs-task>
</target>
<target name="package">
...
</target>
</project>
好了就到这里吧,ant脚本只是一个构建载体,你可以将借用exec 扩展很多命令,也可以使用groovy脚本开发扩展任务或者字符串解析等等。
下期预告:如何实现构建任务的数据展示?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。