嵌套子ant属性重写行为的解决方案(自1.8.0起)



我以以下方式使用apacheant:

我有项目P1、P2、P3。其中一些项目有模块,比如P2有M1、M2等。所有项目都有自己的ant构建脚本,并且所有项目都必须实现一组预定义的目标(build、dist等),这些脚本希望在调用时定义一些属性。比方说(build.dir.base)

模块遵循类似的结构,因此每个模块都有自己的构建文件,用于实现预定义的目标集,并期望设置一些属性。(比如build.dir.base-与项目相同)

我还有一个全局蚂蚁脚本,用于构建所有项目(或子集)

在代码中看起来像:

build-all.xml:

<project name="x">
    <property name="build.dir.base" location="system.build.base" />
    <target name="build">
        <echo message="build.dir.base as defined for build-all.xml=${build.dir.base}" />
        <subant antfile="build.xml" target="build" inheritAll="false" inheritRefs="false">
            <dirset dir="${system.base}" includes="${project-list}" />
            <property name="build.dir.base" location="${build.dir.base}" />
        </subant>
    </target>
</project>

build.xml(每个有模块的项目一个,如果项目没有模块,则没有subant):

<project name="y">
    <property name="build.dir" location="${basedir}/build" />
    <target name="build">
        <echo message="build.dir.base as defined for project=${build.dir.base}" />
        <subant antfile="build.xml" target="build" inheritAll="false" inheritRefs="false">
            <dirset dir="project.base" includes="${module-list}" />
            <property name="build.dir.base" location="${build.dir.base}/${name}" />
        </subant>
    </target>
</project>

对于具有模块的项目:build.xml(用于模块):

<project name="z">
    <property name="build.dir.base" location="build.dir.base" />
        <target name="build">
            <echo message="build.dir.base as defined for module=${build.dir.base}" />
        </target>
</project>

这种结构允许独立构建项目,也可以独立构建模块,或者使用build-all.xml构建整个系统。此外,最终产品具有以下结构:

  • ${system.build.base}/P1
  • ${system.build.base}/P2/M1
  • ${system.build.base}/P2/M2

etc

然而,由于ant>=1.8.0,这就不可能了。原因是build-all.xml中的<property name="build.dir.base" location="${basedir}/build" />在build.xml中优先于<property name="build.dir.base" location="${build.dir.base}/${name}" />(为项目构建)。因此,项目"子模块"的目的地是${system.build.base}/M1,而不是${system.build.base}/P2/M1

这说明了在命令行上定义的属性不能被嵌套元素覆盖自蚂蚁1.8.0以来。任务的嵌套结构也是如此:如果构建文件a通过任务设置嵌套元素的属性来调用B,而B包含调用C的任务,则C将看到a中设置的值,即使B也使用了嵌套元素

如果某些父级也定义了subant的属性,则无法覆盖该属性。这是严重的,因为构建应该知道父级出于某种无关原因使用的属性。

对于这种不兼容的行为更改,是否有解决方法?由于,我的构建系统在很大程度上依赖于这样一个事实,即<subant inheritAll="false" inheritRefs="false">将在不污染子构建的情况下执行exec。

https://issues.apache.org/bugzilla/show_bug.cgi?id=49891似乎也与这个问题有关。

在尝试了许多不同的东西(包括过滤掉不需要的属性然后重置它的技术)之后,我得出结论,在子ant任务中覆盖命令行属性是不可能的。

不是一个完整的答案,但我发现您可以通过执行以下操作来防止子任务继承特定属性:

<resources id='aoeu'>
    <intersect>
        <propertyset>
            <propertyref builtin="commandline"/>
        </propertyset>
        <propertyset negate="true">
            <propertyref name="property.not.to.be.inherited"/>
        </propertyset>
    </intersect>
</resources>
<groovy>
    ant.propertyset(id:"snth") {
        project.references["aoeu"].each {
            propertyref(name:"${it.name}")
        }
    }
</groovy>
<subant buildpathref="buildpath">
    <propertyset>
        <propertyset refid="snth"/>
    </propertyset>
    <target name="zvwm"/>
</subant>

这并非不可能!!可以使用scriptdef覆盖属性self.getProject().setInheritedProperty(键,值)。查看API

您可以使用antcontrib-var任务。http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html

相关内容

  • 没有找到相关文章

最新更新