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 {
@InputFiles
FileTree input
@OutputDirectory
File output
def gzip(byte[] input) {
def os = new java.io.ByteArrayOutputStream()
def gz = new java.util.zip.GZIPOutputStream(os) { { def.setLevel(java.util.zip.Deflater.BEST_COMPRESSION); } }
gz.write input
gz.close()
return os.toByteArray()
}
String getRelativePath(File file) {
String path = null
input.visit { FileVisitDetails details ->
if (details.file == file) {
path = details.getRelativePath()
details.stopVisiting()
}
}
if (path == null)
throw new Exception('File not found in input FileTree: ' + file.getPath());
return path;
}
@TaskAction
void execute(IncrementalTaskInputs inputs) {
if (!inputs.incremental)
project.delete(output.listFiles())
inputs.outOfDate { change ->
File file = change.file
String path = getRelativePath(file)
File out = new File(output, path + '.gz')
out.parentFile.mkdirs()
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?