Sample Gradle Tasks and Notes

www.gradleware.com
Well worth a look-see for more Gradle inspiration: http://evgeny-goldin.com/wiki/Gradle

Sample Gradle Zip Task

task zip(type: Zip) {
    from jar.outputs.files
    from('scripts/') {
      fileMode = 0755
      include '**/*.sh'
      include '**/*.bat'
    }
    from('lib/') {
        include '**/*.jar'
        into('lib')
    }
    from('.') {
        include 'project.config'
    }
}

Custom Task Types

extend DefaultTask

Actions:

@org.gradle.api.tasks.TaskAction
class FtpTask extends DefaultTask 
{
    String host = 'docs.mycompany.com'
    @TaskAction
    def ftp() {
        println host
        // do something complicated
    }
}

OR

class FtpTask extends DefaultTask {
    String host = 'docs.mycompany.com'
    String user
    String password

    @TaskAction
    def ftp() { println host }
}

task dosomething( type: FtpTask, dependsOn: ... ) {
    user     = '...'
    password = '...'
}

List Method Pointers and DSL

Groovy provides a way to have a reference to an object’s method :

What a great way to create your own DSL !

def shoppingList = []
def add = shoppingList.&add
def remove = shoppingList.&remove

add "Milk"
add "Bread"
add "Beer"
remove "Beer"
add "Apples"
print shopping

Plugins

Plugins == Build Scripts

    Two Flavors:

  • Another build script (local or remote) (Script Plugin)
  • A class implementing org.gradle.api.Plugin (Binary Plugin)
apply from: 'otherScript.gradle'
apply from: 'http://mycomp.com/otherScript.gradle'

Applying Plugins

  • Any gradle script can be a plugin.
  • Binary plugins must be in the build script classpath
  • can have id’s (meta properties in the jar).

The built-in plugins are by default in the build script classpath.

apply plugin: org.gradle.api.plugins.JavaPlugin
apply plugin: 'java'

What Plugins Can Do

  • Configure the project object (e.g. add task instances)
  • Add other classes to classpath (e.g. custom task types)
  • Add props and methods to the project object (extend DSL).
  • Build Script Decomposition
  • Separate Imperative from Declarative
  • Modularization
  • Code Reuse

Test Task Example

Tests auto-detected in sourceSets.test.classes

test {
    jvmArgs ["-Xmx512M"]
    include "**/tests/special/**/*Test.class" // Disables Auto Detection of which tests to run
    exclude "**/Old*Test.class"
    forkEvery = 30
    maxParallelForks = guessMaxForks()
}

def guessMaxForks() {
    int processors =
    Runtime.runtime.availableProcessors()
    return Math.max(2, (int) (processors / 2))
}

Ant Tasks

Gradle provides an instance of the Groovy AntBuilder

ant.delete dir: 'someDir' 
ant {     
    ftp(server: "ftp.comp.org", userid: 'me', ...) 
    { 
      fileset(dir: "htdocs/manual") 
      { 
        include name: "**/*.html" 
      } // high end

      myFileTree.addToAntBuilder(ant, 'fileset') 
    } 
    mkdir dir: 'someDir' 
} // end of ant

Picture 1

Dependencies & Java Plugin

Picture 3

apply plugin: 'java'
configurations { myConf.extendsFrom compile }
dependencies {
    compile "junit:junit:4.4"
    runtime org:'asm', name:'asm-all', version:'3.2'
    testCompile files('file1.jar')
    myConf "log4j:log4j:1.2.9"
}
  • The Java plugin adds configurations.
  • Many Java plugin tasks use those configurations as default input values (e.g. test).
  • Configurations can extend each other.

Picture 2

Repositories

Any Maven/Ivy repository can be accessed.

Very flexible layouts are possible for non Maven repositories.

repositories {
    mavenCentral()
    mavenCentral(urls: ['http://repo.com'])
    mavenRepo(urls: ['http://repo1.com',
                     'http://repo2.com'])
    flatDir(dirs: ['core', 'template-project'])
}

Global Properties

myDocsDestDir = "$buildDir/myDocs"

task myDocs << {
copy {
    from 'someDir'
    into myDocsDestDir
  }
}

task zip(type: Zip) {
    from myDocsDestDir
}

Adds a dynamic property inside task definition

task myDocs {
destDir = "$buildDir/myDocs"
doFirst {
  copy 
  {
   from 'someDir'
   into destDir
  } 
 } 
}

task zip(type: Zip) {
    from myDocs.destDir // ref.to task's destDir !!
}

Adds a Dynamic Method

task bar { 
   serviceUrl = ... 
   domainGroup = { getGroup(serviceUrl) } 
} 
task foo { 
   fooProp = bar.domainGroup() // use new method of bar task 
}

Domain Object Container

Configuration Rules

Provided by the domain object container

tasks.allObjects { task ->
    task.doFirst { println 'rule for all tasks' }
}
tasks.withType(Jar).allObjects { jar ->
    jar.destinationDir = 'somePath'
    jar.doLast { /* do something */ }
}
tasks.whenAdded { task ->; ... }

Init Scripts

Init scripts are run before the build starts. This allows us to:

  • Set up properties based on the current environment
  • Define machine specific details, such as where JDKs are installed.
  • Register build listeners.
  • Enhance builds you don’t want to touch.
  • GRADLE_USER_HOME/init.gradle is automatically applied as an init script.

You can specify any init script via the -I command line option.

>gradle assemble -I ci-init.gradle

Sample Init Script

initscript {
    repositories {
      mavenCentral()
    }
    dependencies {
      classpath 'org.apache.commons:commons-math:2.0'
    }
}
gradle.startParamter // do something with them
gradle.addBuildListener ...

Task/Project Paths

For projects and tasks there is a fully qualified path notation:

  • :root project
  • :clean (the clean task of the root project)
  • :api (the api project)
  • :services:webservice (the webservice project)
  • :services:webservice:clean (the clean task of webservice)

>gradle :api:classes

Multi-Project Builds

Picture 5

    Caelyf Multiproject Layout

  1. caelyfCore
  2. api
  3. website
  4. project-template
  5. shared
Configuration Injection
subprojects {
    apply plugin: 'java'
    dependencies {
        compile "commons-lang:commons-lang:3.1"
        testCompile "junit:junit:4.4"
    }
    test {
        jvmArgs: ['Xmx512M']
    }
}
Filtered injection
configure(nonWebProjects()) {
    jar.manifest.attributes
    Implementor: 'Gradle-Man'
}

def nonWebProjects() {
    subprojects.findAll {project ->
        !project.name.startsWith('web')
    }
}

Project Dependencies & Partial builds

dependencies {
   compile "commons-lang:commons-lang:3.1", project(':shared')
}

>gradle build
>gradle buildDependents
>gradle buildNeeded

or name matching:

>gradle build
>gradle classes
>gradle war

For projects and tasks there is a fully qualified path notation:

 :root project
 :clean (the clean task of the root project)
 :api (the api project)
 :website:webservice (the webservice project)
 :website:webservice:clean (the clean task of webservice)
 >gradle :api:classes

Separate Config/Execution Hierarchy

..

EVEN MORE

  • Smart Merging
  • Smart Exclusion
  • Skipping Tasks
  • Conditional Tasks
  • Hooks
  • Ivy
  • Custom Tasks

2 thoughts on “Sample Gradle Tasks and Notes

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s