8

Let's say there is this sample groovy code in my build.gradle:

import org.apache.tools.ant.filters.ReplaceTokens

task doSomeFiltering(type: Copy) {
    from 'some/directory'
    into 'some/target'

    filter(ReplaceTokens, tokens: [SAMPLE: '123abc456'])
}

If I had some Unicode characters in the copied and filtered files, they would be turned into the system default encoding in the output files, which creates some big problems if unicode-specific characters are used and the files are expected to stay in unicode.

So the problem is: This sample code does not respect custom encoding choices, it will always default to the system default for outputting the files after filtering. How can I set the encoding of the Reader/Writer that the filter uses?

Is it possible to work around this limitation, e.g. call Apache Ant directly?

randers
  • 5,031
  • 5
  • 37
  • 64

2 Answers2

15

Specifying the encoding for filter calls was not natively supported by Gradle prior to version 2.14. Since Gradle 2.14, you can use the filteringCharset attribute of the Copy task, like this:

import org.apache.tools.ant.filters.ReplaceTokens

task doSomeFiltering(type: Copy) {
    from 'some/directory'
    into 'some/target'

    filteringCharset = 'UTF-8'

    filter(ReplaceTokens, tokens: [SAMPLE: '123abc456'])
}
randers
  • 5,031
  • 5
  • 37
  • 64
0

It is possible to work around this limitation by calling Apache Ant directly.

task doSomeFiltering << {
    ant.copy(todir: 'some/target', encoding: 'utf8', outputencoding: 'utf8') {
        fileset(dir: 'some/directory')
        filterchain {
            replacetokens {
                token(key: 'SAMPLE', value: '123abc456')
            }
        }
}

The following is a more generic approach, you can use any filter:

task doSomeFiltering << {
    ant.copy(todir: 'some/target', encoding: 'utf8', outputencoding: 'utf8') {
        fileset(dir: 'some/directory')
        filterchain {
            filterreader(classname: 'org.apache.tools.ant.filters.ReplaceTokens') {
                param(type: 'token', name: 'SAMPLE', value: '123abc456')
            }
        }
}

Note that this filterreader call is a convenience method provided by Ant here (screenshot).


If you want to customize your gradle ant call, you can pretty much use Ant's XML syntax:

<filterchain>
    <filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
        <param type="token" name="SAMPLE" value="123abc456"/>
    </filterreader>
</filterchain>

turns into

filterchain {
    filterreader(classname: 'org.apache.tools.ant.filters.ReplaceTokens') {
        param(type: 'token', name: 'SAMPLE', value: '123abc456')
    }
}

That way you can use properties and features described in the official documentation of ant, like these:

If you just "convert" the syntax provided there into the one that's required for gradle, it's possible to have great control over any ant call.

randers
  • 5,031
  • 5
  • 37
  • 64