Ant pass specific string values from one file to another - regex

I'm trying to configure autoincrement of version number in an Android aplication.
I've configured Ant tasks which make a checkout of the file then autoincrement the string with version value and then automatically do check-in in TFS system. So this test.properties file has this contetnt:
versionCode="1"
Autoincrement did this task:
<propertyfile file="${basedir}/src/test.properties">
<entry key="versionCode" value="1" type="int" operation="+" />
</propertyfile>
How would I configure replacement of the value of this string: android:versionCode="1", located in the target file androidmanifest.xml?

I suppose you can use the ReplaceRegExp task in Ant:
Directory-based task for replacing the occurrence of a given regular expression with a substitution pattern in a file or set of files.
It might look something like this:
<replaceregexp file="${src}/androidmanifest.xml"
match="android:versionCode="[0-9]+""
replace="android:versionCode="${versionCode}""
/>
The build.number property could be obtained by reading in the property file before running this task.

A solution with vanilla ant, no Ant addon needed, you may use a propertyfiletemplate that has =
f.e. named props.txt
...
android:versionCode=#versionCode#
...
and later on use the property ${versionCode} set by your workflow
and create a propertyfile from your template with copy + nested filterset =
<!-- somewhere set in your workflow maybe via userproperty -DversionCode=42 -->
<property name="versionCode" value="42"/>
...
<copy file="props.txt" todir="/some/path" overwrite="true">
<filterset>
<filter token="versionCode" value="${versionCode}"/>
</filterset>
</copy>
/some/path/props.txt will have =
...
android:versionCode=42
...
see Ant Manual on filtersets

Related

Read content of a set of file and check existence of a file in Ant

I'm new to Ant and I can't quite figure out how to do the following (if possible at all):
I have this basic code:
<copy todir="${mydir}">
<fileset dir="${mydir2}" includes="**/*.html" />
<filterchain>
<replaceregex pattern="bla" replace="pla"/> <!-- regex1 -->
<replaceregex pattern="doh" replace="dah"/> <!-- regex2 -->
<filterchain>
</copy>
In the folder recursed by the fileset task, I have a bunch of html files, some contain a link to an existing file, some contain a link to an non-existing file.
Now what I'm trying to do is to:
Read each file of the fileset to extract a specific link that they all contain.
See if this link points to an existing file.
If it does, I apply regex1.
If it doesn't, I apply regex2 to remove the dead link.
So there's a bit of everything: conditions, retrieval of data from files to Ant to use it in other tasks, and it seems impossible to do!
Thanks for the help.
Use filterchain with tokenfilter replaceregex, f.e. :
<copy todir="${mydir}">
<fileset dir="${mydir2}" includes="**/*.html"/>
<filterchain>
<tokenfilter>
<!-- regex 1 -->
<replaceregex pattern="hello" replace="world" flags="gi"/>
<!-- regex 2 -->
<replaceregex pattern="doh" replace="dah"/>
</tokenfilter>
</filterchain>
</copy>
It seems Ant-contrib has a task that allows you to retrieve the result of a regexp andstore that in an ant property, that will do the job for sure to test the existence of the file and then go on a provided switch statement.

Ant task replace escaped URI param

I'm trying to use Ant to remove a url parameter in an xml file.
The line in the xml is similar to below.
<from uri="http://www.google.com?q=test&somethingElse=something" />
I want to remove the "&somethingElse=something". "something" could be different values so it must be generic.
I've tried
<replaceregexp file="somefile.xml" match="&somethingElse(.*)" replace='" />' flags="gs" byline="true" />
<replaceregexp file="somefile.xml" match="\&somethingElse(.*)" replace='" />' byline="true" />
<replaceregexp file="somefile.xml" match="(&)somethingElse(.*)" replace='" />' flags="gs" byline="true" />
but those don't seem to work.
$(ant.regexp.regexpimpl) is not set so the default engine is being used.
In order to get & you need to write & in the Ant build file because it is XML. To match &somethingElse in the input of the replaceregexp Ant task you might therefore need to specify &amp;somethingElse in the Ant build file.

Set Ant property based on a regular expression in a file

I have the following in a file
version: [0,1,0]
and I would like to set an Ant property to the string value 0.1.0.
The regular expression is
version:[[:space:]]\[([[:digit:]]),([[:digit:]]),([[:digit:]])\]
and I need to then set the property to
\1.\2.\3
to get
0.1.0
I can't workout how to use the Ant tasks together to do this.
I have Ant-contrib so can use those tasks.
Based on matt's second solution, this worked for me for any (text) file, one line or not. It has no apache-contrib dependencies.
<loadfile property="version" srcfile="version.txt">
<filterchain>
<linecontainsregexp>
<regexp pattern="version:[ \t]\[([0-9]),([0-9]),([0-9])\]"/>
</linecontainsregexp>
<replaceregex pattern="version:[ \t]\[([0-9]),([0-9]),([0-9])\]" replace="\1.\2.\3" />
</filterchain>
</loadfile>
Solved it with this:
<loadfile property="burning-boots-js-lib-build.lib-version" srcfile="burning-boots.js"/>
<propertyregex property="burning-boots-js-lib-build.lib-version"
override="true"
input="${burning-boots-js-lib-build.lib-version}"
regexp="version:[ \t]\[([0-9]),([0-9]),([0-9])\]"
select="\1.\2.\3" />
But it seems a little wasteful - it loads the whole file into a property!
If anyone has any better suggestions please post :)
Here's a way that doesn't use ant-contrib, using loadproperties and a filterchain (note that replaceregex is a "string filter" - see the tokenfilter docs - and not the replaceregexp task):
<loadproperties srcFile="version.txt">
<filterchain>
<replaceregex pattern="\[([0-9]),([0-9]),([0-9])\]" replace="\1.\2.\3" />
</filterchain>
</loadproperties>
Note the regex is a bit different, we're treating the file as a property file.
Alternatively you could use loadfile with a filterchain, for instance if the file you wanted to load from wasn't in properties format.
For example, if the file contents were just [0,1,0] and you wanted to set the version property to 0.1.0, you could do something like:
<loadfile srcFile="version.txt" property="version">
<filterchain>
<replaceregex pattern="\s+\[([0-9]),([0-9]),([0-9])\]" replace="\1.\2.\3" />
</filterchain>
</loadfile>

Ant regexp mapper: Reading patterns from a file?

I would like to write a generic Ant build script with a <copy> task that could optionally rename files based on regexps. A nested <regexpmapper> would load the renaming patterns from a project-specific properties files if it exists.
Has someone already done this or do I have to write an own mapper?
Here's an example of how you might do this.
Project properties file proj_props.txt contains:
use.filter=regexp.mapper
from.regexp=(.*)_test(.*)
to.regexp=\\1\\2
(Note the escapes \ in the to string.)
Buildfile:
<property file="proj_props.txt" />
<!-- filter for regexp -->
<filtermapper id="regexp.mapper">
<tokenfilter>
<replaceregex pattern="${from.regexp}"
replace="${to.regexp}" />
</tokenfilter>
</filtermapper>
<!-- identity filter, used when no regexp needed -->
<filtermapper id="identity.mapper" />
<!-- decide which filter to use -->
<condition property="chosen.mapper"
value="regexp.mapper" else="identity.mapper">
<isset property="use.filter" />
</condition>
<copy todir="...">
<fileset>
...
</fileset>
<filtermapper refid="${chosen.mapper}" />
</copy>
You define a couple of filtermapper instances, one that carries out a regexp replace based on properties from the project properties file, the other that does nothing. The use.filter property decides which gets chosen. If the project properties file doesn't exist use.filter would not be set, so the 'do-nothing' identity filtermapper will be used.
Note that this only works when using nested resources in the copy task. If you only have one file to copy, and use <copy file="...", the filtermapper is ignored.

Exclude nodes based on attribute wildcard in XSL node selection

Using cruisecontrol for continuous integration, I have some annoyances with Weblogic Ant tasks and how they think that server debug information are warnings rather than debug, so are shown in my build report emails. The XML output from cruise is similar to:
<cruisecontrol>
<build>
<target name="compile-xxx">
<task name="xxx" />
</target>
<target name="xxx.weblogic">
<task name="wldeploy">
<message priority="warn">Message which isn't really a warning"</message>
</task>
</target>
</build>
</cruisecontrol>
In the cruisecontrol XSL template the current selection for the task list is:
<xsl:variable name="tasklist" select="/cruisecontrol/build//target/task"/>
What I would like is something which selects the tasklist in the same way, but doesn't include any target nodes which have the attribute name="*weblogic" where * is a wildcard. I have tried
<xsl:variable name="tasklist" select="/cruisecontrol/build//target[#name!='*weblogic']/task"/>
but this doesn't seem to have worked. I'm not an expert with XSLT, and just want to get this fixed so I can carry on the real development of the project. Any help is much appreciated.
In the cruisecontrol XSL template the
current selection for the task list
is:
<xsl:variable name="tasklist" select="/cruisecontrol/build//target/task"/>
What I would like is something which
selects the tasklist in the same way,
but doesn't include any target nodes
which have the attribute
name="*weblogic" where * is a wildcard
Use:
/cruisecontrol/build
//target
[not(substring(#name, string-length(#name)-7)
= 'weblogic'
)
]/task