Project.delete and Windows 10 fall edition

project.delete treats symlinks differently comparing Ubuntu to Windows 10 Fall Edition.

If using Cygwin with the environment variable CYGWIN set to “winsymlinks:nativestrict”, symlinks start to work like on Linux. My guess is that this started to work without being priviliged in the version “Creator’s Update”, arriving in September 2017.

Now, deleting a directory with project.delete (where followSymlinks is false by default) on Windows Version 10.0.16299.125, may not work correctly.

  • If the directory to be deleted contains a symlink to a file, the action is correct. The symlink is deleted but the file linked to is kept (SYMLINK).
  • if the directory to be deleted contains a symlink to a directory, the directory’s contents (but not the directory) are wiped out prior deleting the symlink itself (SYMLINKD).

It is probably not related to Gradle Delete task follows NTFS junction points when followSymlinks=false

This script pinpoints the problem:

cat > b.gradle << EOF
task showIfLinksAndDel {
  doLast {
    File target = project.file("target-dir-to-remove")

    if (target.exists() == false) return

    target.traverse { File f ->
      String is = java.nio.file.Files.isSymbolicLink(f.toPath()) ? "IS" : "is not"

      printf("%s %s a symbolic link\n", f.canonicalPath, is)

WD=$( cd "$( dirname "$0" )" && pwd )
rm -rf target-dir-to-remove dir-to-keep symlinkd-directory
mkdir target-dir-to-remove dir-to-keep symlinkd-directory
touch dir-to-keep/file-to-be-kept
touch target-dir-to-remove/file-to-be-deleted
touch symlinkd-directory/another-file-to-be-kept
ln -s $WD/dir-to-keep/file-to-be-kept target-dir-to-remove/absolute-native-link-to-file
ln -s $WD/symlinkd-directory target-dir-to-remove/absolute-native-link-to-symlinkd-directory
echo  "Tree:"
ls -lR -hF --color=tty
if [[ "${osname:0:6}" == "CYGWIN" ]]
  printf "\ncmd view of target-dir-to-remove:\n\n"
  cmd /c dir here
gradle -b b.gradle showIfLinksAndDel
ls -lR -hF --color=tty

On Windows, the directory symlinkd-directory is emptied (but exists). On Linux, the directory still contains another-file-to-be-kept. The behavior exists at least in Gradle versions 3.1 and 4.4.1.