Looking for a strategy to convert from ANT with macrodefs to gradle


(Don Henry) #1

Our current ANT scripts make a number of macrodef calls. In most cases an ANT target will get its work done by making a number calls to macrodefs instead of using dependent targets.

For example, see below:

<antcontrib:if>
    <equals arg1="${tag.name}" arg2="last" casesensitive="false"/>
        <!-- If specified tag name is "last", then get version info from tip version of build notes -->
      <antcontrib:then>
         <get_properties_from_buildnotes/>
      </antcontrib:then>
        <!-- If specified tag name is something else, then use it to set version info -->
      <antcontrib:else>
         <get_properties_from_tagname/>
      </antcontrib:else>
  </antcontrib:if>
<!-- Store get properties for use later -->
<create_get_propertyfile/>

I’ve successfully imported the build.xml into a build.gradle, so now I want to replace the ANT XML code with gradle code. Since most the ANT code is in the macrodef definitions, what seems like the best first step in a conversion would be to recode these definitions as gradle. I’m trying to determine how to create a macrodef definition within a build.gradle file.

build.xml

<?xml version="1.0" encoding="utf-8"?>
  <project>
  <target name="hello">
    <property name="msg" value="Set by ant"/>
    <echo>${msg}</echo>
     <test_task/>
    <echo>${msg}</echo>
   </target>
</project>

build.gradle

ant.importBuild 'build.xml'
  ant.macrodef (name: 'test_task') {
  sequential { ant.properties['msg']='Set by gradle'}
}

Running “gradle hello” I get: :hello [ant:echo] Set by gradle [ant:echo] Set by gradle

what I was expecting: :hello [ant:echo] Set by ant [ant:echo] Set by gradle

I can even comment out the test_task call in the buld.xml and get the same results, so it looks like the macrodef is run in the build or configuration phase, instead of the execution phase. I’ve tried several techniques (e.g. putting the macrodef in a task), but have not been successful.

So I have two questions: - Is there a way to move an ANT macrodef definition into gradle? - Is there a better to do this ANT->gradle conversion that doesn’t require the move of the macrodefs into gradle?

Thanks.


(Peter Niederwieser) #2

From what I can tell, Gradle’s ‘AntBuilder’ (which builds upon Groovy’s ‘AntBuilder’) doesn’t support defining macros (only calling them).

If you want to make the most out of Gradle, you’ll have to turn the Ant build into a more idiomatic Gradle build, primarily using Gradle plugins and tasks and falling back to Ant tasks only where necessary. A proven way to achieve this is to work inside out (compile -> test -> jar/war -> etc.) and compare the results of the builds at (ideally) each step. A future Ant->Gradle migration plugin will help you with the comparisons, but for now you’ll have to implement them yourself (using Groovy/Gradle APIs.) For example, a basic check whether two Jars contain the same files can be implemented in a few lines of code.


(Don Henry) #3

Thanks. I was hoping to stay away from a monolithic rewrite, but sounds like the best I can hope for is a convenient way to compare the build results between the rewrite and the original.

I’m still committed to the switch to gradle/groovy just because the language capabilities are so much greater, but it just won’t be an iterative switch.