mirror of https://github.com/sbt/sbt.git
feat: Support glob expressions in scripted
**Problem** It's currently not easy to write a scripted test that works on both sbt 1.x and 2.x when you want to write exists test under target. **Solution** Since we can only use the file system (and not evaluate Scala version etc) 1. this implements glob expression support in `exists`, `absent`, and `delete`. 2. this also introduces `||` operator that would mean a or b.
This commit is contained in:
parent
f996ad1a01
commit
d21b2d250a
|
|
@ -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("[ ", " , ", " ]"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue