Naming a file in Apache Ant based on contents of different file - ant

I've got foo.js, and an ant build process that results in foo.min.js.
foo.js has a header comment that includes:
* $Id: foo.js 12345 2011-10-04 14:35:23Z itoltz $
Where 12345 is the revision of the file when committed to SVN.
I'd like to copy foo.min.js to foo.min.12345.js

You can extract the revision number into a property using loadfile and regex. Then you can copy the file using the property.
<project default="rename">
<target name="rename" depends="get-rev">
<copy file="foo.min.js" toFile="foo.min.${revision.number}.js"/>
</target>
<target name="get-rev">
<loadfile srcFile="foo.js" property="revision.number">
<filterchain>
<linecontainsregexp>
<regexp pattern="\* \$Id: foo.js"/>
</linecontainsregexp>
<tokenfilter>
<replaceregex pattern="\* \$Id: foo.js (\d+).*" replace="\1"/>
</tokenfilter>
<striplinebreaks/>
</filterchain>
</loadfile>
<echo message="revision.number: ${revision.number}"/>
</target>
</project>
Output:
$ ls
build.xml foo.js foo.min.js
$
$ ant
Buildfile: C:\tmp\build.xml
get-rev:
[echo] revision.number: 12345
rename:
[copy] Copying 1 file to C:\tmp
BUILD SUCCESSFUL
Total time: 0 seconds
$
$ ls
build.xml foo.js foo.min.12345.js foo.min.js

Related

Ant: Why are my CLI args not persisting when I invoke targets that use them?

I have a property and target in my build.xml:
<property name="somedir" value="path/to/dir/${prop}"/>
<echo message="${prop}"/>
<target name="foo">
<echo message="Property: ${somedir}"/>
</target>
In the directory where build.xml is I run:
ant -Dprop="someVal" foo
This gets echoed:
[echo] someVal
[echo] Property: path/to/dir/
What happened to ${prop} when foo is called? How do I get the value to persist when foo is invoked?
Thanks in advance!
I can't reproduce your issue. What version of ANT are you using?
build.xml
<project name="demo" default="foo">
<property name="somedir" value="path/to/dir/${prop}"/>
<echo message="${prop}"/>
<target name="foo">
<echo message="Property: ${somedir}"/>
</target>
</project>
Run as follows:
$ ant -Dprop=hello
Buildfile: /home/me/tmp/build.xml
[echo] hello
foo:
[echo] Property: path/to/dir/hello
ANT version:
$ ant -version
Apache Ant(TM) version 1.9.0 compiled on March 5 2013
I'm using Ant version 1.8.4
I have this as my build.xml
<project>
<property name="somedir" value="path/to/dir/${prop}"/>
<echo message="${prop}"/>
<target name="foo">
<echo message="Property: ${somedir}"/>
</target>
</project>
I get this:
$ ant -Dprop=foo foo
Buildfile: /Users/david/build.xml
[echo] foo
foo:
[echo] Property: path/to/dir/foo
BUILD SUCCESSFUL
Total time: 0 seconds
I had to put <project> and </project> in the build.xml or else it wouldn't execute.
Is there something I'm missing? It seems to work fine.
I was trying to overwrite a pre-defined property that is immutable from the build.xml ...this is more along the lines of what I'm trying to do:
<project>
<property name="basedir" value="/usr/me/${prop}"/>
<echo message="${basedir}"/>
</project>
echos:
Buildfile: build.xml
[echo] /usr/me
BUILD SUCCESSFUL
Total time: 0 seconds
facepalm

Want to remove [echo], [script] like keywords from file

I am using filter in a filterchain, in a task which supports the filterchain element, i.e. the built-in Concat, Copy, LoadFile, LoadProperties, Move tasks.
So, for example, copy or move the file using a filterchain containing your linecontains filter.
Use the negate parameter on your linecontains filter to exclude lines containing that string.
Example: Consider the following code
<project default="test">
<target name="test">
<copy tofile="file.txt.edit" file="file.txt">
<filterchain>
<linecontains negate="true">
<contains value="[echo]"/>
</linecontains>
</filterchain>
</copy>
</target>
</project>
outputs:
$ cat file.txt
[echo] Your project1 location is: D:/Project/Project1
[echo] Your project2 location is: D:/Project/Project2
[script] my script running
[echo] Your project3 location is: D:/Project/Project3
[echo] Your project4 location is: D:/Project/Project4
$ cat file.txt.edit
[script] my script running
Expected:
$ cat file.txt.edit
Your project1 location is: D:/Project/Project1
Your project2 location is: D:/Project/Project2
[script] my script running
Your project3 location is: D:/Project/Project3
Your project4 location is: D:/Project/Project4
Here if i am using filterchain then complete line gets deleted. I want only the word like
[echo], [script]...etc. should be removed.
Replace your linecontains element with replaceregex:
<tokenfilter>
<replaceregex pattern="\[echo\]" replace="" />
</tokenfilter>
For multiple token replacements, modify pattern="\[(echo|script)\]"

Ant mkdir failed

i'm new to ant. Please highlight which goes wrong in my build.xml. Any help is appreciated. Thanks.
Problem: The folders i wanted to make kept created on the upper level of current directory.
ant version: 1.8.0
platform: LinuxMint 10.10
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.9) (6b20-1.9.9-0ubuntu1~10.10.2)
OpenJDK Server VM (build 19.0-b09, mixed mode)
build.xml:
<property name="prj.root" value="." />
<property name="build.dir" value="${prj.root}/build"/>
<property name="build.docs" value="${build.dir}/docs"/>
<property name="build.models" value="${build.dir}/models"/>
<property name="build.projects" value="${build.dir}/projects"/>
<property name="dist.dir" value="${prj.root}/dist"/>
<target name="clean">
<delete dir="${build.dir}" />
<delete dir="${dist.dir}" />
</target>
<target name="init" depends="clean" description="initialization target">
<echo message=">> Build JAS ${jas.version} at ${prj.root}"/>
<echo message="build.dir = ${build.dir}" />
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.docs}" />
<mkdir dir="${build.models}" />
<mkdir dir="${build.projects}" />
<mkdir dir="${dist.dir}"/>
</target>
Execution + Output:
yamhon#yamhon-g410 ~/projects/JAS $ ant init
Buildfile: /home/yamhon/projects/JAS/build.xml
clean:
[delete] Deleting directory /home/yamhon/projects/build
[delete] Deleting directory /home/yamhon/projects/dist
init:
[echo] >> Build JAS ${jas.version} at .
[echo] build.dir = ./build
[mkdir] Created dir: /home/yamhon/projects/build
[mkdir] Created dir: /home/yamhon/projects/build/docs
[mkdir] Created dir: /home/yamhon/projects/build/models
[mkdir] Created dir: /home/yamhon/projects/build/projects
[mkdir] Created dir: /home/yamhon/projects/dist
BUILD SUCCESSFUL
Total time: 0 seconds
yamhon#yamhon-g410 ~/projects/JAS $
Two things you can try.
1) Resolve your relative '.' path by assigning it to a property with the location attribute.
<property name="my.path" location="."/>
<echo message="my.path = ${my.path}"/>
2) Use the build in basedir property which points to the directory of the build.xml file itself.
<echo message="basedir = ${basedir}"/>
This should get you going :)

strip till delimeter in ant

I have a target which will run a executable and get a version. But I need to remove stuff till the delimeter. Help me please.
<target name="tomcatVersion">
<exec executable="${WT_HOME}/tomcat/bin/catalina.bat" outputproperty="tomcat.version">
<arg value="version" />
<redirector>
<outputfilterchain>
<tokenfilter>
<containsstring contains="Server number:"/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo message="${tomcat.version}"/>
</target>
[Update: single step loadresource method with thanks to Matt]
You could do this by reading the output of the executable into a property and then filtering the property through a replaceregexp token filter to extract the string you require. For example:
<project default="get-version">
<target name="get-version">
<exec executable="bash" outputproperty="version.output">
<arg value="ant"/>
<arg value="-version"/>
</exec>
<loadresource property="version">
<string value="${version.output}"/>
<filterchain>
<tokenfilter>
<replaceregex pattern="[^\d]*(\d.\d.\d).*" replace="\1"/>
</tokenfilter>
<striplinebreaks/>
</filterchain>
</loadresource>
<echo level="info" message="version is: '${version}'"/>
</target>
</project>
Sample output:
$ ant -version
Apache Ant(TM) version 1.8.2 compiled on December 20 2010
$ ant
Buildfile: build.xml
get-version:
[echo] version is: '1.8.2'
BUILD SUCCESSFUL
Total time: 2 seconds
(I am using ant -version as a handy stand in for whatever executable you are running. I am aware that Ant version can be got from Ant properties.)
With older versions of Ant (<1.7) you could do this in two steps:
Write the output of the executable to file
Read the file through a replaceregexp token filter
For example:
<project default="get-version">
<target name="get-version">
<exec executable="bash" output="version.out">
<arg value="ant"/>
<arg value="-version"/>
</exec>
<loadfile property="version" srcfile="version.out">
<filterchain>
<tokenfilter>
<replaceregex pattern="[^\d]*(\d.\d.\d).*" replace="\1"/>
</tokenfilter>
<striplinebreaks/>
</filterchain>
</loadfile>
<echo level="info" message="version is: '${version}'"/>
</target>
</project>
Sample output
$ ant -version
Apache Ant version 1.6.5 compiled on June 2 2005
$ ant
Buildfile: build.xml
get-version:
[echo] version is: '1.6.5'
BUILD SUCCESSFUL
Total time: 2 seconds
The exec task has 3 attributes to catch the output from an executable :
outputproperty => catches stdout
errorproperty => catches stderr
resultproperty => catches returncode
see Ant Manual for exec task
So for your purpose :
use outputproperty to catch the
version written to stdout
grep the versionstring from
outputproperty via String replace
function from Ant Plugin Flaka
<project xmlns:fl="antlib:it.haefelinger.flaka">
<exec executable="bash" outputproperty="bashversion">
<arg value="--version"/>
</exec>
<fl:let>bashversion ::= '#{replace('${bashversion}','$2','(?s)(.+)(\d\.\d\.\d\(.\)?)(.+)')}'</fl:let>
<fl:echo>
Bashversion => ${bashversion}
</fl:echo>
</project>
output :
[fl:echo] Bashversion => 4.1.7(1)

Filtering Files In-Place with Ant?

I have a directory of files for which I'd like to do "in-place" string filtering using Apache Ant (version 1.7.1 on Linux).
For example, suppose that in directory mydir I have files foo, bar, and baz. Further suppose that all occurences of the regular expression OLD([0-9]) should be changed to NEW\1, e.g. OLD2 → NEW2. (Note that the replace Ant task won't work because it does not support regular expression filtering.)
This test situation can be created with the following Bash commands (ant will be run in the current directory, i.e. mydir's parent directory):
mkdir mydir
for FILE in foo bar baz ; do echo "A OLD1 B OLD2 C OLD3" > mydir/${FILE} ; done
Here is my first attempt to do the filtering with Ant:
<?xml version="1.0"?>
<project name="filter" default="filter">
<target name="filter">
<move todir="mydir">
<fileset dir="mydir"/>
<filterchain>
<tokenfilter>
<replaceregex pattern="OLD([0-9])" replace="NEW\1" flags="g"/>
</tokenfilter>
</filterchain>
</move>
</target>
</project>
Running this first Ant script has no effect on the files in mydir. The overwrite parameter is true by default with the move Ant task. I even fiddled with the granularity setting, but that didn't help.
Here's my second attempt, which "works," but is slightly annoying because of temporary file creation. This version filters the content properly by moving the content to files with a filtered suffix, then the filtered content is "moved back" with original filenames:
<?xml version="1.0"?>
<project name="filter" default="filter">
<target name="filter">
<move todir="mydir">
<globmapper from="*" to="*.filtered"/>
<fileset dir="mydir"/>
<filterchain>
<tokenfilter>
<replaceregex pattern="OLD([0-9])" replace="NEW\1" flags="g"/>
</tokenfilter>
</filterchain>
</move>
<move todir="mydir">
<globmapper from="*.filtered" to="*"/>
<fileset dir="mydir"/>
</move>
</target>
</project>
Can the first attempt (without temporary files) be made to work?
See the replace task:
<replace
dir="mydir"
includes="foo, bar, baz">
<replacefilter token="OLD" value="NEW" />
</replace>
or the replaceregexp task:
<replaceregexp
file="${src}/build.properties"
match="OldProperty=(.*)"
replace="NewProperty=\1"
byline="true"/>

Resources