条件属性覆盖

时间:2012-10-10 18:15:44

标签: ant

如果定义了另一个属性,我想使用condition属性将属性值设置为X,否则使用Y.但是,我不希望用户能够从命令行覆盖condition属性。

如何实现这一目标?

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分: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目录中的ant-contrib jar。如果将其检入源存储库,它将允许签出项目的每个人都能够在不在系统上安装ant-contrib jar的情况下进行构建。

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

答案 2 :(得分:1)

ant设置的属性在设计时是不可变的。您可以使用任何提供对ant api访问的脚本语言覆盖现有属性,即javascript JDK&gt; = 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,这无济于事!! as userproperties(通过-Dkey = value定义的属性)具有特殊保护 因此,您的要求是“..但是,我不希望用户能够从命令行覆盖条件属性”。
未填满。

但是来自Ant addon Flakalet任务提供了覆盖甚至用户属性的可能性:

<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>

使用ant -f yourbuild.xml -Dfoo = bla运行这两个脚本以查看差异。

Ant api还有方法project.setUserProperty(String,String),所以你也可以使用:

...
 <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>
...

防止通过.. -D ..设置foo属性,即使在命令行上定义了属性x -Dx =无论什么,你必须做出选择,用javascript输出脚本任务盒子或Flaka让任务 oneline解决方案,但需要Flaka jar。