ant - if doesn't support the "name" attribute - ant

i have a requirement that as follows.
I have a .properties file (with name=value pair) from which i am reading couple of properties.
i want to check a particular property exist or not.
i am getting the error with if doesn't support the "name" attribute for the following code.
where JavaProjectName,projDir are the names getting from the .properties file.
<if name="${JavaProjectName}" exists="true">
<property name="importJavaProject" value="${projDir}/${JavaProjectName}"/>
</if>
can you please tell me where am i doing wrong.

Read the document of <if> task first. It doesn't support the way you wrote.
It should be:
<if>
<isset property="JavaProjectName" />
<then>
<property name="importJavaProject" value="${projDir}/${JavaProjectName}"/>
</then>
</if>
However, you want to set a property importJavaProject when another property JavaProjectName has been set before (in the build file or in a properties file imported). So, what if JavaProjectName has not been set?
You should either think of an <else> part, or fail the build.
If you just want to check for existence and fail the build when it does not exist, just use <fail>:
<fail unless="JavaProjectName"/>
Also check Condition task and "Supported conditions".
Addition:
Also read the question posted by ManMohan in the comment more carefully. For "check the property existence in .properties file", the accepted answer of that question checks both "whether the property has been set" and "whether its value is empty".

Related

Property application was circularly defined in ANT Build.xml

I am running a build.xml which is referring to the property file named ant.properties and I have declared the same in my build.xml but when i run the build.xml on my Linux machine it gives below error
build.xml:15: Property application was circularly defined.
It is working fine with an existing windows VDI but now we are migrating to new Linux server and hence tried the same existing build and properties file
property file="ant.properties" is what I am using in my build.xml
I am not sure why it is saying circularly defined as I am sure nothing is running gin loop and my properties file does not have reference back to my build.xml to create a loop.
This happened to us due to us referencing a property which had not been added to our properties file. As a result ant was trying to pull the property from the same one that was being declared.
Bad declaration:
<entry key="my.prop.name" value="${my.prop.name}"/>
To fix it we just had to add a check to see if the property was set or not as it was an optional one.
<if>
<isset property="my.prop.name" />
<then>
<propertyfile file="path/to/config.properties">
<entry key="my.prop.name" value="${my.prop.name}"/>
</propertyfile>
</then>
</if>
This fixed our circular dependency issue and allowed the property to be optional in the project.

Conditionally setting properties from a selection

I've created an ant task that will deploy to a specific url, and it works fine.
However I'd like to use the same task again to deploy to a second env. The only difference being in the URL of the env I supply.
I've created two properties in my build.properties :
DEVURL
TESTURL
and I'd like to set the relevant one within my target, based on an argument that I supply. for example build.xml -Denv=DEV would run the target with the URL set to DEVURL.
I've looked at the condition task, but it only seems to set things dependent on the property being set, not the value within the property ?
Any ideas ?
solved it myself : wasn't using the correctly.
<if>
<equals arg1="${envname}" arg2="DEV"/>
<then>
<echo message="ENV is : DEV"/>
</then>
</if>

How can I iterate over properties from a file?

All my projects and their versions are defined in a properties file like this:
ProjectNameA=0.0.1
ProjectNameB=1.4.2
I'd like to iterate over all the projects, and use their names and versions in an Ant script.
At present I read the entire file using the property task, then iterate over a given list in a for loop like this:
<for list="ProjectNameA,ProjectNameB" param="project">
<sequential>
<echo message="#{project} has version ${#{project}}" />
</sequential>
</for>
How can I avoid the hard-coding of the project names in the for loop?
Basically iterate over each line and extract the name and the version of a project as I go.
Seeing as you're already using antcontrib for, how about making use of the propertyselector task:
<property file="properties.txt" prefix="projects."/>
<propertyselector property="projects" match="projects\.(.*)" select="\1"/>
<property file="properties.txt" />
<for list="${projects}" param="project">
...
</for>
The idea here is to read the properties once with the projects prefix, and use the resulting set of properties to build a comma-separated list of projects with the propertyselector task. Then the properties are re-read without the prefix, so that your for loop can proceed as before.
Something you want to keep in mind, if you are reading additional .property files (besides build.properties) is scoping. If you read an additional file (via the property file="foo.property") tag, ant will show that the file was read, and the properties loaded. However, when you goto reference them, they come up un-defined.

Ant target with property part of the name attribute

I want to define a target using a property as part of its name attribute, but the property doesn't seem to resolve.
<property name="foo" value="FOO" />
<target name="${foo}.init.win32" />
<antcall target="${foo}.init.win32" />
The error I get is: Target "FOO.init.win32.x86" does not exist in the project.
I guess Ant doesn't allow this behavior?
Yes, ant doesn't allow variable name of the target. Otherwise dependency calculation can be very difficult task

Valid <property> names in Ant

I'd like to set some properties in my ant build file, the names of which, are based on ant's build in properties. In particular, I'd like to set a property like:
<property name="${ant.project.name}.compiled" value="true" />
However, when I tried this the ${ant.project.home} portion was not expanded.
Is it possible to use the value of properties as the names of other properties, and if so, how?
<property name="name.holder" value="iamholder" />
<property name="${name.holder}.flag" value="true" />
<echoproperties></echoproperties>
result:
[echoproperties] iamholder.flag=true
this is definitely valid ant code and the property iamholder.flag gets the value of true.
If ${name.holder} does not get expanded, it means it has not been set yet (like if the first line in my sample was missing).
Anyways, this still does not quite solve your problem, as you have pretty much no means of getting the value of this property as you don't know it's name and you can't do a nested resolve in pure ant. Depending on what you are trying to do it could still be useful to you though. This one would work (keep in mind, that until 1.8 the value is irrelevant as long as the property is set):
<target name="compile_stuff" unless="${name.holder}.flag">
<echo>compiling...</echo>
</target>
To really get the value of such a property you have to use ant-contrib's propertycopy as suggested in one of the answers. That way you can get the value in a property whose name you know. Just make sure to do the trick just before use and set the override parameter to true (your post implies that you would be setting more properties like these, but without override your final property could not be changed). Another option for working with such properties is to use ant macros.
I think the only way is to echo your values to a .properties file and then load them back.
However, you should ask yourself if you really need it; when I last used ant I tried to do the same thing but concluded I didn't really need to.
Is
$ant.project.home.compiled
not just as useful?
It can be done, a bit ugly, though. You need the < propertycopy > task from ant-contrib for this. The following shows an example
<property name="projectNameCompiled" value="${ant.project.name}.compiled" />
<property name="${projectNameCompiled}" value="true" />
<propertycopy property="final" from="${ant.project.name}.compiled" />
The property final contains the value true.
There are several ways to achieve that, see Ant FAQ
One possible solution via macrodef simulates the antcontrib / propertycopy task but doesn't need any external library.

Resources