How to replace a file with its first part? - ant

Given the file prep.js with contents:
head
middle
tail
And the build.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project name="abc" default="build">
<target name="build">
<replaceregexp file="./prep.js"
match="(.*)(middle)(.*)"
replace="\1"/>
</target>
</project>
Running "ant" leaves the file prep.js with:
head
tail
But I expect:
head
How do I get what I expect?

The documentation mentions a flag that treats the file content as a single line. You also may not need to match the middle word as the pattern should only keep the first line, so you can try:
<replaceregexp file="./prep.js"
match="([^\r\n]*)(.*)"
replace="\1" flags="s" />
[^\r\n] matches all characters except newline characters.

Related

Where should the fileset property be placed within the ant build file?

Here is an example of my beginning build file, I do not know where to put the fileset property. Right now I have a build.properties file that defines src as my directory with the current src. Ex(src= C:\workspace\project\src)
My fileset is defined like so
<?xml version="1.0" encoding="UTF-8"?>
<project name="Hello World Project" default="info">
<fileset dir="${src}"
<include name="**/*.java"/>
</fileset>
<target name="info">
<echo>packaging the .java files...</echo>
</target>
</project>
I don't really understand where the .java files are supposed to be put. this is only for my understanding and a demo. can I include them in a random folder?? Is the fileset located in the proper placement or should it be inside the target task?
Thanks
When running your build file the following error is thrown.
$ ant -p
Buildfile: build.xml
build.xml:6: Element type "fileset" must be followed by either attribute specifications, ">" or "/>".
This not related to the placement of the fileset tag, but rather a message telling you your xml is not well formed.
Fix the XML as follows:
<fileset dir="${src}">
<include name="**/*.java"/>
</fileset>
Note the missing ">" character.

ANT : 'ZIP' Task - how to prevent trailing slashes on ZIP entries?

I am using ANT to both unzip and then re-zip a "Open Packaging Convention" file.
It happens to be an EXCEL (*.xlsx) file: and the process works; but it seems that the ANT 'zip' task is creating the ZIP slightly differently that how it was created by EXCEL itself.
The ZIP entries created appear to have trailing slash characters.
I discovered this when opening the resultant ZIP with Apache POI (which has some unit-tests to detect and complain about this situation) with DEBUG logging on.
Here's an example of the WARNING log messages from Apache POI when re-opening up the re-zipped file:
2015-10-29 14:06:11 WARN ZipPackage:135 - Entry xl/worksheets/_rels/ is not valid, so this part won't be add to the package.
org.apache.poi.openxml4j.exceptions.InvalidFormatException: A part name shall not have a forward slash as the last character [M1.5]: /xl/worksheets/_rels/
Is there a way of avoiding this (annoying, but not critical) issue when using Ant ?
I'm running this on a Windows platform.
Here's my (simplified) 'build.xml' file.
<project name="repackage" default="repackage" basedir=".">
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="temp" location="temp"/>
<property name="extract" location="${temp}\extract"/>
<property name="inputfile" value="original.xlsx"/>
<target name="cleantemp">
<delete includeemptydirs="true">
<fileset dir="${temp}" includes="**/*"/>
</delete>
<mkdir dir="${extract}"/>
</target>
<target name="extract" depends="cleantemp">
<unzip src="${src}/${inputfile}" dest="${extract}"/>
</target>
<target name="reassemble" depends="extract">
<zip destfile="${build}/repair.xlsx" basedir="${extract}"/>
</target>
<target name="repackage" depends="reassemble">
</target>
</project>
It looks as if the parser you use didn't like directory entries (which end in a /). Use filesonly="true" in your <zip> task.

Why can't I use inherited references outside a target on ant (1.8.1)?

All I want to do is set a reference to a path on a parent build.xml and use it on a child build.xml (called with <ant>). Here's the simplest example I could create:
build-parent.xml
<?xml version="1.0"?>
<project name="parent" default="do-parent">
<target name="do-parent">
<path id="inherited.path"/>
<ant antfile="build-child.xml" inheritrefs="false" inheritall="false">
<reference refid="inherited.path"/>
</ant>
</target>
</project>
build-child.xml
<?xml version="1.0"?>
<project name="child" default="do-child">
<pathconvert property="converted.path" refid="inherited.path"/>
<target name="do-child"/>
</project>
I run ant.bat -f build-parent.xml
and get: Reference inherited.path not found.
If I change build-child.xml to be:
<?xml version="1.0"?>
<project name="child" default="do-child">
<target name="do-child">
<pathconvert property="converted.path" refid="inherited.path"/>
</target>
</project>
It works fine...
Obviously I could work around this in several ways, but I wanted to do this the proper way. What am I doing wrong?
This behavior has been encountered before:
Passing References from Master Build File to Child
I couldn't find anything that suggests whether this behavior is by design.

trouble using replaceregexp when replacing string DIR location

I am having trouble in doing this.
there is 1 batch file with this line:
set TEST_DIR=C:\temp\dir1
I just want to set some new value to TEST_DIR
But, when I use in my ant script, it escapes forward slashes and gives this result:
set TEST_DIR=C:homedir2
Instead, I want to give it:
set TEST_DIR=C:\home\dir2
I am using this command:
<replaceregexp file="${MT_BATCH_FILE_LOCATION}\myfile.bat" match="TEST_DIR=C:\\temp\\dir1" replace="TEST_DIR=C:\home\dir2" byline="true" />
You can get the result you want by using this replace pattern:
replace="TEST_DIR=C:\\\\home\\\\dir2"
The reason is that you must escape the backslash once for the regex and once for Java - backslash is an escape character in both those contexts.
In answer to your subsequent questions in comments...
I expect the answer will be the same. You will need to double-escape the backslash in the value of ${new_loc}, i.e. use C:\\\\my_projcode not C:\my_projcode.
If new_loc is coming in as an environment variable, you could use the propertyregex task from ant-contrib to escape backslashes in the value:
<project default="test">
<!-- import ant-contrib -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="C:/lib/ant-contrib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<target name="test">
<!-- load environment variables -->
<property environment="env"/>
<!-- escape backslashes in new_loc -->
<propertyregex property="loc" input="${env.new_loc}" regexp="\\" replace="\\\\\\\\\\\\\\\\" />
<echo message="env.new_loc: ${env.new_loc}"/>
<echo message="loc: ${loc}"/>
<!-- do the replace -->
<replaceregexp file="test.bat" match="TEST_DIR=C:\\temp\\dir1" replace="TEST_DIR=${loc}\\\\home\\\\dir2" byline="true" />
</target>
Output:
c:\tmp\ant>set new_loc=c:\foo\bar
c:\tmp\ant>ant
Buildfile: c:\tmp\ant\build.xml
test:
[echo] new_loc: c:\foo\bar
[echo] env.new_loc: c:\foo\bar
[echo] loc: c:\\\\foo\\\\bar
BUILD SUCCESSFUL
Total time: 0 seconds
c:\tmp\ant>type test.bat
set TEST_DIR=c:\foo\bar\home\dir2
I have found another simple solution use replace instead of replaceregexp.
<replace file="${MT_BATCH_FILE_LOCATION}\myfile.bat"
token='TEST_DIR=C:\temp\dir1'
value='TEST_DIR=${new_loc}\home\dir2' />

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