Skip contents of symlinked directories in clean

The clean task was previously deleting the contents of directories that
were symlinked into the target directory. This was an oversight because
it never occurred to me that users might symlink a directory whose
contents they did not want deleted into the target directory.
This commit is contained in:
Ethan Atkins 2020-09-15 08:27:12 -07:00
parent 70111bb689
commit a946cbf702
4 changed files with 20 additions and 9 deletions

View File

@ -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.

View File

@ -0,0 +1,5 @@
import java.nio.file.Files
TaskKey[Unit]("createSymlinkedDirectory") := {
Files.createSymbolicLink(target.value.toPath / "foo", baseDirectory.value.toPath / "foo")
}

View File

@ -0,0 +1 @@
bar

View File

@ -0,0 +1,9 @@
> createSymlinkedDirectory
$ exists target/foo/bar
$ exists foo/bar
> clean
$ absent target/foo
$ exists foo/bar