Consider this example:
def readOnlyFile = file('readOnly.txt');
task createFile << {
if(!readOnlyFile.exists())
readOnlyFile.createNewFile()
readOnlyFile.setWritable(false)
}
task createZip(type: Zip, dependsOn: createFile) {
from(readOnlyFile)
archiveName = 'a.zip'
}
task unzip() << {
FileTree zip = zipTree('a.zip')
zip.each { file -> println file.name }
}
Here, createZip simple creates a zip file called a.zip with a read only file inside. Running unzip works the first time just fine, however this task can only be run once. This is because FileTree expands the zip file into tmp/expandedArchives to iterate over the files, but will not re-expand over the previous version since it has a read only file. Clearly gradle has permissions to overwrite these files since cleaning before re-running works fine. I haven’t looked at the source, but I’m guessing FileTree attempts to overwrite files that exist rather than remove and re-create these files. To get the desired behavior, one could make unzip depend on clean, but then you lose all incremental building capabilities.
To give some context, this causes issues with distZip and distTar as these both use FileTree under the hood, meaning in our current builds we have to clean before each time we wish to create a distribution.