How to replace template in one file with content of another file? - ant

I have a file username.txt with one word in it.
I have another file with template in it:
<root>
<user name="${username}">
</root>
I need during ant build change template ${username} with content of file username.txt.
How to do it?
What ant task should I use for this purpose?

If you can make your first file be a properties file instead of containing just the one word e.g.
username=superuser
Then you can load it using the property task. e.g.
<property file="username.properties" />
Update
If the file format needs to remain as in the question then take a look at the LoadFile task. It can be used to load the contents of a file into a property. e.g.
<loadfile property="username" srcFile="username.txt" />

Related

Ant copy text between two xml tags

I am trying to copy an entire xml tag from a file and append it to another file.
I have been messing arround with filterchains
<loadproperties srcFile="${dir}/file.xml">
<filterchain>
<linecontainsregexp>
<regexp pattern="<assembly-descriptor> "/>
</linecontainsregexp>
</filterchain>
</loadproperties>
I dont know how to form the regx pattern.
the source file looks some thing like this
<assembly-descriptor>
<somelines>
<somelines>
<somelines>
</assembly-descriptor>
i need to copy the this entire tag to another file .
Treating xml with line matching/regular expression matching will eventually fail. Could you write a small program to do what you have described. Apparently there are some task for xml.
If you are okay with xslt, xslt task could help.

Changing properties file inside a jar with Ant

I have a settings in a properties file located within a jar that I wish to alter at build-time using ant. Ideally if I am able to search for a specific text in the properties file and replace it easily, I would like to do that but isn't sure how.
So I was thinking I can overwrite it with another properties file that has the new settings already predefined. The jar already exists in my directory and the hierarchy of my jar is as follows:
food.jar
/com/food/donut.properties
some file...
some file...
If I had another donut.properties file with a different setting located in a different directory. How can I overwrite it with ant?
Thanks for the help, much appreciated!
EDIT:
With the following code I was able to copy the properties file into the jar. But whenever I attempt to copy the new properties file into the same directory of the old properties file, it does not get replaced. (i.e. If i change the prefix to 'com' i can see the new properties file being inserted into the jar. If the prefix is changed to com/food, nothing is replaced. What am i doing incorrectly?
<jar destfile="${dist.dir}/food.jar" update="true">
<zipfileset file="donut.xml" prefix="com/food/" />
</jar>
needs Ant 1.8.x
Step 1)
edit your propertyfile, multiple nested entry elements possible :
<propertyfile file="/path/to/propertyfile/foo.properties">
<!-- will change an existing key named 'somekey' with the value 'foo' inplace -->
<entry key="somekey" value="foo"/>
</propertyfile>
see Ant Manual propertyfile
Step 2)
update your jar with the altered propertyfile :
<jar destfile="/path/to/your/foo.jar" update="true">
<fileset dir="/path/to/propertyfile" includes="*.properties"/>
</jar>
for renaming use nested mapper like that :
<jar destfile="/path/to/your/foo.jar" update="true">
<mappedresources>
<fileset dir="." includes="*.properties"/>
<globmapper from="*.properties" to="/com/xml/*.properties"/>
</mappedresources>
</jar
The ant documentation of the jar task says:
The update parameter controls what happens if the JAR file already
exists. When set to yes, the JAR file is updated with the files
specified. When set to no (the default) the JAR file is overwritten.
An example use of this is provided in the Zip task documentation.
Please note that ZIP files store file modification times with a
granularity of two seconds. If a file is less than two seconds newer
than the entry in the archive, Ant will not consider it newer.
You might need to make sure the properties file is newer than the one in the jar file. Using the touch task could solve the problem.
Or you might just unzip the jar in the temp directory, copy the properties file with the copy task and its overwrite attribute set to true, and re-jar the contents of the temp directory.

Store a Value in a Property with Ant or Phing

With Ant or Phing, I need to load a file's contents into a property, run a regular expression on the value of that property, and then store the result of that regular expression in another property. What's the best way to do this?
I can load the file into a property easily (with Phing) like so:
<loadfile file="myfile.txt" property="my.file" />
And I know how to update the file, but I can't seem to figure out how to run a regex on that property, and store the result in a new property for future use.
Any help would be greatly appreciated!
Update
I've been tinkering with it, and this will work. Let me know if there's a streamlined way though! The code below loads a file into a property, then reduces it to only the line that contains the title tag. And then, it runs a regular expression on that line, and stores the contents of that tag in my.prop.
<loadfile file="../index.html" property="my.prop">
<filterchain>
<linecontainsregexp>
<regexp pattern="<title>" />
</linecontainsregexp>
<replaceregexp>
<regexp pattern="[\s\S]+<title>(.+?)</title>" replace="$1" />
</replaceregexp>
</filterchain>
</loadfile>
Update 2
Actually, I ended up using an adhoc task to create my own. Worked perfectly!
You can run an arbitrary command from an ant target like this:
<exec executable="bash">
<arg line="script.sh"/>
</exec>
You can for example store the result of the regexp in a tmp file and then load it into another property the same way as the initial one.
In Phing you could process the content of the property where you loaded the file using the "php" task. See: http://www.phing.info/docs/guide/stable/chapters/appendixes/AppendixB-CoreTasks.html#PhpEvalTask

Access Antlib Resources From Within Apache Ant Macros

Is it possible to access resources from within Apache Ant macros defined in an Antlib?
For instance, within my antlib.xml, I have a macro that performs some XSLT. Ideally I would like the XSLT file to be packaged in the same JAR as the antlib.xml, but I have no idea how to specify the location of the XSLT.
Here is the (simplified) code:
<antlib xmlns:tibant="antlib:org.windyroad.tibant">
<macrodef name="configure-ear">
<attribute name="xml" />
<attribute name="out" />
<sequential>
<xslt in="#{xml}"
out="#{out}"
style="...what to put here...">
</xslt>
</sequential>
</macrodef>
</antlib>
The problem is that whatever I put in the style attribute is relative to the basedir for the project using the antlib and I can't find any way to specify a path relative to the antlib.xml.
Any ideas?
I can ship the XSLT as a separate file, but then I would need to give users some way to specify the location of the XSLT, which is not ideal (e.g. setting a tibant.home property). I could also use echoxml to write out the XSLT to a temp file, but IMO that's a hack.
Instead of using the style attribute, try a nested <style> element, which will allow you to specify a javaresource as the style sheet. You can then put the stylesheet next to your antlib.xml in the jar, and it will be available on the classpath.
<xslt in="#{xml}"
out="#{out}">
<style>
<javaresource name="your/package/structure/style.xslt" />
</style>
</xslt>
The first thing I would look at is to load XSL from the classloader as a resource. You should be able to accomplish this with LoadResource task (http://ant.apache.org/manual/Tasks/loadresource.html). The next I would look at options that XSLT task gives you for the specifying style. It doesn't look like it has any ability to take literal contents of XSLT. You can work around this by writing out the XSLT content to a temporary file and then giving the path to the temp file to the XSLT task.
So...
Load XSLT text from the classloader.
Acquire a temporary file using Tempfile task (http://ant.apache.org/manual/Tasks/tempfile.html).
Write out XSLT text to the temp file using Echo task.
Invoke XSLT with reference to the temp file.

ANT: How to call target for all build.xml in subdirectories?

How do you call a specific target in all build.xml located in all subdirectories using wildcards (ie not hard coding the subdirectory names)? The below answer is hardcoded. Is there a way to do it without hardcode?
Similar to this question: Pass ant target to multiple build.xml files in subdirectories
Use the Ant subant task like this:
<subant target="sometarget">
<fileset dir="." includes="*/build.xml" />
</subant>
If you include an "inheritall" attribute (same as how it's used in but defaults the opposite), you can share all your current project's properties and everything too. This also makes it very easy to overwrite tasks defined in your main build.xml file if you need to.
Read more about it here.
I'll setup different properties within my build.properties file. I use these to dynamically build paths in my targets.
Define the location of your build.properties file:
<!-- all properties are in build.properties -->
<property file="build.properties" />
Use those properties in your targets:
Properties in the build properties are similar to setting up an .ini file:
project.rootdir=c:/Deploy
project.tempbuilddir = c:/Deploy/Temp/Inetpub
project.builddir=c:/Deploy/Inetpub
# Build prefix will be added to that tags urls (.../tags/${project.buildprefix}Build_${today.date})
project.buildprefix=ACA_
I guess you could use a dynamic file as your properties file, if necessary, as long as you define the proper path to the file. You could point it to a server-side file to dynamically write your properties file (ColdFusion, PHP, JSP, whatever).
I've used ant-contrib's foreach task to do something like this.
http://ant-contrib.sourceforge.net/tasks/tasks/foreach.html
Sounds like a perfect candidate for the <subant> task.

Resources