views:

2185

answers:

5

We have an Apache ANT script to build our application, then check in the resulting JAR file into version control (VSS in this case). However, now we have a change that requires us to build 2 JAR files for this project, then check both into VSS.

The current target that checks the original JAR file into VSS discovers the name of the JAR file through some property. Is there an easy way to "generalize" this target so that I can reuse it to check in a JAR file with any name? In a normal language this would obviously call for a function parameter but, to my knowledge, there really isn't an equivalent concept in ANT.

+5  A: 

It is generally considered a bad idea to version control your binaries and I do not recommend doing so. But if you absolutely have to, you can use antcall combined with param to pass parameters and call a target.

<antcall target="reusable">
    <param name="some.variable" value="var1"/>
</antcall>

<target name="reusable">
    <!-- Do something with ${some.variable} -->
</target>

You can find more information about the antcall task here.

Chris Dail
+2  A: 

Also check out the subant task, which lets you call the same target on multiple build files:

<project name="subant" default="subant1">
    <property name="build.dir" value="subant.build"/>
    <target name="subant1">
        <subant target="">
            <property name="build.dir" value="subant1.build"/>
            <property name="not.overloaded" value="not.overloaded"/>
            <fileset dir="." includes="*/build.xml"/>
        </subant>
    </target>
</project>
jodonnell
+1  A: 

Take a look at Ant macros. They allow you to define reusable "routines" for Ant builds. You can find an example here (item 15).

Dan Dyer
+4  A: 

I would suggest to work with macros over subant/antcall because the main advantage I found with macros is that you're in complete control over the properties that are passed to the macro (especially if you want to add new properties).

You simply refactor your Ant script starting with your target:

<target name="vss.check">
    <vssadd localpath="D:\build\build.00012.zip" 
        comment="Added by automatic build"/>
</target>

creating a macro (notice the copy/paste and replacement with the @{file}):

<macrodef name="private-vssadd">
    <attribute name="file">
    <sequential>
        <vssadd localpath="@{file}" 
            comment="Added by automatic build"/>
    </sequential>
</macrodef>

and invoke the macros with your files:

<target name="vss.check">
    <private-vssadd file="D:\build\File1.zip"/>
    <private-vssadd file="D:\build\File2.zip"/>
</target>

Refactoring, "the Ant way"

Vladimir
+1  A: 

You can use Gant to script your build with groovy to do what you want or have a look at the groovy ant task.

Peter Kelley