Check for parameters value in ant build.xml - ant

I have a requirement where in a build.xml file I have two variables.
While calling the build.xml file from Java program, I will pass the values as properties
And while calling the same build.xml file from command line, it should ask the user for input
Now I have to check whether a particular property is having any value or not, if not, then ask user to input the value
Can you please help me to write this build.xml file?
Thanks in advance.

You can do it like this:
<target name="printMyProperty" depends="askUser">
<echo message="${my.property}"/>
</target>
<target name="askUser" unless="my.property">
<input
message="Enter the value for my.property:"
addproperty="my.property"
/>
</target>
The unless attribute is the solution to your problem. It means "execute this target only if my.property is not set".

Related

Why does ANT update the contents of a fileset after it was created, and can I override this?

I think this may be easiest explained by an example, so here goes:
<target name="test">
<fileset id="fileset" dir="target">
<include name="*"/>
</fileset>
<echo>${toString:fileset}</echo>
<touch file="target/test"/>
<echo>${toString:fileset}</echo>
</target>
Outputs:
test:
[echo]
[touch] Creating target/test
[echo] test
What I ideally want is to have the fileset stay the same so I can have a before/after set (in order to get a changed set using <difference>, so if you know of a way to skip right to that...).
I've tried using <filelist> instead, but I can't get this correctly populated and compared in the <difference> task (they're also hard to debug since I can't seem to output their contents). I also tried using <modified/> to select files in the fileset, but it doesn't seem to work at all and always returns nothing.
Even if there is an alternative approach I would appreciate a better understanding of what ANT is doing in the example above and why.
The path selector is evaluated on the fly. When a file is added, it will reflect in the set when you use it.
You may able to evaluate and keep it in variable using pathconvert. Then this can be converted back to filest using pathtofilest
A fileset is something like a selector. It's a set of "instructions" (inclusions, exclusions, patterns) allowing to get a set of files.
Each time you actually do something with the fileset (like printing the files it "references"), the actual set of files is computed based on the "instructions" contained in the fileset.
As Jayan pointed out it might be worth posting the final outcome as an answer, so here's a simplified version with the key parts:
<fileset id="files" dir="${target.dir}"/>
<pathconvert property="before.files" pathsep=",">
<fileset refid="files"/>
</pathconvert>
<!-- Other Ant code changes the file-system. -->
<pathconvert property="after.files" pathsep=",">
<fileset refid="files"/>
</pathconvert>
<filelist id="before.files" files="${before.files}"/>
<filelist id="after.files" files="${after.files}"/>
<difference id="changed.files">
<filelist refid="before.files"/>
<filelist refid="after.files"/>
</difference>

Renaming files with dir values using Ant?

I have the following simple thing to do with Ant but did not find how to do that:
move build/xxx/file.ext to dest/xxxfile.ext
I'm no Ant Guru .
file.ext is constant in this particular case
Nota : xxx can take many values so I want to apply to all these values
You need to use a mapper element to generate the destination file names. This is derived from the Ant mapper docs:
<move todir="dest">
<fileset dir="build" includes="*/*.ext" />
<mapper type="regexp" from="^([^/]*)/([^/]*)" to="\1\2"/>
</move>
When in doubt, an exec will do the job for you, but it's not always the best way.
Try the move task.
<move file="build/xxx/file.ext" tofile="dest/xxxfile.ext"/>

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.

How to determine if a property value is directory path using ANT?

We have a property file containing list of key and their values. The value of a property can be directory paths or numeric values or hyperlink URLs or database URLs or database server I.P address or port numbers etc.
I would like to know if there is a way in ANT build file to detrmine if the value of a property is directory path or not. Based on the answer, for the values with directory path, we would like to execute a special logic than others.
Please advise.
You want to use the Available Ant task. This is untested but it should get you started.
<target name="check.directory">
<available file="${my.property}" type="dir" property="my.property.present"/>
</target>
<target name="do-if-directory" depends="check.directory" if="my.property.present">
<!-- custom task here -->
</target>
Alternatively you can use the Condition Ant Task.

Execute Ant action always and independently from target

Is there a way to specify actions like <copy> in an Ant buildfile that get executed every time the build file gets read by ant (regardless of the target which is called)?
The background is: I want a *.properties-file to be automatically created from a template when it's not present. I know, I could specify a target which does this and then include it at the root of the dependency-tree but maybe there is a more elegant solution. Because actually the problem is a bit more complex: the ant file where the *.properties-file is read-out is imported by other build files and I don't want to cross-reference targets between them.
I hope I explained my problem sufficiently. In cases of questions do not hestitate to ask.
This is my first posting here. Hope you can help - Greetings from Germany, Ben.
Just put the code at the top of the file, outside of a target definition.
<project name="myproject" default="mytarget" basedir=".">
<echo message="Hello there." />
<target name="mytarget">
<!-- Do stuff. -->
</target>
<target name="myothertarget">
<!-- Do other stuff. -->
</target>
</project>
In this case the echo will get executed once before any target, regardless of which target is invoked.

Resources