Merge pull request #7933 from eed3si9n/bport/exists

[1.x] feat: Support glob expressions in scripted
This commit is contained in:
eugene yokota 2024-12-09 02:55:22 -05:00 committed by GitHub
commit f61100fe87
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 55 additions and 18 deletions

View File

@ -11,11 +11,15 @@ package internal
package scripted package scripted
import java.io.File import java.io.File
import sbt.nio.file.{ FileTreeView, Glob, PathFilter, RecursiveGlob }
import sbt.io.{ IO, Path } import sbt.io.{ IO, Path }
import sbt.io.syntax._ import sbt.io.syntax._
import Path._ import Path._
class FileCommands(baseDirectory: File) extends BasicStatementHandler { class FileCommands(baseDirectory: File) extends BasicStatementHandler {
final val OR = "||"
lazy val view = FileTreeView.Ops(FileTreeView.default)
val baseGlob = Glob(baseDirectory)
lazy val commands = commandMap lazy val commands = commandMap
def commandMap = def commandMap =
Map( Map(
@ -51,8 +55,38 @@ class FileCommands(baseDirectory: File) extends BasicStatementHandler {
def spaced[T](l: Seq[T]) = l.mkString(" ") def spaced[T](l: Seq[T]) = l.mkString(" ")
def fromStrings(paths: List[String]) = paths.map(fromString) def fromStrings(paths: List[String]) = paths.map(fromString)
def fromString(path: String) = new File(baseDirectory, path) 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("||")) orGlobs
else exprs.map(Glob(baseDirectory, _): PathFilter)
}
def touch(paths: List[String]): Unit = IO.touch(fromStrings(paths)) 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) = /*def sync(from: String, to: String) =
IO.sync(fromString(from), fromString(to), log)*/ IO.sync(fromString(from), fromString(to), log)*/
def copyFile(from: String, to: String): Unit = def copyFile(from: String, to: String): Unit =
@ -78,13 +112,16 @@ class FileCommands(baseDirectory: File) extends BasicStatementHandler {
scriptError(s"$pathA is not newer than $pathB") 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 = { def exists(paths: List[String]): Unit = {
val notPresent = fromStrings(paths).filter(!_.exists) val notPresent = filterFromStrings(paths).filter(!exists0(_))
if (notPresent.nonEmpty) if (notPresent.nonEmpty)
scriptError("File(s) did not exist: " + notPresent.mkString("[ ", " , ", " ]")) scriptError("File(s) did not exist: " + notPresent.mkString("[ ", " , ", " ]"))
} }
def absent(paths: List[String]): Unit = { def absent(paths: List[String]): Unit = {
val present = fromStrings(paths).filter(_.exists) val present = filterFromStrings(paths).filter(exists0)
if (present.nonEmpty) if (present.nonEmpty)
scriptError("File(s) existed: " + present.mkString("[ ", " , ", " ]")) scriptError("File(s) existed: " + present.mkString("[ ", " , ", " ]"))
} }

View File

@ -1,6 +1,6 @@
> compile > compile
$ exists target/scala-2.12/src_managed/foo.txt target/scala-2.12/src_managed/bar.txt $ exists target/**/src_managed/foo.txt target/**/src_managed/bar.txt
> clean > clean
$ absent target/scala-2.12/src_managed/foo.txt $ absent target/**/src_managed/foo.txt
$ exists target/scala-2.12/src_managed/bar.txt $ exists target/**/src_managed/bar.txt

View File

@ -1,22 +1,22 @@
$ touch target/cant-touch-this $ touch target/cant-touch-this
> Test/compile > Test/compile
$ exists target/scala-2.12/classes/A.class $ exists target/**/classes/A.class
$ exists target/scala-2.12/test-classes/B.class $ exists target/**/test-classes/B.class
> Test/clean > Test/clean
$ exists target/cant-touch-this $ exists target/cant-touch-this
# it should clean only compile classes # it should clean only compile classes
$ exists target/scala-2.12/classes/A.class $ exists target/**/classes/A.class
$ exists target/scala-2.12/classes/X.class $ exists target/**/classes/X.class
$ absent target/scala-2.12/test-classes/B.class $ absent target/**/test-classes/B.class
# compiling everything again, but now cleaning only compile classes # compiling everything again, but now cleaning only compile classes
> Test/compile > Test/compile
> Compile/clean > Compile/clean
$ exists target/cant-touch-this $ exists target/cant-touch-this
# it should clean only compile classes # it should clean only compile classes
$ absent target/scala-2.12/classes/A.class $ absent target/**/classes/A.class
$ exists target/scala-2.12/test-classes/B.class $ exists target/**/test-classes/B.class
# and X has to be kept, because of the cleanKeepFiles override # and X has to be kept, because of the cleanKeepFiles override
$ exists target/scala-2.12/classes/X.class $ exists target/**/classes/X.class

View File

@ -1,7 +1,7 @@
> taskB > taskB
$ exists target/b $ exists target/**/b
$ exists target/a $ exists target/**/a
> taskF > taskF
$ exists target/e $ exists target/**/e
$ exists target/f $ exists target/**/f