2012-10-10 176 views
2

我想要使用一个条件属性来设置属性值为X,如果另一个属性被定义,否则为Y。但是,我不希望用户能够从命令行重写条件属性。条件属性被覆盖

这是如何实现的?

+0

覆盖属性:[我如何允许一个Ant属性文件覆盖在另一个设置的值?](http://stackoverflow.com/questions/4206080/how-can-i-allow-an-ant-property -file到覆盖最值集合另一个) – Jarekczek

回答

2

不,你不能覆盖命令行上设置的属性。至少,这并不容易。在命令行上覆盖属性的全部目的是允许用户覆盖默认值,以便按照项目构建的方式进行修改。例如:

<property file="${basedir}/build.properties"/> 
<property name="javac.debug" value="no"/> 

<target name="compile"> 
    <javac destdir="${main.destdir}" 
     debug="${javac.debug}"> 

默认情况下,Java代码编译时没有调试信息。也许这样做是为了使jar文件更小,或更快的解释,或者使代码难以反编译和阅读。无论出于何种原因,这种构建都不会将调试信息放入类文件中。

但是,开发人员需要这么做调试信息,所以他们希望能够覆盖此设置:

$ ant -Djavac.debug=true compile 

或者,他们可以创建一个build.properties文件,并把价值在那里。

当您不使用Ant进行构建时会出现此类问题。我知道使用Ant脚本进行部署的几个站点。我通常不喜欢这个,因为Ant并不是真的为这种类型的东西制作的。例如,Ant没有任何内置逻辑或循环。一旦设置了属性,就无法更改。对于构建语言来说,这些都是很好的想法,但对于通用编程语言却是一个糟糕的主意。

此外,开发人员不应该为QA或生产进行构建。这些应该由不会覆盖默认值的构建服务器来完成。


现在如何摧毁这整个经过深思熟虑的系统,并导致大破坏:

可以使用ant-contrib任务在项目中。这样做将允许您访问Ant Contrib var任务以取消设置属性。

下载ant-contrib.jar文件(无论最新版本是什么),并将其放入项目下的lib目录中。然后,你可以这样做:

<project name="danger-will-robinson" default="package" basedir="." 
    xmlns:ac="http://ant-contrib.sourceforge.net"> 

    <!-- Define the Ant-Contrib tasks --> 
    <taskdef=resource="net/sf/antcontrib/antlib.xml" 
     uri="http://ant-contrib.sourceforge.net"> 
     <classpath> 
      <fileset dir="${basedir}/lib"> 
       <include name="ant-contrib*.jar"/> 
      </fileset> 
     </classpath> 
    </taskdef> 

    <!-- Unset Property "foo", so you can use it --> 
    <ac:var name="foo" unset="true"/> 

注意,<classpath>点在${basedir}/lib目录蚂蚁的contrib罐子。如果您将它检入到源代码库中,它将允许签出项目的每个人都能够在不在其系统上安装ant-contrib的情况下进行构建。

请注意,我定义了一个“ac”XML namespace,所以Ant-Contrib任务不会与其他可能的第三方任务重叠。

3

从ant 1.8开始,对于某些使用案例local任务可能适用。由于属性是本地化的,因此它以空值开始。它的范围仅限于当前目标,但您可以在antcall中使用param参数将其传递给后续目标。

1

蚂蚁一旦设置属性是不可改变的设计。您可以用提供对ant api的访问权限的任何脚本语言覆盖现有属性,即javascript。
JDK> = 1.6已经附带了一个JavaScript引擎,所以您可以使用类似:

<project> 

<property name="x" value="whatever"/> 

<script language="javascript"> 
    project.getProperty('x') ? 
    project.setProperty('foo', 'true') : 
    project.setProperty('foo', 'false'); 
</script> 

<echo>$$[foo} => ${foo}</echo> 

</project> 

开箱。
但是,如果有人使用ant -f yourbuild.xml -Dfoo=bla !!作为userproperties(通过-Dkey = value定义的那些属性)具有特殊保护。
所以你的要求是“..但是,我不希望用户能够从命令行覆盖条件属性”。
未填满。

但是从Ant addon Flakalet任务提供possibillity覆盖甚至userproperties:

<project xmlns:fl="antlib:it.haefelinger.flaka"> 

<property name="x" value="whatever"/> 

<!-- 
    := defines a new property whereas 
    ::= overwrites any existing property 
    even userproperties 
--> 
<fl:let> foo ::= has.property['x'] ? 'true' : 'false'</fl:let> 

<echo>$$[foo} => ${foo}</echo> 

</project> 

运行都与蚂蚁-f yourbuild.xml -Dfoo = BLA脚本,看到了差距。

蚂蚁API也有方法project.setUserProperty(字符串,字符串),所以你也可以使用:

... 
<script language="javascript"> 

project.getProperty('x') ? 
    project.setProperty('foo', 'true') : 
    project.setProperty('foo', 'false'); 

project.getUserProperty('x') ? 
    project.setUserProperty('foo', 'true') : 
    project.setUserProperty('foo', 'false'); 

</script> 
... 

防止foo的属性通过设置.. -D ..它会工作即使属性x在命令行上定义-Dx = whatever
您必须作出选择,使用JavaScript开箱即用的脚本任​​务或Flaka让任务 oneline解决方案,但需要Flaka jar。