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

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)\]"

Related

How can I extract version from a file name in Ant without using ant contrib?

I am trying to scan a folder in ant script and extract the version out of it, suppose file name is abc-1.0.0.exe/dmg. I want to get the 1.0.0 in Ant. Is there any way I can do without using ant contrib? I only found help with ant contrib which I don't want to use.
You might be able to use something like this, based on the <pathconvert> task with a regexmapper.
Here's the directory structure in this example:
$ find folder
folder
folder/abc-1.0.0.exe
folder/abc-1.0.0.exe/dmg
Here's the Ant buildfile:
<fileset dir="folder" id="folder"/>
<echo message="file is: ${toString:folder}" />
<pathconvert property="version">
<path path="${toString:folder}" />
<regexpmapper from=".*-(.*).exe.*" to="\1" />
</pathconvert>
<echo message="version is: ${version}" />
Output:
[echo] file is: abc-1.0.0.exe/dmg
[echo] version is: 1.0.0

How to read the Class-Path from a JAR in Ant?

The Class-Path of a JAR is written in the Manifest file in the JAR. The following Bash code reads the Class-Path from a JAR, if it does not exceed the 72 char limit:
unzip -c "$1" META-INF/MANIFEST.MF |
sed -n 's/^Class-Path: \(.\+\)$/\1/p' |
tr -d '\r'
Right now I am calling the code with exec in Ant but I would like to remove all execs.
How to do the same in Ant without using unzip, sed and tr?
You may want to try adding the following (in the beginning of your build.xml file where properties are defined) which puts the short Class-Path in property classpath:
<loadresource property="classpath">
<zipentry zipfile="demo.jar" name="META-INF/MANIFEST.MF"/>
<filterchain>
<tokenfilter>
<containsregex pattern="^Class-Path: (.+)$" flags="i"/>
<replaceregex pattern="^Class-Path: (.+)$" replace="\1" flags="i"/>
</tokenfilter>
<tokenfilter><!-- get rid of trailing line separator -->
<filetokenizer/>
<replaceregex pattern="(\r?\n)+" replace="" flags="m"/>
</tokenfilter>
</filterchain>
</loadresource>
Edit: If you put the following before the tokenfilter above, then it should also work for longer values of Class-Path (by first joining split lines):
<tokenfilter>
<filetokenizer/>
<replaceregex pattern="\r?\n (.+)$" replace="\1" flags="m"/>
</tokenfilter>

Ant resourcecount , how can I count the number of commas delimited existing in property

My xml does not work:
When I run in command line
ant compile -Dmodules=a,b,c
My build file need to count how many modules in modules parameters, compile them one by one using for loop
<target name="count_modules">
<resourcecount property="count">
<tokens>
<concat>
<filterchain>
<tokenfilter>
<stringtokenizer delims=","/>
</tokenfilter>
</filterchain>
<propertyresource name="modules" />
</concat>
</tokens>
</resourcecount>
<echo message="count is ${count}" />
</target>
count will always return 1
[echo] count is 1
The propertyresource will return a single resource to the concat task which is designed to act on resources like files.
This complex piece of logic is best replaced by an in-line script.
<project name="myproject" default="count_modules">
<property name="modules" value="a,b,c"/>
<target name="count_modules">
<script language="javascript"><![CDATA[
modules = project.getProperty("modules");
project.setProperty("count", modules.split(",").length);
]]></script>
<echo message="Number of modules: ${count}"/>
</target>
</project>
Running sub-module builds
The for task is not part of core ant, it's part of an extension called ant-contrib. My advice is to use the subant task when invoking sub-module builds. The following answer has some simple and advanced examples of its use:
Ant Script to Automate the build process

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

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

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