I would have thought that if you didn't provide a destination, xmltask would modify the source file and replace it, but apparently that's not the case since the below code does not work:
<xmltask source="**\plugin.xml">
<attr path="plugin" attr="version" value="12345" />
</xmltask>
If I specify a destination, I get an error saying "Multiple inputs, but only one destination":
<xmltask source="**\plugin.xml" dest="**\plugin.xml">
<attr path="plugin" attr="version" value="12345" />
</xmltask>
How can I get this to work with wildcards? Is it possible?
Instead of specifying a single output file with dest, specify an output directory with todir:
<xmltask source="**\plugin.xml" todir="output">
<attr path="plugin" attr="version" value="12345" />
</xmltask>
Related
in my build file, I have declared:
<basename property="filename" file="${args.input}" suffix="XML"/>
where ${args.input} is passed in through an Oxygen transformation scenario, ex -Dargs.input="${cfd}\PMC-min.XML"
${filename} returns PMC-min, which is the desired output. I want the file name without any extension.
However, after discovering an error I realized that
<basename property="filename" file="${args.input}" suffix="xml"/>
was returning PMC-min.XML. So #suffix is case-sensitive.
I could change ${args.input} to ${cfd}\PMC-min (which would require other changes to the build file), or just make sure the extension case of ${args.input} matches #suffix in the scenario. But I was wondering if there was a case-insensitive way to retrieve the filename without the extension in ant? (It doesn't seem to matter if the case of the actual file's extension is different, only the parameters have to match).
One way that might work for you is to use a <mappedresources> "collection of one", something like this:
<mappedresources id="converted">
<string value="${args.input}" />
<chainedmapper>
<flattenmapper />
<globmapper casesensitive="false" from="*.xml" to="*" />
</chainedmapper>
</mappedresources>
<echo message="file_name=${toString:converted}" />
The echo is just to illustrate how to reference the resource.
In the above:
the string resource specifies the input value
the chained mapper combines two mapping steps to alter the string:
a flattenmapper removes the directory part
a globmapper removes the suffix, ignoring case.
I've looked all over the net as to how I can load a list of files that contain spaces and don't yet exist with an Ant task.
I have a file that contains one file path per line, like so:
dir1/dir2/dir with spaces/file1.js
dir1/dir2/dir with spaces/dir3/file2.js
dir1/file1.js
Since the paths have spaces I cannot use:
<filelist files="..." />
The files also don't exist yet, so it seems like I can't use
<fileset>
<includesfile name="..." />
</fileset>
Any ideas would be greatly appreaciated.
You can use a resourcelist for this. For example, if your list of files are in a file called 'files.txt':
<resourcelist id="files">
<file file="files.txt"/>
</resourcelist>
<touch mkdirs="true">
<resources refid="files" />
</touch>
For me this yields:
[touch] Creating .../filelist/dir1/dir2/dir with spaces/file1.js
[touch] Creating .../filelist/dir1/dir2/dir with spaces/dir3/file2.js
[touch] Creating .../filelist/dir1/file1.js
The reason this works is that a <resourcelist> treats each line in the file read as a separate resource, so line separators rather than commas or spaces divide the items.
I'm currently using ant to remove lines from a file if the line matches any of a list of email addresses, and output a new file without these email addresses as follows:
<copy file="src/emaillist.tmp2" tofile="src/emaillist.txt">
<filterchain>
<linecontains negate="true"><contains value="paultaylor#hotmail.com"/>
</linecontains>
<linecontains negate="true"><contains value="paultaylor2#hotmail.com"/>
</linecontains>
........
........
</filterchain>
</copy>
But I already have a file containing a list of the invalid email addresses (invalidemail.txt) I want to remove, so I want my ant file to read the list of invalid email addresses from this file rather than having to add a element for each email I don't want. Cannot work out how to do this.
Ant has some useful resource list processing tasks. Here's a 'prototype' solution.
Load the input and exclusion lists to two resource collections, tokenized by default on line breaks.
<tokens id="input.list">
<file file="src/emaillist.tmp2"/>
</tokens>
<tokens id="invalid.list">
<file file="invalidemail.txt"/>
</tokens>
Do some set arithmetic to produce a resource list of clean emails:
<intersect id="to_be_removed.list">
<resources refid="input.list"/>
<resources refid="invalid.list"/>
</intersect>
<difference id="clean.list">
<resources refid="input.list"/>
<resources refid="to_be_removed.list"/>
</difference>
Here's some diagnostics that may be useful:
<echo message="The input list is: ${ant.refid:input.list}" />
<echo message="Emails to be removed: ${ant.refid:to_be_removed.list}" />
<echo message="The clean list is: ${ant.refid:clean.list}" />
Use the pathconvert task to reformat the clean list into one entry per line:
<pathconvert property="clean.prop" refid="clean.list"
pathsep="${line.separator}" />
Finally, output to a file:
<echo file="src/emaillist.txt">${clean.prop}
</echo>
I have a comma-delimited list of directories:
foo,bar,baz,qux
I want to convert it to an Ant path containing (something like) the following:
${basedir}/build/foo/classes
${basedir}/build/bar/classes
${basedir}/build/baz/classes
${basedir}/build/qux/classes
It seems like there should be a way to do this with <pathconvert>, but it's not obvious to me what it would be. Suggestions?
You might be able to use a dirset to hold your list of directories, then feed that into pathconvert. Something like:
<property name="dirs" value="foo,bar,baz,qux" />
<dirset id="dir_list" dir="${basedir}" includes="${dirs}" />
<pathconvert refid="dir_list" property="dirs_prop">
<regexpmapper from="(${basedir})/(.*)" to="\1/build/\2/classes" />
</pathconvert>
Then the property ${dirs_prop} will hold the path you want... or almost. The problem with dirset is that the order of directories is not defined. To retain the order of the original list, use a filelist in place of the dirlist:
<filelist id="dir_list" dir="${basedir}" files="${dirs}" />
My ant project generates an "output" folder which contains the outputs of multiple runs and I would like to diff them all against files located in an "expected" folder (these lasts have the exact the same name as the ones in the output folder). I tried that:
<apply executable="diff">
<fileset dir="${output.dir}" />
<arg value="-u" />
<srcfile />
<arg value="${expected.dir}/" />
<srcfile />
<redirector>
<outputmapper type="merge" to="result.out" />
</redirector>
</apply>
But I have two problems:
First I am not allowed to put two <srclist /> in one <apply>, so how can I use two times the name of the current file treated in one <apply>?
Second I am not able to get the output of my <apply> in one single file. I tried different ways (putting the output argument in the <apply> tag...) but it always seems to only store the last execution of the apply. How can I append the result of each diff in one single file?
And I don't want to have to install anything else (so no ant-contrib with foreach).
Thanks.
This works for me:
<delete file="result.out" />
<apply executable="diff" force="yes" output="result.out" append="true">
<fileset dir="${output.dir}" />
<srcfile />
<targetfile />
<mapper type="glob" from="*" to="${expected.dir}/*" />
</apply>
Some explanation:
The apply task targetfile element lets you specify a second arg that is derived from the srcfile via the mapper.
To get the merged output use the output attribute and set append true. Note that you may need to delete the output file (i.e. truncate it) otherwise on rerun you'll not get a clean slate.
I fiddled with the arg list for diff to suit my OS, instead of passing expected.dir and the target file as successive elements, the mapper merges them into a single full path to the 'right hand' file for the diff.