Wednesday, October 28, 2009

Setting Version in your manifest using ANT

While the Gant folks will tell you that is not natural to use XML for your makefile as it is nicer to use a real scripting language (and perhaps today’s post will enforce this for you!), it is doable and in my opinion readable. The below is an excerpt of our ant buildfile that we use for upping the manifest version in an interactive way with the the person doing the build.

We added the ant-contrib task in order to enable us to have “if” statements in the XML, so we define the task as follows:

   1: <taskdef resource="net/sf/antcontrib/antlib.xml">

   2:    <classpath>

   3:       <pathelement location="${3rdParty.home}/ant-contrib/ant-contrib-1.0b3.jar" />

   4:    </classpath>

   5: </taskdef>


This will be used below to drive the logic if the user wants to keep the same version of the manifest or change it.

There are two macros that we have defined, loadmanifest – which reads and parses the manifest and createmanifest – which invokes loadmanifest and then interactively decides whether to write a new manifest or not.

Here is loadmanifest:


   1: <macrodef name="loadManifest">

   2:   <attribute name="manifest" />

   3:   <sequential>

   4:     <echo message="about to load file: @{manifest}"/>

   5:         <loadfile property="@{manifest}.build.version" srcFile="@{manifest}">

   6:             <filterchain>

   7:   <filterreader classname="org.apache.tools.ant.filters.LineContains">

   8:                         <param type="contains" value="Implementation-Version:" />

   9:                 </filterreader>

  10:                 <tokenfilter>

  11:   <replacestring from="Implementation-Version: " to="" />

  12:                 </tokenfilter>

  13:                 <striplinebreaks />

  14:           </filterchain>

  15:           </loadfile>

  16:         </sequential>

  17:     </macrodef>


On line 5 we use the loadfile task to read the version number into a property that we will display to the user. We then use the very powerful filterchain to get to the correct line and the correct section of the line with the version number. For lack of a better way, we strip away the text part of the line (Implementation-Version:) on line 11, and are left with just the version number to be stored in the loadfile property @{manifest}.build.version.

Using this property we can now query the user to determine if the version number suits him or not, and then if necessary put out a new manifest file. This is the macro below:



   1: <macrodef name="createManifest">

   2:         <attribute name="manifest" />

   3:         <attribute name="jarDescription" />

   4:         <sequential>

   5:             <loadManifest manifest="@{manifest}" />

   6:             <echo message="Current Version: ${@{manifest}.build.version}" />

   7:             <input message="Enter new version?" validargs="y,n" addproperty="@{jarDescription}.do.newversion" />

   8:             <if>

   9:                 <equals arg1="${@{jarDescription}.do.newversion}" arg2="y" />

  10:                 <then>

  11:                     <input message="Please enter new version number" addproperty="@{jarDescription}.new.build.version" />

  12:                     <manifest file="@{manifest}">

  13:                         <section name="${@{jarDescription}.jar.description}">

  14:                             <attribute name="Implementation-Title" value="${@{jarDescription}.jar.description}" />

  15:                             <attribute name="Implementation-Version" value="${@{jarDescription}.new.build.version}" />

  16:                         </section>

  17:                     </manifest>

  18:                 </then>

  19:                 <else>

  20:                     <property name="@{jarDescription}.new.build.version" value="${@{manifest}.build.version}" />

  21:                 </else>

  22:             </if>

  23:         </sequential>

  24:     </macrodef>


Other than “if”, the rest are all standard ant tasks that you can look up in the manual on the ant site.

The correct thing to do at this point would be to create a parallel GANT site. Unfortunately, i dont have one ready at the moment so this will have to wait until i begin to play with GANT

No comments:

Post a Comment