How to over-write the property in Ant?
Asked Answered
T

9

30

Is there a way to re-assign the value for the Ant property task? Or is there another task available for that purpose?

Thaliathalidomide answered 8/12, 2009 at 12:44 Comment(0)
H
12

Depending on how you want to use the modified property, you can use macrodefs.

For example, instead of writing the following:

<target name="foo">
   <echo message="${my_property}"/>
</target>

and not being able to call ant foo with another message, you could write:

<macrodef name="myecho">
    <attribute name="msg"/>
    <sequential>
        <echo message="@{msg}"/>
    </sequential>
</macrodef>

<target name="foo">
   <myecho msg="${my_property}"/>
   <property name="my_property2" value="..."/>
   <myecho msg="${my_property2}"/>
</target>
Holcombe answered 10/12, 2009 at 19:51 Comment(0)
P
35

ant-contrib's Variable task can do this:

<property name="x" value="6"/>
<echo>${x}</echo>   <!-- will print 6 -->
<var name="x" unset="true"/>
<property name="x" value="12"/>
<echo>${x}</echo>   <!-- will print 12 -->

Not recommended, though, it can lead to weird side-effects if parts of your Ant scripts assume immutable property values, and other parts break this assumption.

Passmore answered 8/12, 2009 at 12:47 Comment(1)
The var task is especially nice for "local variables", e.g. in for loops (also a task from the excellent ant-contrib). One drawback, though, is that the var task doesn't support the "location" attribute.Algolagnia
G
28

For the sake of justice, there is a hack that allows to alter ant's immutable properties without any additional libs (since java 6):

<scriptdef name="propertyreset" language="javascript"
    description="Allows to assign @{property} new value">
    <attribute name="name"/>
    <attribute name="value"/>
        project.setProperty(attributes.get("name"), attributes.get("value"));
</scriptdef>

Usage:

    <property name="x" value="10"/>
    <propertyreset name="x" value="11"/>
    <echo>${x}</echo>   <!-- will print 11 -->

As others mentioned, this should be used with care after all canonical approaches proved not to fit.

Gaily answered 31/10, 2012 at 5:54 Comment(0)
B
12

Properties are immutable in ant.

You may be interested in ant-contrib's var task.

<var name="my_var" value="${my_property}" />

<echo>Addressed in the same way: ${my_var} and ${my_property}</echo>
Brownell answered 8/12, 2009 at 12:49 Comment(0)
H
12

Depending on how you want to use the modified property, you can use macrodefs.

For example, instead of writing the following:

<target name="foo">
   <echo message="${my_property}"/>
</target>

and not being able to call ant foo with another message, you could write:

<macrodef name="myecho">
    <attribute name="msg"/>
    <sequential>
        <echo message="@{msg}"/>
    </sequential>
</macrodef>

<target name="foo">
   <myecho msg="${my_property}"/>
   <property name="my_property2" value="..."/>
   <myecho msg="${my_property2}"/>
</target>
Holcombe answered 10/12, 2009 at 19:51 Comment(0)
E
10

Since Ant 1.8, you can use the "local" task to change the value of a property within a target. Note that this does NOT change the value of the global property with the same name but it is a way to solve some problems.

See

http://ant.apache.org/manual/Tasks/local.html

Eructate answered 9/8, 2012 at 14:29 Comment(0)
S
4

You can't change the value of a property in Ant.

If you have some Ant tasks you want to run repeatedly passing in different values I recommend the macrodef task as you can run the same macro repeatedly passing in different attributes.

For example:

<macrodef name="copythings">
  <attribute name="todir"/>
  <sequential>
    <copy todir="@{todir}">
      <fileset dir="${src}">
        <exclude name='**/*svn' />
      </fileset>
    </copy>
  </sequential>
</macrodef>

<copythings todir="/path/to/target1"/>
<copythings todir="/path/to/target2"/>

Note that ${property} is used to reference properties and @{attribute} is used to reference the attributes passed to the <macrodef> task.

Septempartite answered 8/12, 2009 at 12:58 Comment(0)
B
2

Properties are immutable in ant. But that's not as terrible a limitation as it may seem. There's a whole class of programming languages where (most) variables are constant and yet they get stuff done   this is called "functional programming."

You can "change" values used by different tasks by deriving new, changed properties from old ones, or changing parameters when calling tasks with the subant or antcall tasks. If you're creative you can usually find a way to solve your problem.

Bautzen answered 8/12, 2009 at 12:54 Comment(1)
it's very helpful if you give one example and explain more.Karlee
M
0

Here is a sample using local with the basename command. Var-unset does not work for me.

<for param="db-patches">
       <path>
            <fileset dir="${undeployed-files}" includes="**/ddl*.zip"/>
        </path>
        <sequential>
              <local name="inpfile" />
               <basename property="inpfile" file="@{db-patches}" suffix=".zip" />
               <!-- unzip the patch  -->
               <unzip src="${undeployed-files}/${inpfile}.zip" 
                   dest="${unzipped-patches}/${inpfile}" />
           <move file="${undeployed-files}/${inpfile}.zip" tofile="${deployed-files}/${inpfile}.zip"/>
        </sequential>   </for>
Montiel answered 17/8, 2015 at 19:46 Comment(0)
L
0

There are several options you can do:

  1. Instead of <property/>, you could use ant-contrib's <var/>. Variable can be re-set when needed.
  2. Use <local/> which allows re-setting a property in a "block" scope (e.g. in a target)
  3. Use a script (e.g. Groovy) inside ant which allows re-setting a property:
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpath="path/to/groovy-all.jar" />
<groovy>
    properties.propertyName = "propertyValue"
</groovy>

Or define a macro like this and use it:

<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpath="path/to/groovy-all.jar" />
<macrodef name="overwriteProperty">
    <attribute name="name" />
    <attribute name="value" />
    <sequential>
        <groovy>
            properties["@{name}"] = "@{value}"
        </groovy>
    </sequential>
</macrodef>

<overwriteProperty name="propertyName" value="propertyValue"/>
Lallygag answered 6/7, 2023 at 7:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.