Best way to have relative paths in incremental build

I’m creating a task to gzip all files in a FileTree in a different directory; as I want to mirror the input’s directory structure I need the relative path of input files but IncrementalTaskInputs doesn’t give me that, so I solved it visiting the input FileTree like this:

class CompressTask extends DefaultTask {
    FileTree input
    File output
    def gzip(byte[] input) {
        def os = new
        def gz = new { { def.setLevel(; } }
        gz.write input
        return os.toByteArray()
    String getRelativePath(File file) {
        String path = null
        input.visit { FileVisitDetails details ->
            if (details.file == file) {
                path = details.getRelativePath()
        if (path == null)
            throw new Exception('File not found in input FileTree: ' + file.getPath());
        return path;
    void execute(IncrementalTaskInputs inputs) {
        if (!inputs.incremental)
        inputs.outOfDate { change ->
            File file = change.file
            String path = getRelativePath(file)
            File out = new File(output, path + '.gz')
            out.bytes = gzip(file.bytes)

I don’t really like visiting the FileTree for each file but I found no other way to do it.
I’m also pretty new to Gradle, is there a better way to solve this kind of (pretty typical, I’d say) task?