Does a recursive Ant task exist to recover properties from external file? - java

I ve got a problem in getting properties with ant from a properties file. With a simple target like this in my build.xml, i'd like to get at least two properties path1 and path2. I'd like to have a generic target to get this two properties.... in order to avoid modifying the build.xml (just adding a new prop)
Any suggestions? Thanks in advance !
build.xml :
<target name="TEST" description="test ant">
<property file="dependencies.properties"/>
<svn>
<export srcUrl="${path.prop}" destPath="${workspace}/rep/" />
</svn>
</target>
dependencies.properties :
path1.prop = /path/to/src1
path2.prop = /path/to/src2

Thanks, it works.
in addition you can use the propertycopy from ant-contrib to get other properties from the file.
dependencies.list=path1,path2
path1.prop1=val1
path1.prop2=val2
path2.prop1=val3
path2.prop2=val4
like this :
<target name="main">
<property file="dependencies.properties"/>
<foreach list="${dependencies.list}" delimiter="," param="name" target="doExtract" inheritall="true"/>
</target>
<target name="doExtract">
<propertycopy name="prop1" from="${name}.prop1" silent="true"/>
<propertycopy name="prop2" from="${name}.prop2" silent="true"/>
<svn>
<export srcUrl="${prop1}" destPath="${workspace}/rep/"" />
</svn>
</target>

You could write your path settings to a comma separated list in a single property and use a foreach loop

Related

apache ant: import filelist from file and use it in apply task

I'm trying to import an external filelist into my ant build-script and using it during in an apply task.
listoffiles:
<filelist id="myfiles" dir=".">
<file name="file1" />
<file name="file2" />
</filelist>
build.xml:
<target name="build">
<property file="listoffiles"/>
<apply executable="cat" parallel="false">
<srcfile/>
<filelist id="${myfiles}" />
</apply>
</target>
I'm not sure if this works. In a tutorial I read that property is for importing properties and filelist is defined as a datatype. I also tried to define the filelist inside build.xml and referencing it with the code above... also no success.
Hope someone can help me!
Thanks aronadaal
P.S: Is there a way to print the content of a filelist? Just for debugging purposes.
I gave ant-contrib a try and found the following working solution.
example content of 'includes':
path1/file1
path2/file2
path2/file3
target from build.xml:
<target name="build-xml" depends="get-xml-files">
<loadfile property="file" srcfile="includes"/>
<for param="line" list="${file}" delimiter="${line.separator}">
<sequential>
<xslt-saxon in="#{line}.xml" out="#{line}.xml" style="tranform.xsl"/>
</sequential>
</for>
</target>
pros: script-like, easy to implement
cons: additional dependency, not-ant-like
So regarding your proposal resourcelist I'll stuck how to reference the lines read in my saxon-call. With ant-contrib I do something like `#{line}'.
Sorry for all these questions... but the ant manual is not really helpful for beginners.
Do you have any book recommendations for ant?
Thanks aronadaal
You want to use refid when you use the filelist rather than id - and not use the id like a property, i.e.
<apply executable="cat" parallel="false">
<srcfile/>
<filelist refid="myfiles" />
</apply>
You can print the value of a reference with ${toString:myfiles} - see http://ant.apache.org/manual/properties.html#toString
Edited to answer resourcelist question of the follow up answer
resourcelist is a resource collection that consists of resources whose names have been read from a file. Something like https://stackoverflow.com/a/37132426/4524982 should be doable with
<xslt-saxon ...>
<resourcelist>
<file file="includes"/>
</resourcelist>
</xslt-saxon>
which works if (and only if) the xslt-saxon task supports nested resource collections.

apache ant mutable file type property

I'm looking for a way to load properties from a file in ant script. Specifically, I want to loop through a list of properties files, and on each loop load the properties from the current file and do something with it. Something like this:
<for param="file">
<path>
<fileset containing my properties files.../>
</path>
<sequential>
<property file="#{file}" prefix="fromFile"/>
<echo message="current file: #{file}"/>
<echo message="property1 from file: ${fromFile.property1}"/>
</sequential>
</for>
The code above results in only the first properties file from being read, even though each loop does go through each properties file name. I know property is immutable, and I can get around it by using local task or variable task from ant-contrib. However, I don't know how to apply them here, or if they even contribute to a solution in this case.
Here I used Antcontrib and two property files in the same directory as the build.xml.
p1.properties:
property1=from p1
p2.properties:
property1=from p2
The trick is to use antcall inside the for loop to call another target. Properties set in the called target at not propagated back to the caller.
build.xml:
<project name="test" default="read.property.files">
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="ant-contrib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<target name="read.property.files">
<for param="file">
<path>
<fileset dir="." includes="*.properties"/>
</path>
<sequential>
<antcall target="read.one.property.file">
<param name="propfile" value="#{file}"/>
</antcall>
</sequential>
</for>
</target>
<target name="read.one.property.file">
<property file="${propfile}" />
<echo message="current file: ${propfile}" />
<echo message="property1 from file: ${property1}"/>
</target>
</project>
The output is:
Buildfile: /home/vanje/anttest/build.xml
read.property.files:
read.one.property.file:
[echo] current file: /home/vanje/anttest/p1.properties
[echo] property1 from file: from p1
read.one.property.file:
[echo] current file: /home/vanje/anttest/p2.properties
[echo] property1 from file: from p2
BUILD SUCCESSFUL
Total time: 0 seconds
In my original question I had trouble loading entire properties file from within for loop (from ant-contrib). Turns out inside for loops, ant-contrib's own var task works just the same as property task from pure ant. All I have to do is replace <property file="#{file}" prefix="fromFile"/> with <var file="#{file}"/>. The properties loaded will be overwritten with the latest values and I don't even need prefix attribute to keep track of which loop I'm currently on.

pass an file into antfile when using ANT task

For example, I have two build.xml: build.xml and subbuild.xml. In the build.xml, it will use an ant task to call and run the subbuild.xml like this:
<target name="antCall1" >
<ant antfile="${basedir}/cache/subBuildTarget/subbuild.xml" />
</target>
My question is like this: I have an "test.xml" next to the build.xml. How can I modified the codes above so that I can pass the "test.xml" into the subbuild.xml and do some operations in the subbuild.xml?
Actually, I want to pass the "test.xml" as a of a task in subbuild.xml. I am just confused about how to let the subbuild.xml get accessed to the "test.xml" in the build.xml. Thanks!
Just set a property containing the name of the file in your build.xml before calling the subbuild.xml. An Ant subproject invoked using the ant task automatically inherits all properties set in their parent unless the attribute inheritAll is set to false. Alternatively you can pass the property to the subproject with a nested property element as suggested by CAustin in the comments.
First method:
<target name="antCall1" >
<!-- since the file is in the same directory as the build.xml -->
<property name="input.file" value="test.xml" />
<ant antfile="${basedir}/cache/subBuildTarget/subbuild.xml" />
</target>
Second method:
<target name="antCall1" >
<ant antfile="${basedir}/cache/subBuildTarget/subbuild.xml">
<property name="input.file" value="test.xml" />
</ant>
</target>
In subbuild.xml:
<loadfile property="file.contents" srcFile="${input.file}"/>
<echo message="${file.contents}" />

How to use Ant to auto renaming output apk file?

I'm currently playing with Ant to do some auto branding work. I modified default build.xml and setup my own target. What I hope to ask is that is there a way in Ant Script that could automatic renaming the apk file just build with the certain name?
I currently has this Ant target setup in my build.xml:
<target name="release-brandA"
depends="default, -set-release-mode, -release-obfuscation-check, -package, -post-package, -release-prompt-for-password, -release-nosign, -release-sign, -post-build"
description="Builds the application in release mode for brandA.">
<delete dir="${res}" />
<copydir dest="${res}" src="${branding}/brandA" forceoverwrite="ture" />
<replaceregexp flags="g" byline="false">
<regexp pattern="import com.arthur.android(.*).R;"/>
<substitution expression="import com.arthur.android.brandA.R;"/>
<fileset dir="src" includes="**/*.java" />
</replaceregexp>
<replaceregexp flags="g" byline="false">
<regexp pattern="package="com.arthur.android(.*)"" />
<substitution expression="package="com.arthur.android.brandA"" />
<fileset dir="" includes="AndroidManifest.xml" />
</replaceregexp>
</target>
Is there a way that I could add some more task, to let the output file just be like brandA.apk?
Thank you!
The final apk filename is actually defined by the property 'out.final.file'
So you could create a new Task that sets this property:
<target name="-set-out-final-file">
<property name="out.final.file" location="${out.absolute.dir}/brandA.apk" />
</target>
Finally, you just need to invoke the -set-out-final-file target before calling the debug or release targets.
Using your release-brandA task, it would become this:
<target name="release-brandA"
depends="default, -set-out-final-file, -set-release-mode, -release-obfuscation-check...
Here I found more better explanation and more suitable way to override release target.
Please refer to section:
<target
name="release"
depends="custom-set-release-mode, android_rules.release" />
Its very simple.Refer this link [1]: https://ant.apache.org/manual/running.html
So in the above case,we need to run it like this,
ant debug -Dout.final.file=brandA.apk
Thats it.

How to use wildcard in Ant's Available command

I'm using an Ant build script to collate my Eclipse-based application for distribution.
One step of the build is to check that the correct libraries are present in the build folders. I currently use the Ant command for this. Unfortunately, I have to amend the script each time I switch to a new Eclipse build (since the version numbers will have updated).
I don't need to check the version numbers, I just need to check that the file's there.
So, how do I check for:
org.eclipse.rcp_3.5.0.*
instead of:
org.eclipse.rcp_3.5.0.v20090519-9SA0FwxFv6x089WEf-TWh11
using Ant?
cheers,
Ian
You mean, something like (based on the pathconvert task, after this idea):
<target name="checkEclipseRcp">
<pathconvert property="foundRcp" setonempty="false" pathsep=" ">
<path>
<fileset dir="/folder/folder/eclipse"
includes="org.eclipse.rcp_3.5.0.*" />
</path>
</pathconvert>
</target>
<target name="process" depends="checkEclipseRcp" if="foundRcp">
<!-- do something -->
</target>
A slightly shorter and more straightforward approach with resourcecount condition:
<target name="checkEclipseRcp">
<condition property="foundRcp">
<resourcecount when="greater" count="0">
<fileset file="/folder/folder/eclipse/org.eclipse.rcp_3.5.0.*"/>
</resourcecount>
</condition>
</target>
<target name="process" depends="checkEclipseRcp" if="foundRcp">
<!-- do something -->
</target>
The pathconvert task is probably the preferred way to go in most cases. But it creates a little problem when the directory tree is very large and one uses the echoproperties task. With a very large directory tree, the string generated by pathconvert can be huge. Then echoproperties sprays the huge string, making the output more difficult to work with. I use a macrodef on Linux that creates a property set to "1" if there are files in the directory:
<macrodef name="chkDirContents" >
<attribute name="propertyName" />
<attribute name="dirPath" />
<attribute name="propertyFile" />
<sequential>
<exec executable="sh" dir="." failonerror="false" >
<arg value="-c" />
<arg value='fyles=`ls -1 #{dirPath} | head -1` ; if [ "$fyles" != "" ] ; then echo #{propertyName}=1 > #{propertyFile} ; fi' />
</exec>
</sequential>
</macrodef>
<target name="test" >
<tempfile destdir="." property="temp.file" deleteonexit="true" />
<chkDirContents propertyName="files.exist" dirPath="./target_dir" propertyFile="${temp.file}" />
<property file="${temp.file}" />
<echoproperties/>
</target>
Executing the "test" target will generate the following echoproperties line if there are files in the ./target_dir/ directory:
[echoproperties] files.exist=1
What "test" does:
It generates a temporary filename, ${temp.file}, that can later be used as a property file.
It then executes the macrodef, which calls the shell to check the contents of the dirPath directory. If there are any files or directories in dirPath, it assigns the propertyName property a value of 1 in the temporary file. It then reads the file and sets the property given in the file. If the file is empty, no property is defined.
Note that the temporary file could be reused for subsequent calls of the macrodef if desired. On the other hand, of course, once a property is set, it is immutable.

Categories

Resources