Search code examples
gradleantbuild.gradlegradle-plugingradle-eclipse

Gradle Copy task: Ant to gradle migration


I am new to gradle and migrating ant build.xml script to gradle. Usually copy tasks are fairly simple and straight forward but i came across this little complex copy task (might be simple as well) which has verbose enabled and fileset. Can I know how to convert this ant code to gradle task ?

<copy todir="client" verbose="true">
        <fileset dir="${build.classes}">
        <include name="com/corp/domain/**" />                   
      </fileset>
   </copy>

Gradle task i tried to write so far is

task copyDocs(type: Copy) {
  from 'dist'
  include "com/corp/domain/**"
  into 'client'
}

I need to know how fileset and verbose can come into picture to make it perfect migrated task


Solution

  • Your Gradle task is already doing almost everything right. A <fileset> in Ant is a group of files. Using dir=, you can start in one directory and include or exclude a subset of all files in this directory. This behaviour is already implemented by the Gradle Copy task, because it implements the CopySpec interface. So, for only one Ant <fileset> you can use the Copy task and its methods, like you did in your example:

    task copyDocs(type: Copy) {
        from 'path/to/dir'
        include 'com/corp/domain/**'
        into 'client'
    }
    

    If you need to use multiple <fileset> elements, you can add a child CopySpec for each of them, e.g. by using the from method followed by a closure. The configurations in this closure will only apply to the files from this directory, just like configuring a single <fileset>:

    task copyDocs(type: Copy) {
        from('dir1') {
            include 'foo/bar'
        }
        from('dir2') {
            exclude 'bar/foo'
        }
        into 'dir3'
    }
    

    ${build.classes} refers to an Ant property. Since Gradle is based on Groovy, you could define your property in various places and ways (e.g. extra properties), but please mind that build is the name of a task, which is present in nearly all Gradle build scripts, so using build.classes directly would propably look for the property in the scope of the build task:

    task copyDocs(type: Copy) {
        // if you defined the property before
        from my.build.classes
        include 'com/corp/domain/**'
        into 'client'
    }
    

    The verbose attribute only defines whether all file copy operations should be logged on the console. Gradle does not support file logging via a simple option, so we need to implement it on our own. Luckily, Gradle provides the eachFile method. We can pass a closure, which is called for each copied file and carries a FileCopyDetails object. I do not know how Ant logs the copied files, but one way could be the following:

    task copyDocs(type: Copy) {
        // ...
        eachFile { details ->
            println "Copying $details.sourcePath to $details.path ..."
        }
    }