diff --git a/internal/util-scripted/src/main/scala/sbt/internal/scripted/FileCommands.scala b/internal/util-scripted/src/main/scala/sbt/internal/scripted/FileCommands.scala index 596278c25..66422e465 100644 --- a/internal/util-scripted/src/main/scala/sbt/internal/scripted/FileCommands.scala +++ b/internal/util-scripted/src/main/scala/sbt/internal/scripted/FileCommands.scala @@ -11,11 +11,15 @@ package internal package scripted import java.io.File +import sbt.nio.file.{ FileTreeView, Glob, PathFilter, RecursiveGlob } import sbt.io.{ IO, Path } -import sbt.io.syntax._ +import sbt.io.syntax.* import Path._ class FileCommands(baseDirectory: File) extends BasicStatementHandler { + final val OR = "||" + lazy val view = FileTreeView.Ops(FileTreeView.default) + val baseGlob = Glob(baseDirectory) lazy val commands = commandMap def commandMap = Map( @@ -51,8 +55,33 @@ class FileCommands(baseDirectory: File) extends BasicStatementHandler { def spaced[T](l: Seq[T]) = l.mkString(" ") def fromStrings(paths: List[String]) = paths.map(fromString) def fromString(path: String) = new File(baseDirectory, path) + def filterFromStrings(exprs: List[String]): List[PathFilter] = + def orGlobs = + val exprs1 = exprs + .mkString("") + .split(OR) + .filter(_ != OR) + .toList + .map(_.trim) + val combined = exprs1.map(Glob(baseDirectory, _)) match + case Nil => sys.error("unexpected Nil") + case g :: Nil => (g: PathFilter) + case g :: gs => + gs.foldLeft(g: PathFilter) { case (acc, g) => + acc || (g: PathFilter) + } + List(combined) + if exprs.contains("||") then orGlobs + else exprs.map(Glob(baseDirectory, _): PathFilter) + def touch(paths: List[String]): Unit = IO.touch(fromStrings(paths)) - def delete(paths: List[String]): Unit = IO.delete(fromStrings(paths)) + def delete(paths: List[String]): Unit = + IO.delete( + (filterFromStrings(paths) + .flatMap: filter => + view.list(baseGlob / RecursiveGlob, filter)) + .map(_._1.toFile) + ) /*def sync(from: String, to: String) = IO.sync(fromString(from), fromString(to), log)*/ def copyFile(from: String, to: String): Unit = @@ -78,13 +107,16 @@ class FileCommands(baseDirectory: File) extends BasicStatementHandler { scriptError(s"$pathA is not newer than $pathB") } } + // use FileTreeView to test if a file with the given filter exists + def exists0(filter: PathFilter): Boolean = + view.list(baseGlob / RecursiveGlob, filter).nonEmpty def exists(paths: List[String]): Unit = { - val notPresent = fromStrings(paths).filter(!_.exists) + val notPresent = filterFromStrings(paths).filter(!exists0(_)) if (notPresent.nonEmpty) scriptError("File(s) did not exist: " + notPresent.mkString("[ ", " , ", " ]")) } def absent(paths: List[String]): Unit = { - val present = fromStrings(paths).filter(_.exists) + val present = filterFromStrings(paths).filter(exists0) if (present.nonEmpty) scriptError("File(s) existed: " + present.mkString("[ ", " , ", " ]")) } diff --git a/sbt-app/src/sbt-test/actions/clean-managed/test b/sbt-app/src/sbt-test/actions/clean-managed/test index f9cf78153..f5d1c179d 100644 --- a/sbt-app/src/sbt-test/actions/clean-managed/test +++ b/sbt-app/src/sbt-test/actions/clean-managed/test @@ -1,6 +1,7 @@ > compile -$ exists target/out/jvm/scala-3.3.1/clean-managed/src_managed/foo.txt target/out/jvm/scala-3.3.1/clean-managed/src_managed/bar.txt +$ exists target/**/clean-managed/src_managed/foo.txt target/**/clean-managed/src_managed/bar.txt > clean -$ absent target/out/jvm/scala-3.3.1/clean-managed/src_managed/foo.txt -$ exists target/out/jvm/scala-3.3.1/clean-managed/src_managed/bar.txt +$ absent target/**/clean-managed/src_managed/foo.txt +$ exists target/**/clean-managed/src_managed/bar.txt +$ exists target/**/clean-managed/src_managed/bar.txt || target/**/clean-managed/src_managed/x.txt diff --git a/sbt-app/src/sbt-test/actions/compile-clean/test b/sbt-app/src/sbt-test/actions/compile-clean/test index 3802f91ee..4ce605ebd 100644 --- a/sbt-app/src/sbt-test/actions/compile-clean/test +++ b/sbt-app/src/sbt-test/actions/compile-clean/test @@ -1,17 +1,17 @@ $ touch target/out/jvm/scala-2.12.20/compile-clean/backend/cant-touch-this > Test/compile -$ exists target/out/jvm/scala-2.12.20/compile-clean/backend/A.class -$ exists target/out/jvm/scala-2.12.20/compile-clean/backend/X.class -$ exists target/out/jvm/scala-2.12.20/compile-clean/test-backend/B.class +$ exists target/**/compile-clean/backend/A.class +$ exists target/**/compile-clean/backend/X.class +$ exists target/**/compile-clean/test-backend/B.class > Test/clean -$ exists target/out/jvm/scala-2.12.20/compile-clean/backend/cant-touch-this -$ exists target/out/jvm/scala-2.12.20/compile-clean/backend/A.class -$ exists target/out/jvm/scala-2.12.20/compile-clean/backend/X.class -$ absent target/out/jvm/scala-2.12.20/compile-clean/test-backend/B.class +$ exists target/**/compile-clean/backend/cant-touch-this +$ exists target/**/compile-clean/backend/A.class +$ exists target/**/compile-clean/backend/X.class +$ absent target/**/compile-clean/test-backend/B.class > Compile/clean -$ exists target/out/jvm/scala-2.12.20/compile-clean/backend/cant-touch-this -$ absent target/out/jvm/scala-2.12.20/compile-clean/backend/A.class -$ exists target/out/jvm/scala-2.12.20/compile-clean/backend/X.class +$ exists target/**/compile-clean/backend/cant-touch-this +$ absent target/**/compile-clean/backend/A.class +$ exists target/**/compile-clean/backend/X.class diff --git a/sbt-app/src/sbt-test/actions/task-map/test b/sbt-app/src/sbt-test/actions/task-map/test index f22910038..e5c2c2d81 100644 --- a/sbt-app/src/sbt-test/actions/task-map/test +++ b/sbt-app/src/sbt-test/actions/task-map/test @@ -1,7 +1,7 @@ > taskB -$ exists target/out/jvm/scala-3.3.1/task-map/b -$ exists target/out/jvm/scala-3.3.1/task-map/a +$ exists target/**/task-map/**/b +$ exists target/**/task-map/**/a > taskF -$ exists target/out/jvm/scala-3.3.1/task-map/e -$ exists target/out/jvm/scala-3.3.1/task-map/f +$ exists target/**/task-map/e +$ exists target/**/task-map/f