Gradle

From Evgeny Goldin

Jump to: navigation, search

Contents

Resources


Command-line

gradle :                          // root project
gradle :clean                     // the clean task of the root project
gradle :api                       // the api project
gradle :services:webservice       // the webservice project
gradle :services:webservice:clean // the clean task of webservice
gradle :shared:build
gradle :api:classes
 
gradle tasks -i
gradle test  -i
 
gradle properties
gradle tasks
gradle tasks --all
gradle dependencies // mvn dependency:tree
 
gradle build
gradle buildDependents
gradle buildNeeded


-?, -h, --help          Shows this help message.
-a, --no-rebuild        Do not rebuild project dependencies.
-b, --build-file        Specifies the build file.
-C, --cache             Specifies how compiled build scripts should be cached. Possible values are: 'rebuild' and 'on'. Default value is 'on' [deprecated - Use '--rerun-tasks' or '--recompile-scripts' instead]
-c, --settings-file     Specifies the settings file.
--continue              Continues task execution after a task failure.
-D, --system-prop       Set system property of the JVM (e.g. -Dmyprop=myvalue).
-d, --debug             Log in debug mode (includes normal stacktrace).
--daemon                Uses the Gradle daemon to run the build. Starts the daemon if not running.
--foreground            Starts the Gradle daemon in the foreground. [incubating]
-g, --gradle-user-home  Specifies the gradle user home directory.
--gui                   Launches the Gradle GUI.
-I, --init-script       Specifies an initialization script.
-i, --info              Set log level to info.
-m, --dry-run           Runs the builds with all task actions disabled.
--no-color              Do not use color in the console output.
--no-daemon             Do not use the Gradle daemon to run the build.
--no-opt                Ignore any task optimization. [deprecated - Use '--rerun-tasks' instead]
--offline               The build should operate without accessing network resources.
-P, --project-prop      Set project property for the build script (e.g. -Pmyprop=myvalue).
-p, --project-dir       Specifies the start directory for Gradle. Defaults to current directory.
--parallel              Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use. [incubating]
--parallel-threads      Build projects in parallel, using the specified number of executor threads. [incubating]
--profile               Profiles build execution time and generates a report in the <build_dir>/reports/profile directory.
--project-cache-dir     Specifies the project-specific cache directory. Defaults to .gradle in the root project directory.
-q, --quiet             Log errors only.
--recompile-scripts     Force build script recompiling.
--refresh               Refresh the state of resources of the type(s) specified. Currently only 'dependencies' is supported. [deprecated - Use '--refresh-dependencies' instead.]
--refresh-dependencies  Refresh the state of dependencies.
--rerun-tasks           Ignore previously cached task results.
-S, --full-stacktrace   Print out the full (very verbose) stacktrace for all exceptions.
-s, --stacktrace        Print out the stacktrace for all exceptions.
--stop                  Stops the Gradle daemon if it is running.
-u, --no-search-upward  Don't search in parent folders for a settings.gradle file.
-v, --version           Print version info.
-x, --exclude-task      Specify a task to be excluded from execution.


"apply"

apply from: 'otherScript.gradle'
apply from: 'file:../emma.gradle'
 
apply from: 'http://mycomp.com/otherScript.gradle'
apply from: 'http://github.com/breskeby/gradleplugins/raw/master/emmaPlugin/emma.gradle'
apply from: 'https://raw.github.com/evgeny-goldin/gradle-plugins/master/src/main/groovy/CodeNarc.gradle'
 
apply plugin: org.gradle.api.plugins.JavaPlugin
apply plugin: 'java'


Configurations and Dependencies


configurations {
    myConf.extendsFrom compile
    compile.exclude module: 'commons'
    all*.exclude group: 'org.gradle.test.excludes', module: 'reports'
}
 
dependencies {
    // Groovy Plugin: http://gradle.org/groovy_plugin.html
    groovy 'org.codehaus.groovy:groovy-all:1.9.0-beta-2'
 
    // Scala Plugin: http://gradle.org/scala_plugin.html
    scalaTools 'org.scala-lang:scala-compiler:2.9.1.RC4',
               'org.scala-lang:scala-library:2.9.1.RC4'
    compile    'org.scala-lang:scala-library:2.9.1.RC4'
 
    // Gradle plugins
    groovy  localGroovy()
    compile gradleApi(),
            fileTree( dir: "${gradle.gradleHomeDir}/lib/plugins", include: 'gradle-*.jar' )
 
    // Dependency configurations added by Java Plugin
    // http://gradle.org/java_plugin.html#sec:java_plugin_and_dependency_management
    compile     ' ... '
    runtime     ' ... '
    testCompile ' ... '
    testRuntime ' ... '
    archives    ' ... '
    default     ' ... '
 
    // Source-level dependency
    compile project( ':moduleA' )
    compile project( ':moduleB' )
 
    // Third-party dependency
    compile 'org.gcontracts:gcontracts-core:1.2.4'
 
    // Artifact only notation
    // http://gradle.org/current/docs/userguide/dependency_management.html#ssub:artifact_dependencies
    runtime "org.groovy:groovy:1.5.6@jar"
 
    // Local files dependency
    compile files('file.jar'),
            fileTree( dir: 'lib', includes: ['*.jar'])
 
    // Excluding transitive dependencies
    compile( 'org.gradle.test.excludes:api:1.0' ) {
        exclude group : 'groupId'
        exclude module: 'artifactId'
        exclude group : 'org.codehaus.groovy', module: 'artifactId'
    }
 
    myConf  'gId:aId:v'
    compile 'gId:aId:v' {
        force      = true  // Sets whether or not the version of this dependency should be enforced in the case of version conflicts
        transitive = false // Sets the transitivity of this configuration
    }
}
 
configurations.myConf.transitive = false
 
task printDeps( dependsOn: build ) << {
    configurations*.dependencies.each { println it }
}
 
 
configurations { provided }
sourceSets     {
    main { compileClasspath += configurations.provided }
}
 
 
// http://gradle.1045684.n5.nabble.com/Test-dependencies-not-keeped-at-test-runtime-td4773771.html
task listTestRuntime(dependsOn: configurations.testRuntime) << {
    configurations.testRuntime.files.each { file -> println file.name }
}


Repositories

repositories {
 
    mavenLocal()
    mavenCentral()
 
    maven {
        credentials { username '..'; password '..' }
        url 'http://evgenyg.artifactoryonline.com/evgenyg/repo/'
    }
 
    ivy {
        credentials { username '..'; password '..' }
        artifactPattern 'http://repo/[organisation]/[module]/[revision]/[module]-[revision].[ext]'
        artifactPattern 'http://repo/[module]-[revision].[ext]'
    }
 
    flatDir( dirs: [ 'dir1', 'dir2' ] )
 
    ivy {
        name = 'ivyRepo'
        artifactPattern "http://repo.gradleware.org/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
    }
 
    add(new FileSystemResolver()) {
        name = "repo"
        addArtifactPattern("$rootDir/repo/[organization]/[module]-[revision].[ext]")
        addIvyPattern("$rootDir/repo/[organization]/ivy-[module]-[revision].xml")
        checkmodified = true
    }
}
 
uploadArchives {
    repositories {
        mavenDeployer {
            repository( url: deploymentRepoUrl ) { authentication( .. ) }
        }
    }
}
 
 
// http://en.appsatori.eu/2011/08/using-gradle-with-cloudbees-maven.html
uploadArchives {
   repositories {
      deployer = mavenDeployer {
        // you might use this configuration not to generate
        // date based artefact names
        // uniqueVersion = false
        configureAuth = {
           authentication(userName: cloudbeesUsername, password: cloudbeesPassword)
        }
        configuration = configurations.deployerJars
        snapshotRepository(url: "dav:https://repository-${cloudbeesAccountName}.forge.cloudbees.com/snapshot/", configureAuth)
        repository(url: "dav:https://repository-${cloudbeesAccountName}.forge.cloudbees.com/release/", configureAuth)
      }
   }
}


Tasks


taskName {
    .. configure it ..
}
 
clean {
    delete 'fooDir', 'bar.txt', fileTree( 'texts' ).matching { ... }
}
 
task copySomething << {
    copy {
        from configurations.runtime
        into 'build/deploy/lib'
    }
 
    copy {
        into 'build/webroot'
        exclude '**/.svn/**'
        from('src/main/webapp') {
            include '**/*.jsp'
            filter(ReplaceTokens, tokens:[copyright:'2009', version:'2.3.1'])
        }
        from('src/main/js') {
            include '**/*.js'
        }
    }
}


Task Dependencies

task loadTestData {
    dependsOn createSchema
    dependsOn compileTestClasses, createSchema
    dependsOn << createSchema
    dependsOn << compileTestClasses
    dependsOn 'createSchema'
}
 
task hello ( dependsOn: taskA ) { .. }
task hello ( dependsOn: [ taskA, taskB ] ) { .. }
task buildAllJars( dependsOn: allJars )
 
hello { dependsOn taskA }
 
hello.dependsOn taskA
hello.dependsOn taskA, taskB
 
task emailMe( dependsOn: compileJava ) << {
    if( tasks.compileJava.didWork ) {
        println 'SEND EMAIL ANNOUNCING SUCCESS'
    }
}


Configuring Tasks

task hello    { ... }  // Configuring task
task hello << { ... }  // Adding doLast()  action to the task
hello.doFirst { ... }  // Adding doFirst() action to the task
 
task "$taskName" {} // Dynamically named task
 
task helloWorld( description: 'Says hello to the world' ) << {
    ...
}
 
task hello {
    description = 'Says hello to the world'
    onlyIf   { 3 < 4 }
    dependsOn otherTask
    doFirst { .. }
    doLast  { copy { from '..'; into '..' }}
 
    doLast {
        logging.level = level // 'DEBUG', 'INFO', 'LIFECYCLE', 'QUIET', 'WARN', 'ERROR'
        logger.debug     '...'
        logger.info      '...'
        logger.lifecycle '...'
        logger.quiet     '...'
        logger.warn      '...'
        logger.error     '...'
}
 
hello { .. config .. }
hello.dependsOn otherTask
hello.onlyIf { 3 > 2 }
hello.doFisrt { .. }
hello.enabled = true/false
 
project.tasks.add.( 'someTask' ).doFirst { .. }
 
 
/**
 * Dynamic Property
 */
task myDocs {
    destDir = "$buildDir/myDocs"
    doFirst {
        copy {
            from 'someDir'
            into destDir
        }
    }
}
 
/**
 * Dynamic Method
 */
task bar {
    serviceUrl  = ...
    domainGroup = {
        getGroup(serviceUrl)
    }
}
 
task foo {
    fooProp = bar.domainGroup()
}


Conventions


task show << {
    // Access the convention property as a project property
    println relativePath(sourceSets.main.classesDir)
    println relativePath(project.sourceSets.main.classesDir)
 
    // Access the convention property via the convention object
    println relativePath(project.convention.sourceSets.main.classesDir)
    println relativePath(project.convention.plugins.java.sourceSets.main.classesDir)
}


Custom Tasks

  • Four options for where to put custom Gradle build code:
    • The build script itself, in a task action block.
    • "buildSrc" directory.
    • Separate build script file imported into the main build script.
    • Custom plug-in written in Java or Groovy.


class FtpTask extends DefaultTask {
    String host = 'docs.mycompany.com'
    String user
    String password
 
    @TaskAction
    def ftp() { println host }
}
 
 
task something( type: FtpTask, dependsOn: ... ) {
    user     = '...'
    password = '...'
}


Typed Tasks

/**
 * Copy
 */
task copyFiles( type: Copy ) {
    from    'resources'
    into    'target'
    include '**/*.xml', '**/*.txt', '**/*.properties'
}
 
/**
 * Jar
 */
task customJar( type: Jar ) {
    manifest {
        attributes firstKey: 'firstValue', secondKey: 'secondValue'
    }
    archiveName    = 'hello.jar'
    destinationDir = file( "${buildDir}/jars" )
    from sourceSets.main.classes
}
 
/**
 * Zip
 */
task zip( type: Zip ) {
    from myDocsDestDir
}
 
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'
    }
}
 
/**
 * JavaExec
 */
task encode( type: JavaExec, dependsOn: classes ) {
    main = 'org.gradle.example.commandline.MetaphoneEncoder'
    args = "The rain in Spain falls mainly in the plain".split().toList()
    classpath sourceSets.main.classesDir
    classpath configurations.runtime
}
 
[ 'shakespeare', 'williams', 'shelley', 'chesterton' ].each { poet ->
    task "$poet"( type: JavaExec ) {
        group = 'Encoded Poetry'
        args  = [ poet ]
        main  = 'org.gradle.example.codedpoet.CommandLine'
        classpath sourceSets.main.runtimeClasspath,
                  project(':codec').sourceSets.main.runtimeClasspath
    }
}
 
/**
 * Wrapper
 */
task wrapper( type: Wrapper ) {
    gradleVersion = '1.0-milestone-3'
    jarPath       = 'gradle'
}


Selecting Tasks

allJars  = tasks.withType( Jar )
webTasks = tasks.matching { task -> task.name.startsWith( 'web' ) }
compJars = tasks.withType( Jar ).matching { task -> task.name.startsWith( 'comp' ) }
 
tasks.allObjects{ task -> task.doFirst { .. }}
tasks.whenAdded { task -> ... }
tasks.withType( Jar ).allObjects { jar -> jar.destinationDir = 'somePath'
                                          jar.doLast { ... }}
 
task myJar( type: Jar ) // Contained in all Jars
task buildAllJars( dependsOn: allJars )
 
gradle.taskGraph.whenReady { taskGraph ->
   version = versionBase + ( taskGraph.hasTask( ':release' ) ? '' : '-SNAPSHOT' )
}


Compile Task


// Input
sourceSets.main(test).java
configurations.compile(testCompile)
 
sourceSets.main.java.srcDir  = 'src'
sourceSets.main.java.srcDirs = ['src/main/java', 'srcAdditional/main/java'
sourceSets.main.java.srcDirs 'srcAdditionalTwo/main/java'
 
compileJava {
    // http://gradle.org/current/docs/groovydoc/org/gradle/api/tasks/compile/CompileOptions.html
    // https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/groovy/org/gradle/api/tasks/compile/ForkOptions.groovy
    options.fork { memoryMaximumSize = '512M' }
}


Test Task


gradle -Dtest.single=ThisUniquelyNamedTest test
gradle -Dtest.single=*IntegrationTest test
gradle -Dtest.debug
 
sourceSets.test.java.srcDirs = [ 'src/test/java', 'srcAdditional/test/java' ]
sourceSets.test.java.srcDirs 'srcAdditionalTwo/test/java'
 
// Input
sourceSets.test.classes
configurations.testRuntime
 
test.useJUnit()
test.useTestNG()
 
test {
    useJUnit()
    useTestNG()
    jvmArgs ['-Xmx512M']
    include '**/tests/special/**/*Test.class'
    exclude '**/Old*Test.class'
    forkEvery        = 30
    maxParallelForks = Runtime.runtime.availableProcessors()
}
 
test {
    beforeTest { descr         -> .. }
    afterTest  { descr, result -> .. }
    beforeSuite{ descr         -> .. }
    afterSuite { descr, result -> .. }
}


Multi-project Builds


"settings.gradle":

include 'moduleA', 'moduleB'


Root "build.gradle":


// Declares that this project has an evaulation dependency on the project with the given path
evaluationDependsOn( ':moduleA' )
 
// Declares that this project have an execution dependency on each of its child projects
dependsOnChildren()
 
apply plugin: 'java'
 
dependencies {
    compile project( ':moduleA' )
    compile project( ':moduleB' )
}


allprojects {
    apply plugin: 'java'
}
 
project( ':moduleA' ) {
    repositories { mavenCentral() }
    dependencies {
        compile 'commons-codec:commons-codec:1.5'
    }
}
 
subprojects {
    ...
}
 
dependencies {
    compile project( ':moduleA' )
    compile project( ':moduleB' )
}
 
...


Cookbook


Publishing the JAR file

uploadArchives {
    repositories.mavenDeployer {
        repository(url: releaseUrl) { ... }
        snapshotRepository(url: snapshotUrl) { ... }
    }
}
 
uploadArchives {
    repositories {
       flatDir( dirs: file('repos'))
    }
}


Deploying source jar with Gradle

configurations { extra }
 
task sourcesJar(type: Jar) {
    classifier = 'sources'
    from sourceSets.main.java
}
 
artifacts { extra sourceJar }
 
 
// Or
 
 
task sourcesJar( type: Jar, dependsOn: classes ) {
    classifier = 'sources'
    from sourceSets.main.allSource
}
artifacts { archives sourcesJar }
 
 
// Or
// http://en.appsatori.eu/2011/08/using-gradle-with-cloudbees-maven.html
 
task packageJavadoc( type: Jar, dependsOn: 'javadoc' ) {
   from javadoc.destinationDir
   classifier = 'javadoc'
}
 
task packageSources( type: Jar ) {
   from sourceSets.main.allSource
   classifier = 'sources'
}
 
artifacts {
   archives( packageJavadoc ) {
      type      = 'javadoc'
      extension = 'jar'
   }
   archives( packageSources )
}


Setting the repository URL at the time the DAG is ready

uploadArchives {
  repositories {
      mavenDeployer {
          repository(url: deploymentRepoUrl) {
              authentication(...)
          }
     }
  }
}
 
gradle.taskGraph.whenReady { taskGraph ->
   if ( ! taskGraph.hasTask( ':release' ))
   {
       version += '-SNAPSHOT'
       uploadArchives.repositories['mavenDeployer'].repository.url = 'http://myrepo.org'
   }
}


Using Ant

ant.delete dir: 'someDir'
ant {
    ftp( server: 'ftp.comp.org', userid: 'me', ... ) {
        fileset( dir: 'htdocs/manual' ) {
            include name: '**/*.html'
        }
        myFileTree.addToAntBuilder( ant, 'fileset' )
    }
    mkdir dir: 'someDir'
}
Personal tools