Tuesday, March 30, 2010

Gradle

For one new project I have had to choose new build tool. I know Maven and Ant for long time already and heard about Gradle here and there. So I have decided first to check these tools, and only look for something else if they will not be good for me.

My project is quite small and I was not going to configure it a lot, so some all-in-one tool would be great, however some customization would be still nice.

So Ant is good that it is extremely popular and robust and can be extended and customized quite easily. Big minus for me is that it does not have build in dependency manager, so I have to download and additionally configure Ivy. Also, I have to configure absolutely everything, there is no defaults like in Maven.

Maven is good, because it has these defaults, like compile, test and build. It has also dependency manager, which is great. Unfortunately, it is not easily customizable, and I need customization. For example, for Java Web Start project I need to sign all dependency jars (in Maven there is only plugin to sign build jar), I also need to upload automaticaly my jars and other files to Google Code.

So here comes Gradle. In short it combines good things from both Maven and Ant: includes dependency management (via Ivy, but with native Gradle integration) and has predefined tasks like Maven; all extension in one same build file like with Ant and natively can call Ant tasks - so you don't have to throw them away or rewrite everything.

Plus, there is also one (and not so little) bonus: no XML, all configuration is in Groovy, which is both: sexier and easier. There is only one minus I can see so far - it is quite large, about 20M, probably because it packages Groovy inside it, but anyway it is not show stopper for me.

Few examples:

Dependency definitions:

dependencies {
    compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '7.0.1.v20091125'
    compile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '7.0.1.v20091125'
    compile group: 'org.eclipse.jetty', name: 'jetty-util', version: '7.0.1.v20091125'
    compile group: 'org.eclipse.jetty', name: 'jetty-http', version: '7.0.1.v20091125'
    compile group: 'javax.servlet', name: 'servlet-api', version: '2.5'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

Dependencies are downloaded from Maven repository by default.

This is simple task that cleans and creates folder for libs and signs all runtime dependencies:


task copyAndSign() << {
    ant.delete(dir:'build/signed')
    ant.mkdir(dir:'build/signed')
    for(file in configurations.runtime.resolve()) {
      ant.signjar(destDir: 'build/signed', jar: file, alias:"myself", keystore:"myKeystore", storepass:"123456", preservelastmodified:"true")
    }
}

It uses Ant tasks to do actual job.

This task signs jar file after running JAR task, of course it will be run also after any task that depends on JAR task.


jar.doLast {
  ant.signjar(destDir: 'build/signed', jar: tasks.jar.archivePath, alias:"myself", keystore:"myKeystore", :"123456", preservelastmodified:"true")
}


You can also define custom Ant task from Gradle.

ant {
  taskdef( name: 'gcupload', classname: 'net.bluecow.googlecode.ant.GoogleCodeUploadTask', classpath: 'ant/ant-googlecode-0.0.2.jar' )
}
task uploadAll << {
  collection = files { file('build/signed/').listFiles() }
  collection.each { 
    ant.gcupload(username:gcusername, password:gcpassword, projectname:"project", 
        filename:it, targetfilename:it.name, summary:"automatic", labels:"")
  }
}

No comments:

Post a Comment