Conditionally setting properties from a selection - ant

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>

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.

Control run of depends target ant?

Based on whether a certain property is set I want to decide whether I want to run a target and its dependencies
Now I know that the "if" attribute can only control the run of the target in which it is specified and not the dependencies.
Is there any variant of "if" or any other alternative which would ensure that I control the run of a target and its dependencies too.
One alternative which comes to my mind it to have "if" attribute in all the dependent targets. But that seems redundant.
This has already been asked before in this question. The answer there applies very well. However, depending on how frequently the target is going to be invoked, another solution (more readable than the mentioned answer) is to use the if task from Ant-Contrib:
<if>
<equals arg1="condition_prop" arg2="some_value" />
<then>
<antcall target="target_with_dependencies" />
</then>
</if>

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

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

Passing optional path arguments to ant

I have an ant task that uses an apply task to run a script on a group of files.
I have a directory structure resultant of something like this:
mkdir -p a/{b,c,d,e}/f
Normally (if I pass no arguments), I would like ant to run on all fs.
That is, if I called ant mytask, it should process: a/b/f, a/c/f, a/d/f, a/e/f. This already works using apply and patternsets.
However, when I pass it an optional argument called foo, it should only call the script on a/foo/f.
So if I called ant mytask -foo b, it should process a/b/f only, and not the others.
I have read this SO post, which explains ways of passing arguments, and I have looked at the ant documentation regarding properties, and conditionals. But I am still unable to piece them together in a way that works.
Also, I do not want to use one of the suggestions from the SO above which called for arguments like this:
<arg value="${arg0}"/>
<arg value="${arg1}"/>
I want to be able to call it as ant mytask -foo valueoffoo for any arbitrary foo.
Thanks.
I tried martin clayton's suggestion below and have code like:
<target name="mytask">
<property name="foo" value="*" />
<apply executable="perl">
<arg value="somescript"/>
<dirset id="them" dir="a">
<include name="${foo}/*/f" />
</dirset>
</apply>
</target>
The above does what I want.
Note 1: In my actual code I use a patternset instead of dirset but it should work the same.
Note 2: In my original question I said the directory structure was a/{b,c,d,e}/f. It is in fact a bit more complicated, hence the * in the include above. I omitted that the first time around because it did not seem relevant.
You can do this - albeit with a slightly different command-line syntax -
using a property 'override'.
First, in the buildfile, construct your fileset or dirset from a property foo,
something like this:
<property name="foo" value="*" />
<dirset id="them" dir="a">
<include name="${foo}/f" />
</dirset>
This will give you your default behaviour - processing all
subdirectories of a that themselves have a subdirectory f.
Now, if you run Ant like this:
ant -Dfoo=d
Only directory a/d/f will be processed.
This works because Ant properties are not mutable - well, not normally anyway -
so the command-line definition of foo prevents the one within the buildfile from being used.

Store a Value in a Property with Ant or Phing

With Ant or Phing, I need to load a file's contents into a property, run a regular expression on the value of that property, and then store the result of that regular expression in another property. What's the best way to do this?
I can load the file into a property easily (with Phing) like so:
<loadfile file="myfile.txt" property="my.file" />
And I know how to update the file, but I can't seem to figure out how to run a regex on that property, and store the result in a new property for future use.
Any help would be greatly appreciated!
Update
I've been tinkering with it, and this will work. Let me know if there's a streamlined way though! The code below loads a file into a property, then reduces it to only the line that contains the title tag. And then, it runs a regular expression on that line, and stores the contents of that tag in my.prop.
<loadfile file="../index.html" property="my.prop">
<filterchain>
<linecontainsregexp>
<regexp pattern="<title>" />
</linecontainsregexp>
<replaceregexp>
<regexp pattern="[\s\S]+<title>(.+?)</title>" replace="$1" />
</replaceregexp>
</filterchain>
</loadfile>
Update 2
Actually, I ended up using an adhoc task to create my own. Worked perfectly!
You can run an arbitrary command from an ant target like this:
<exec executable="bash">
<arg line="script.sh"/>
</exec>
You can for example store the result of the regexp in a tmp file and then load it into another property the same way as the initial one.
In Phing you could process the content of the property where you loaded the file using the "php" task. See: http://www.phing.info/docs/guide/stable/chapters/appendixes/AppendixB-CoreTasks.html#PhpEvalTask

Resources