Hi,
If one uses a delete action to remove a directory containing symlinks, the files the symlink are pointing to a removed, too. This violates the principle of least surprise.
Please see this build.gradle. It removes testDir/file. Please consider what is happening, if one places a symlink pointing to “/” into toRemoveDir instead? (Hint: Don’t try).
task demo << {
delete('testDir')
delete('toRemoveDir')
mkdir('testDir')
new File('testDir/file').write('anythingi\n')
mkdir('toRemoveDir')
exec {
workingDir '.'
commandLine "ln -s ../testDir toRemoveDir/testLink".split()
}
// show testDir
exec {
workingDir '.'
commandLine "ls -lR testDir".split()
}
delete('toRemoveDir')
// expected: 'toRemoveDir is removed (o.k)
// but actually testDir/file has been removed !!
exec {
workingDir '.'
commandLine "ls -lR testDir".split()
}
}
Looking at the source code of ./subprojects/core/src/main/groovy/org/gradle/api/internal/file/copy/DeleteActionImpl.java
(doDelete): It follows symlinks and deletes everything on its way. Gradle should use the java.nio.file.Files isSymlink() method to detect symlinks.