Pass two different DirSets in Ant in a custom task - ant

How can I pass two different DirSets in Ant in a custom task.
Use case: I need two different lists of directories passed into the task.
<target name="name123">
<customTask>
<dirset id="sourceDirs" .../>
<dirset id="classesDirs" .../>
</customTask>
</target>
the custom task needs to have two different array lists with dirs

Related

Define two param in for loop in ant script

I am working on ant script and I am defining two param but script says you have already defined the param.Can yopu define how could I define two param in for loop in ant script.
<project name="tomcat_win_deploy" basedir="." default="usage">
<!--taskdef resource="net/sf/antcontrib/antcontrib.properties"/-->
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<target name="env.copy.local.props">
<for param="host" list="${deploy.host}" param="path" list="${deploy.path}">
<sequential>
<copy todir="\\#{host}\${deploy.path}\conf\"
file="Properties/${deploy.env}/local_for_test.properties"
overwrite="true"/>
</sequential>
</for>
</target>
</project>
One way might be to define a list of delimited property pairs and process that in a loop, splitting each property into its two values.
So instead of having separate host and path lists:
hosts=a,b,c
paths=/a/,/b/,/c/
you might have a single host_path list:
host_path=a /a/, b /b/, c /c/
The trick then would be how to split variables and use them in the loop (and not running into the ant "properties are immutable" feature).
This answer shows how you could use the Ant Flaka addon to achieve exactly that.

How to write Custom Nant tasks of Nant tasks

Hi I new to nant and am looking to make some kind of function/task that groups a bunch of regular nant tasks.
Basically I have 3 websites with web.config files that I need to write the connectionstring and imageDir values 2, only the file path changes
Currently I am looping through the a csv of file paths to accomplish this but would like to be able to pull the code out of the loop and make it a task/function/target or something. What is the best approach.
<foreach item="String" in="${webConfig.includedFilePaths}" delim="," property="File.Path">
<do>
<xmlpoke
file="${File.Path}"
xpath="${connectionString.XPath}"
value="${connectionString.Value}" />
<xmlpoke
file="${File.Path}"
xpath="${imageDir.XPath}"
value="${imageDir.Value}" />
</do>
</foreach>
I am hoping for something like:
<writeWebConfig file=${file.Path}"
You can create a custom nant task with a property like:
<target name="UpdateConfig">
<property name="config.filepath" value="" />
<!-- Rest of the task code here -->
</target>
And then you can call this task as many times as you want with the custom value of the property config.filepath. You can override the property value from command line using -D like:
-D:config.filepath=D:\TestWeb\web.config

How to pass nested arguments from one ant target to another

How to pass nested arguments from one ant target to another?
I need to pass a variable number of nested elements from one target to another.
I have a common file with all of my standard build tasks that's included in all of my projects.
I am adding a new custom task that takes a variable number of nested arguments
As a standard, all ant calls are made through the common file to ensure consistency of build style and logging.
Thus the new custom task and its nested child will be defined in the common script.
The project build script looks like this
<target name="projectBuild">
...
<ant target="_newFooTaskWrapper" antfile="commonFile">
<property name="_arg1" value="hello"/>
<property name="_arg2" value="world"/>
<nestedArg value="qux"/>
<nestedArg value="baaz"/>
...
<nestedArg value="AAAAA"/>
</ant>
...
</target>
The common script looks like this:
<target name ="_newFooTaskWrapper">
<echo message="Target _newFooTaskWrapper in project ${ant.project.name} from base directory ${basedir}"/>
<echo message="arg1 = ${_arg1}"/>
<echo message="arg2 = ${_arg2}"/>
<taskdef name="newFooTask" classname="org.foo.NewFooTask"/>
<typedef name="nestedArg" classname="org.foo.NewFooTask$NestedArg"/>
<newFooTask arg1="${_arg1}" arg2="${_arg2}">
<nestedArg value="qux"/>
<nestedArg value="baaz"/>
...
<nestedArg value="AAAAA"/>
</newFooTask>
Obviously, this isn't right. My question is, what's the right way to do this?
I need to pass a variable number of nested elements from one target to another.
For "varible", I assume you mean you don't know the exact number of the nested elements you want to pass to the task, so what you want is something like method(Object param...) in java, is it?
It's not a good idea to try such a way. Ant is not a scripting language but a build tool. It provides limited "scripting" possibilities.
However, you can try it in the following two ways:
1, If your nested element is just in the form of <elementName value="xx" />, you don't need anything complicated. Just pass another property containing a comma seperated list of the values, and process the list in your custom ant task. It's easy for Java to split the property into a list and process it.
2, If your nested element may be more complicated... maybe you can try reference:
Make a type fooTaskParams which can be referenced via an id:
<fooTaskParams id="_foo_task_params">
<nestedArg value="qux"/>
<nestedArg value="baaz"/>
...
<nestedArg value="AAAAA"/>
</fooTaskParams>
and pass the reference to the other build file:
<ant target="_newFooTaskWrapper" antfile="commonFile">
<property name="_arg1" value="hello"/>
<property name="_arg2" value="world"/>
<reference refid="_foo_task_params"/>
</ant>
and then make your task to be able to process the reference:
<newFooTask arg1="${_arg1}" arg2="${_arg2}" paramRefId="_foo_task_params" />
You may need to take care of reference override, or make your task able to process the ref as well as taking nested elements.
Read ant's manual about <ant> and <typedef> for more about this approach, and refer to SO Q&As like this when you encount any problem.

<zipfileset> vs. <fileset> in ant

The ant build tool provides two different tasks <fileset/> and <zipfileset/>.
According to the documentation <zipfileset/> allows us to extract files from a .zip file
if we use src attribute.
My question is if we are using dir attribute to select files then what is the difference between the two, <zipfileset/> and <fileset/>.
e.g.
<zipfileset dir="conf/Gateway>
<include name="jndi.properties" />
</zipfileset>
and
<fileset dir="conf/Gateway>
<include name="jndi.properties" />
</fileset>
One useful difference between the two tasks if you're building an archive (a ZIP or WAR or JAR for example) is that a zipfileset has a prefix attribute you can use to relocate the given files at a different folder in the archive. For example, if the following is included in a bigger set of fileset and zipfileset elements:
<zipfileset dir="conf/Gateway" prefix="properties">
<include name="jndi.properties" />
</zipfileset>
then the file conf/Gateway/jndi.properties will actually be included in the output as conf/Gateway/properties/jndi.properties. You can achieve the same end in other ways, but this is occasionally useful.
Otherwise, just use the task that seems most appropriate for the task at hand.

Filter a fileset referenced using a refid

I have a fileset (which is returned from the Maven Ant task), and it contains all the jars I need to repack. This fileset is referenced by a refid. I only want to include our own jars, so I would like to filter that. But Ant filesets don't support any further attributes or nested tags if a refid is used.
For example, if the fileset is:
org.foo.1.jar
org.foo.2.jar
log4j.jar
and I want to have a fileset which contains only
org.foo*.jar
How would I do that?
Try using a restrict resource collection, which you can use like a fileset in any task that uses resource collections to select the groups of files to operate on.
For example, for a fileset returned from your Maven task referenced via an id called dependency.fileset you can declare a restrict resource collection like so:
<restrict id="filtered.dependencies">
<fileset refid="dependency.fileset"/>
<rsel:name name="org.foo*.jar"/>
</restrict>
Note you'll have to declare the resource selector namespace as it isn't part of the built-in Ant namespace:
<project xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors">
...
</project>
From here you can reference your restrict resource collection in a similar fashion to how you would reference your fileset. For example, to create backups of your filtered set of files:
<copy todir=".">
<restrict refid="filtered.dependencies"/>
<globmapper from="*" to="*.bak"/>
</copy>
Of course you can inline your restrict resource collection if you so desire:
<copy todir=".">
<restrict>
<fileset refid="dependency.fileset"/>
<rsel:name name="org.foo*.jar"/>
</restrict>
<globmapper from="*" to="*.bak"/>
</copy>
Have a look at the Ant documentation on resource collections for further information.
I think you'll need to write an ant task for that. They're pretty easy to write though.
See http://ant.apache.org/manual/develop.html#writingowntask
In your task, you'll need to call getProject() and ask it to give you the fileset, walk through it, and create a new one.
I 'm using Ant with Ivy. With the help of Ivy it is possible to filter dependencies for retrieval, with the following code in ivy.xml:
<dependency name="Project1" rev="latest.integration" transitive="true" conf="modlibs">
<exclude name="${exclusionRegEx}" matcher="regexp" />
</dependency>
<dependency name="Project2" rev="latest.integration" transitive="false" conf="modules"/>
Maybe a quick look at the Ivy source 'll help?
If you are using a sufficiently recent version of Ant and the JDK, for example, Ant 1.7 and JDK 6, then you can use the optional script task to do what you want. (Earlier versions may also work.) The page I linked to, if you scroll down to the text "The goal is to list the filesizes" then you'll see a sample script that creates a Fileset.
This isn't for the faint of heart, and a custom ant task you write yourself will probably be more flexible. But I wanted to point out the option.

Resources