How to conditionally <echo> into a log-file? - ant

We need to output some logging entries into a file, but only when the filename is specified. The current task reads:
<echo fileName="${debugLog}" message="${message}"/>
Currently, when the debugLog-property is not set, it creates a file named, literally "${debugLog}". How can I make it simply skip the task, when the property is not defined?
Our ant is old (1.6.5 - and cannot be upgraded), and the if:set="debugLog" attribute is simply ignored, but we use ant-contrib already, and <if> is available.

Related

Checking file exists in a particular directory using Ant

I have file abc.txt and i need to check that file exists in suppose
c:\test\abc.txt location
If true then I need to print some message else I need to perform some operation.
Best is to use ant <available ../> to fill a property and then either using ant-contrib <if> task or create separate targets that run depending on the property value.
Check this answer for details: Ant task to run an Ant target only if a file exists?

Create a fileset from a comma-separated list in a property without losing order

I use a specified property to create fileset:
<property name="cases" value="B.java,A.java,C.java" />
<fileset id="casesToBeRunning" dir="${src}" includes="${cases}" />
When casesToBeRunning created, I list the content of it:
<echo>Cases to be running: ${toString:casesToBeRunning}</echo>
it shows A.java,B.java,C.java which I'm not expected to.
I don't want Ant autosort for me, I need the original sort order of the property I defined to execute the cases orderly.
Anyone know how to handle this?
Ant filesets don't retain order - as you've seen. The related filelist type does respect ordering, so you might use:
<filelist id="casesToBeRunning" dir="${src}" files="${cases}" />
Whether the order is respected will depend on what task you plan to use to process the files. Most core Ant tasks that accept a fileset will accept a filelist instead, so you should be ok with them. For non-core tasks it may not work.
(Note that before Ant 1.8.0 some tasks didn't respect the order when traversing a filelist - among them copy for example).

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.

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: Create directory containing file if it doesn't already exist?

Basically, I get a path like "C:\test\subfolder1\subfolder2\subfolder3\myfile.txt", but it's possible that subfolders 1-3 don't exist already, which means I'd get an exception if I try to write to the file.
Is there a way to create the directory structure the target file is in, either by using some task that creates the structure when it outputs to the file and then deleting the file, or by parsing the directory part of the path and using the mkdir task first?
Ant will create the full tree of directories for you when you use the <mkdir> task. So you just need to use the <dirname> task to get the directory name from the file name.
<dirname property="directoryProperty" file="${filePathProperty}"/>
<mkdir dir="${directoryProperty}" />
The first line extracts the directory portion of your file path and stores it in the directoryProperty property. The second line creates the directory (and any parent directories that don't exist).
This task works well
<mkdir dir="${file}/../"/>
Sometimes we could have an alternate choice, using touch task
<touch file="${file}" mkdirs="true" verbose="true"/>
This task should do the job but would have a side effect to create the file with zero size
Just make failonerror=false to avoid the error to stop the whole logic.
<delete includeemptydirs="true" failonerror="false">
<fileset dir="${builder-base.dir}" includes="**/*"/>
</delete>
Using the
<mkdir dir="${dir}"/ >
inside your <target> tag should work, but I am not sure what else you want to do along with mkdir?
I'm not 100% sure it'll work but you might be able to do something like the following to make the parent directory you're after:
<mkdir dir="${file}/../"/>
If that doesn't work straight off then it might be worth defining a property using the location syntax before creating a directory with the new property:
<property name="dir" location="${file}/../" />
<mkdir dir="${dir}" />
Well-behaved Ant tasks are generally expected to create any necessary directory structures unless there is a good reason not to.
Are you writing a task? If so you should add the directory creation logic to your task. If you are getting the task from a third party you should point this fact out to them and have them fix their task. Failing that Dan's solution should work.

Resources