我已经计算出创建包含在目录中我们可重复使用的构建脚本一个jar文件的解决方案,比如COM /例子/ ANT/sharedbuild,它可以在1.8蚂蚁进口:
<project>
<import>
<javaresource name="com/example/ant/sharedbuild/java.xml">
<classpath location="../../../../target/ant-shared-build.jar" />
</javaresource>
</import>
</project>
在我的情况下,它定义了项目的所有“公共”目标,以执行基于Java的构建。
语法有点冗长,特别是当我添加了越来越多的包含文件(比如添加创建OSGi jar的能力)。通过将一个包含macrodef和scriptdef组合的antlib.xml添加到jar文件(与共享构建脚本位于同一目录中),构建文件现在可以如下所示(现在也可以创建OSGi jar包):
<project xmlns:build="antlib:com.example.ant.sharedbuild">
<taskdef uri="antlib:com.example.ant.sharedbuild"
classpath="../../../../target/ant-shared-build.jar" />
<build:build using="java, jar, bundle" />
</project>
不幸的是,我不能共享代码的macrodef或scriptdef,但实际上它并不难:一些JavaScript解析使用属性和循环每个,从中获取文件名,并导入。
我在硬盘上的固定位置(相对于我的项目)引用jar文件。我认为我们可以做得更好。理想情况下,我想从中央位置获取(版本化!)jar文件。既然我们已经使用艾维(与HTTP资料库),我们可以发布的jar文件有(再次,一个版本),并且直接从那里取,
<project xmlns:build="antlib:com.example.ant.sharedbuild">
<property name="ant.shared.build.jar.file"
location="${user.home}/ant/ant-shared-build-1.5.3.jar" />
<get src="http://repo.example.com/.../ant-shared-build-1.5.3.jar"
dest="${ant.shared.build.jar.file}"
skipexisting="true" />
<taskdef uri="antlib:com.example.ant.sharedbuild"
classpath="${ant.shared.build.jar.file}" />
<build:build using="java, jar, bundle" />
</project>
有一些问题是:
- 它再次变得冗长。
- 每个build.xml都会重复详细程度。
- 有很多重复的样板,特别是版本号。
为了缓解这些问题,在每个包含build.xml的目录中,我还有一个bootstrap.xml(名称并不重要)。每个版本。XML然后包括本文件:
<project xmlns:build="antlib:com.example.ant.sharedbuild">
<include file="bootstrap.xml" />
<build:build using="java, jar, bundle" />
</project>
每个bootstrap.xml,在最低限度,包括它的父的bootstrap.xml:
<project>
<include file="../bootstrap.xml" />
</project>
顶层bootstrap.xml(根),然后不获得jar文件并创建自定义任务,如上面的工作:
<project>
<property name="ant.shared.build.version"
value="1.5.3" />
<property name="ant.shared.build.jar.filename"
value="ant-shared-build-${ant.shared.build.version}.jar" />
<property name="ant.shared.build.jar.file"
location="${user.home}/ant/${ant.shared.build.jar.filename}" />
<get src="http://repo.example.com/.../${ant.shared.build.jar.filename}"
dest="${ant.shared.build.jar.file}"
skipexisting="true" />
<taskdef uri="antlib:com.example.ant.sharedbuild"
classpath="${ant.shared.build.jar.file}" />
</project>
虽然没有直接关系的问题,实际上我再处理macrodef和scriptdef成定制Ant任务,因为我希望能够支持语法看起来像这样:
<project xmlns:build="antlib:com.example.ant.sharedbuild">
<include file="bootstrap.xml" />
<build:build>
<using>
<java />
<bundle>
<manifest>
Import-Package: *,org.joda.time;version="[1.6.0,1.6.0]"
Bundle-Activator: com.example.time.impl.Activator
</manifest>
</bundle>
</using>
</build:build>
</project>
我应该指出,仅仅建立一个可再发行组件构建并不意味着它将会是有用的。您仍然需要投入时间和精力来创建符合类似特征设计的凝聚力,模块化,一致的实施方案。这是更重要的,因为您需要跨项目,跨团队,跨组织边界等共享脚本。
总之,通过创建一个jar文件,其版本号可独立于特定文件位置或SCM工具,我们可以获得真正的共享但可重复的构建。
非常感谢!我正在寻找错误的任务。难怪我找不到它。一些例子的链接也会有很大的帮助:如果你有一些好的,你可以随意使用。 – nrobey 2011-02-26 17:30:56
如果您想要可重复构建,这是一个糟糕的主意。 – 2011-02-27 18:29:09
@Dominic Mitchell - 好点。如果common_directive.xml不是静态的,最好是更好地管理该依赖关系。 – 2011-02-27 22:13:47