diff --git a/main/src/main/scala/sbt/internal/Clean.scala b/main/src/main/scala/sbt/internal/Clean.scala index a5b19e465..0f314fd60 100644 --- a/main/src/main/scala/sbt/internal/Clean.scala +++ b/main/src/main/scala/sbt/internal/Clean.scala @@ -41,7 +41,7 @@ private[sbt] object Clean { .list(Glob(path, AnyPath)) .filterNot { case (p, _) => exclude(p) } .foreach { - case (dir, attrs) if attrs.isDirectory => + case (dir, attrs) if attrs.isDirectory && !attrs.isSymbolicLink => deleteRecursive(dir) delete(dir) case (file, _) => delete(file) @@ -89,15 +89,11 @@ private[sbt] object Clean { val excludeFilter = cleanFilter(scope).value val delete = cleanDelete(scope).value val targetDir = (target in scope).?.value.map(_.toPath) - def recursiveFiles(dir: Path): Seq[Path] = - view.list(dir.toGlob / **).collect { case (p, _) if !excludeFilter(p) => p } - val targetFiles = (if (full) targetDir else None).fold(Nil: Seq[Path])(recursiveFiles) - val cleanPaths = (cleanFiles in scope).?.value.getOrElse(Nil).flatMap { f => - val path = f.toPath - if (Files.isDirectory(path)) path +: recursiveFiles(path) else path :: Nil + + targetDir.filter(_ => full).foreach(deleteContents(_, excludeFilter, view, delete)) + (cleanFiles in scope).?.value.getOrElse(Nil).foreach { f => + deleteContents(f.toPath, excludeFilter, view, delete) } - val allFiles = cleanPaths.view ++ targetFiles - allFiles.sorted.reverseIterator.foreach(delete) // This is the special portion of the task where we clear out the relevant streams // and file outputs of a task. diff --git a/sbt/src/sbt-test/nio/clean-symlinks/build.sbt b/sbt/src/sbt-test/nio/clean-symlinks/build.sbt new file mode 100644 index 000000000..b7ad34a81 --- /dev/null +++ b/sbt/src/sbt-test/nio/clean-symlinks/build.sbt @@ -0,0 +1,5 @@ +import java.nio.file.Files + +TaskKey[Unit]("createSymlinkedDirectory") := { + Files.createSymbolicLink(target.value.toPath / "foo", baseDirectory.value.toPath / "foo") +} diff --git a/sbt/src/sbt-test/nio/clean-symlinks/foo/bar b/sbt/src/sbt-test/nio/clean-symlinks/foo/bar new file mode 100644 index 000000000..5716ca598 --- /dev/null +++ b/sbt/src/sbt-test/nio/clean-symlinks/foo/bar @@ -0,0 +1 @@ +bar diff --git a/sbt/src/sbt-test/nio/clean-symlinks/test b/sbt/src/sbt-test/nio/clean-symlinks/test new file mode 100644 index 000000000..48dfcb255 --- /dev/null +++ b/sbt/src/sbt-test/nio/clean-symlinks/test @@ -0,0 +1,9 @@ +> createSymlinkedDirectory + +$ exists target/foo/bar +$ exists foo/bar + +> clean + +$ absent target/foo +$ exists foo/bar