ant replace tokens how to ignore new lines? - ant

I am copying a file while doing search and replace tokens in ant using replaceregex tag
tokens exist in a separate text file specified in the propertiesfile
token1=SDF234\n1sdfad
token2=FooBarBaz\nBar
the config.ini file has replacement values as : ${token1}
Some tokens have \n in them and the replaceregex adds a new line
I tried to add : byline="true" without success
I also added flags="m" to the replaceregex tag, it didn't work
sample token:
QWpVsL2Ti\njWhT\n
the code replaces it like:
QWpVsL2Ti
jWhT
the desired replacement should be in the same line ignoring the \n
ant task:
<copy file="../../config.ini" tofile="./Package/config.ini">
<filterchain>
<replaceregex pattern="\$\{" replace="{" byline="true"/>
<filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
<param type="propertiesfile" value="properties_${build_target}.ini"/>
<param type="tokenchar" name="begintoken" value="{"/>
<param type="tokenchar" name="endtoken" value="}"/>
</filterreader>
</filterchain>
</copy>

Related

How to run shell script in Ant while doing search and replace?

I am trying to achieve following with Ant.
I have a property file where we have list of tokens and their values.
This file is passed to Ant and it works great and does all the normal string replacement.
<copy todir="${target_direcotry}" overwrite="true">
<fileset dir="config">
<include name="*.change_me"/>
</fileset>
<filterset begintoken="<" endtoken=">">
<filtersfile file="${property_file}"/>
</filterset>
<mapper type="glob" from="*.change_me" to="*"/>
</copy>
Now If i have one of the token-value pair as follows :
TOKEN_VALUE1=`./run_me.ksh` in property file.
Target file test.xml.change_me has content :
You have <TOKEN_VALUE1> entries present !!!
With above code in build.xml and this new token in property file i am getting content of test.xml after running ant is :
You have `./run_me.ksh` entries present !!!
Output of script run_me.ksh will decide the value this token and give me output as follows :
Scenario 1 :
Run_me.ksh output: 10
Required content of file test.xml after execution :
"You have 10 entries present !!!"
Scenario 1 :
Run_me.ksh output: 20
Required content of file test.xml after execution :
"You have 20 entries present !!!"
Can i achieve this with Ant function/commands to run such shell script during replacements and how ?
It is technically possible to achieve this with Ant using FilterChain and FilterReader (specifically this one: ScriptFilter). However this is not so trivial and may have some portability issues. You may consider either writing your own task (or a specific FilterReader), or simply define a target that executes your shell script and store its result in a property and the use that property as value for token replacement.
Hereafter a snippet of how to launch a script in your token replacement task :
<copy todir="${target.dir}" overwrite="true">
<fileset dir="${config.dir}">
<include name="*.change_me" />
</fileset>
<filterchain>
<!-- replace token with value in the property file (i.e. `run_me.sh`) -->
<filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
<param type="propertiesfile" value="${token.properties}" />
</filterreader>
<tokenfilter>
<!-- split result along a specific pattern ('`' character for instance). -->
<stringtokenizer delims="`" delimsaretokens="false" />
<!-- apply a script filter to execute shell if token is script name -->
<scriptfilter language="javascript">
<![CDATA[
if( self.getToken().indexOf(".sh") != -1 ){
<!-- rely on ant Exec task to run script -->
exectask = project.createTask("exec");
exectask.setExecutable("sh");
exectask.createArg().setValue(self.getToken());
<!-- store output in an ant property : -->
exectask.setOutputproperty("result");
exectask.perform();
<!-- retrieve the ant property and use it to replace current token -->
self.setToken(project.getProperty("result"));
}
]]>
</scriptfilter>
</tokenfilter>
</filterchain>
<mapper type="glob" from="*.change_me" to="*" />
</copy>

Remove first and last line from file?

I have a file that has lines like this.
(function($, _) {
.....
})(jQuery, jQuery.ZOF);
now I want to remove the first and last line of the file and then concat this file to another file , How could it be possible with ant?
loadfile can be used as follows:
<loadfile srcfile="test.xml" property="file.first.and.last.line.removed">
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.HeadFilter">
<param name="lines" value="-1"/>
<param name="skip" value="1"/>
</filterreader>
<filterreader classname="org.apache.tools.ant.filters.TailFilter">
<param name="lines" value="-1"/>
<param name="skip" value="1"/>
</filterreader>
</filterchain>
</loadfile>
<echo message="${file.first.and.last.line.removed}" file="output.txt" append="true" />
First we use a HeadFilter to read everything but skipping the first line, then we "tail" the result with a TailFilter skipping the last line.
The last line appends the content to another file.

Ant Fileset to Comma Separated List

I'm trying to pass a fileset to a macrodef, and have the macro generate a comma separated list of the classes. More over, I also need to change the list to contain java package & class names instead of "/" delimmited names.
We're using Ant, OSGi, and bnd and what I'm ultimately trying to do is create an entry in the Manifest that contains the fully qualified class name of each entry of the fileset.
End Goal example:
Manifest-Entry: org.foo.bar.ClassOne, org.foo.bar.ClassTo
You could do this using the Ant pathconvert task with a nested mapper, for example:
<property name="classes" location="classes" />
<fileset dir="${classes}" id="classes" />
<pathconvert dirsep="." refid="classes" property="manifest.entry" pathsep=", ">
<mapper type="regexp" from="${classes}/(.*).class" to="\1" />
</pathconvert>
<echo message="Manifest-Entry: ${manifest.entry}" />
Since you are using bnd, you could also try using the ${classes} macro in the bnd file.

How do I remove non-tokens during copy in Ant?

I have files that I need cleaned up during the build process. There is a fixed string that I need removed everywhere it appears. The files are being copied so during that copy I tried including a filterset where the token is the text to be removed and the value is the empty string. This didn't work because I set begintoken and endtoken to the empty string and Ant didn't like that.
This is not a one time operation so it needs to be part of the build process. The files contain SQL INSERT statements and are used to populate tables at runtime. Each line references the schema plus the table name and I need just the table name, e.g.
insert into Schema1.Table1 ...
should be
insert into Table1 ...
Thank you!
Use a nested filterchain with tokenfilter, something like =
<copy todir="...">
<fileset dir="..." />
<filterchain>
<tokenfilter>
<replacestring from="Schema1." to="" />
</tokenfilter>
</filterchain>
</copy>
if you need regexp for replacement use =
...
<tokenfilter>
<replaceregex pattern="..." replace="..." flags="".../>
</tokenfilter>
...
instead.

Ant replace token from properties file

i would like to replace tokens in source files with Ant:
some test ${foo} other text ...
Tokens are contained in a properties file eg.:
foo=1
Actually this is easy if tokens in source files were like '##foo##' or 'foo' but i'm not able to replace whole token : ${foo}
I've succeed years ago but this time i've failed ...
Thanks
This is somewhat similar to these.
Properties are loaded from the file properties.txt.
The weakness here is that all occurrences of ${ in your input text are converted to { before the token substitution - which may well break things if that string appears elsewhere in the text. If that is a problem, it still aught to be possible to adapt this solution.
<copy file="input.txt" tofile="output.txt">
<filterchain>
<replaceregex pattern="\$\{" replace="{" />
<filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
<param type="propertiesfile" value="properties.txt"/>
<param type="tokenchar" name="begintoken" value="{"/>
<param type="tokenchar" name="endtoken" value="}"/>
</filterreader>
</filterchain>
</copy>

Resources