Gradle Build from an Ant Script

Currently I am working on a redesign of a pretty complex project based on Ant builds. The task is to move the whole concept into Gradle.


I will continuously update this article how my work will be moving forward and put interesting issues and my solutions for them.

If you have a better solution, please comment and discuss!

Does a file exist?

In the Ant script I have found such a construct to check if a file exists:

<pathconvert property="MyFile.isPresent" setonempty="false">
    <path>
        <fileset dir="src" includes="MyFile-*.dat" />
    </path>
</pathconvert>

Obviously it checks the folder src for files with names of the filter MyFile-*.dat.

We can do the same with Gradle's FileCollection:

MyFile.isPresent = !fileTree("src").include('MyFile-*.dat').isEmpty();

This will create a file filter on the folder and check if the match is empty, then set to a variable.

Substring

In the Ant script the macro was defined as a javascript:

<scriptdef name="substring" language="javascript">

With Gradle you can easily implement it in java:

def substring(String text, String regexp, int result) {
    java.util.regex.Pattern p = java.util.regex.Pattern.compile(regexp);
    java.util.regex.Matcher m = p.matcher(text);
    if (m.find( )) {
        return m.group(result + 1);
    }
    return null;
}

and use it:

def version = substring(files.getAsPath(), "executor-(.*)\\.msi", 0)

Custom builds

Because the result from the new Gradle build must be the same as from the old Ant build without changes of the project structure, we need to customize standard java plugin builds a bit.

Source sets

Java plugin provides a pretty high-level configuration element called sourceSets. You can change the sources location by setting the sourceSets up:

sourceSets {
    main {
        java {
            srcDirs = ["mysource/mypkg"]
            exclude "test/**"
        }
    }
}

Destination of the result classes

Compilation of the java classes in the java plugin is done by the target called compileJava. If you want to change the destination of the compilation, can do it easily by rewriting the variable destinationDir:

compileJava {
    destinationDir = file("myBuildDir")    // change the default dir for classes
}

Additional clean

If you want to put some additional actions into the standard clean task, do it easily:

clean << {
    // ... do some clean up
}

Compile task

In the old Ant script I have a compile task I need to keep. To make it work correctly together with the standard java plugin, make it dependent on the classes task, which is equivalent in the context:

task compile(dependsOn: classes) {        // depends on the standard java task "classes"
}

Another build

If you want to have a build of different sources in the same Gradle file (of course in a different task), you can do it like this:

sourceSets {
  main {
    ...
  }
  compileApp2 {
    java {
      srcDirs = ["anothersource/mypkg2"]
      include "app/**"
    }
  }
}
...
task compileApp2(type: JavaCompile, dependsOn: prepareApp2) {
    source = sourceSets.compileApp2.allSource.srcDirs
    destinationDir = file('app2BuildDir')   
    classpath = configurations.compile 
}