Search

Dark theme | Light theme

November 24, 2014

Gradle Goodness: Using CopySpec with Tasks

To define a Copy task we specify the files we want to copy and to which directory. This definition is a CopySpec instance. It contains the rules that defines what we want to copy. The archive tasks Jar, Zip and Tar also use a CopySpec instance.

When we create a task of type Copy we get a task object that implements the CopySpec interface. We can use all the methods from this interface to extend our recipe for copying tasks. In the following build file we first define the task website. We use CopySpec methods to configure the task. Then we define a task deploy of type Sync that also implements the CopySpec interface.

// Create a new task of type Copy.
// The website task is of type Copy
// and this means it implements the
// CopySpec interface. 
task website(type: Copy) {
    into "${buildDir}/website"
    from 'src/webroot'

    into 'resources', {
        from 'src/assets'
    }
}

// We can use all CopySpec methods
// to add new specifications to 
// the existing specifications.
website.into('resources') {
    from 'src/javascript'
}

// The copySpec method creates 
// a CopySpec instance
// from the closure.
// The copySpec method is part of the
// Project object.
CopySpec manualSpec = copySpec {
    from('src/manual') {
        include '**/*.html'
    }
}
// And the with method accepts
// the CopySpec we created.
website.with(manualSpec)

// Print each file path
// that is copied.
website.eachFile { 
    println it.path
}

// New task of type Sync.
// The Sync task is also implementing
// the CopySpec interface.
// (Just like archive tasks: Zip, Tar, Jar)
task deploy(type: Sync) {
    destinationDir = file("${buildDir}/production")
    from website
}

// Use rename method from CopySpec.
deploy.rename { file ->
    if (file == 'index.html') {
        'main.html'
    } else {
        file
    }
}

// And finally the exclude method.
deploy.exclude 'man.html'

When we run the deploy task and look at the files in the build directory we see how our copy specifications are executed:

$ gradle deploy
:website
index.html
resources/app.js
resources/site.css
man.html
:deploy

BUILD SUCCESSFUL

Total time: 3.643 secs
$ tree build/
build
├── production
│   ├── main.html
│   └── resources
│       ├── app.js
│       └── site.css
└── website
    ├── index.html
    ├── man.html
    └── resources
        ├── app.js
        └── site.css

4 directories, 7 files

Written with Gradle 2.2.