2

I want to use an condition property to set the property value to X if another property is defined and Y otherwise. However, I don't want the user to be able to override the condition property from the command line.

How can this be achieved?

4

3 回答 3

3

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

于 2012-10-11T08:02:27.200 回答
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 命名空间,因此 Ant-Contrib 任务不会与其他可能的第三方任务重叠。

于 2012-10-10T20:22:14.870 回答
1

一旦设置,ant 中的属性在设计上是不可变的。您可以使用任何提供对 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 定义的那些属性)具有特殊保护。
所以你的要求“..但是,我不希望用户能够从命令行覆盖条件属性”。
未满。

但是let来自Ant addon Flaka的任务提供了覆盖甚至 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>

使用 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=whatever
您必须做出选择,使用开箱即用的 javascript 脚本任务或 Flaka let 任务oneline 解决方案,但需要 Flaka jar。

于 2012-10-11T20:54:24.823 回答