Fixes scripted tests

This commit is contained in:
Eugene Yokota 2022-12-12 06:44:40 -05:00
parent fc31bc3d15
commit e8223cc8be
17 changed files with 132 additions and 93 deletions

View File

@ -4611,7 +4611,7 @@ trait BuildExtra extends BuildCommon with DefExtra {
scoped.scopedKey, scoped.scopedKey,
ClassLoaders.runner mapReferenced Project.mapScope(s => s.in(config)) ClassLoaders.runner mapReferenced Project.mapScope(s => s.in(config))
).zipWith(Def.task { ((config / fullClasspath).value, streams.value) }) { case (rTask, t) => ).zipWith(Def.task { ((config / fullClasspath).value, streams.value) }) { case (rTask, t) =>
(t, rTask).mapN { case ((cp: Keys.Classpath, s: Streams), r: ScalaRun) => (t, rTask).mapN { case ((cp, s), r) =>
r.run(mainClass, data(cp), arguments, s.log).get r.run(mainClass, data(cp), arguments, s.log).get
} }
}.value }.value

View File

@ -66,7 +66,7 @@ object ScriptedPlugin extends AutoPlugin {
.map(_.get().head) .map(_.get().head)
.value, .value,
sbtTestDirectory := sourceDirectory.value / "sbt-test", sbtTestDirectory := sourceDirectory.value / "sbt-test",
libraryDependencies ++= (CrossVersion.partialVersion(scriptedSbt.value) match { libraryDependencies ++= (CrossVersion.partialVersion(scriptedSbt.value) match
case Some((0, 13)) => case Some((0, 13)) =>
Seq( Seq(
"org.scala-sbt" % "scripted-sbt" % scriptedSbt.value % ScriptedConf, "org.scala-sbt" % "scripted-sbt" % scriptedSbt.value % ScriptedConf,
@ -77,9 +77,13 @@ object ScriptedPlugin extends AutoPlugin {
"org.scala-sbt" %% "scripted-sbt" % scriptedSbt.value % ScriptedConf, "org.scala-sbt" %% "scripted-sbt" % scriptedSbt.value % ScriptedConf,
"org.scala-sbt" % "sbt-launch" % scriptedSbt.value % ScriptedLaunchConf "org.scala-sbt" % "sbt-launch" % scriptedSbt.value % ScriptedLaunchConf
) )
case Some((2, _)) =>
Seq(
"org.scala-sbt" % "sbt-launch" % scriptedSbt.value % ScriptedLaunchConf
)
case Some((x, y)) => sys error s"Unknown sbt version ${scriptedSbt.value} ($x.$y)" case Some((x, y)) => sys error s"Unknown sbt version ${scriptedSbt.value} ($x.$y)"
case None => sys error s"Unknown sbt version ${scriptedSbt.value}" case None => sys error s"Unknown sbt version ${scriptedSbt.value}"
}), ),
scriptedClasspath := getJars(ScriptedConf).value, scriptedClasspath := getJars(ScriptedConf).value,
scriptedTests := scriptedTestsTask.value, scriptedTests := scriptedTestsTask.value,
scriptedParallelInstances := 1, scriptedParallelInstances := 1,

View File

@ -1,8 +1,8 @@
lazy val scala212 = "2.12.12" lazy val scala3 = "3.2.1"
lazy val scala213 = "2.13.1" lazy val scala213 = "2.13.1"
ThisBuild / crossScalaVersions := Seq(scala212, scala213) ThisBuild / crossScalaVersions := Seq(scala3, scala213)
ThisBuild / scalaVersion := scala212 ThisBuild / scalaVersion := scala3
lazy val rootProj = (project in file(".")) lazy val rootProj = (project in file("."))
.aggregate(libProj, fooPlugin) .aggregate(libProj, fooPlugin)
@ -20,10 +20,11 @@ lazy val fooPlugin = (project in file("sbt-foo"))
.enablePlugins(SbtPlugin) .enablePlugins(SbtPlugin)
.settings( .settings(
name := "sbt-foo", name := "sbt-foo",
crossScalaVersions := Seq(scala212) crossScalaVersions := Seq(scala3),
) )
lazy val extrasProj = (project in file("extras")) lazy val extrasProj = (project in file("extras"))
.settings( .settings(
name := "foo-extras", name := "foo-extras",
) )

View File

@ -1,64 +1,67 @@
> show rootProj/projectID
> + compile > + compile
$ exists lib/target/scala-2.12
$ exists lib/target/scala-3.2.1
$ exists lib/target/scala-2.13 $ exists lib/target/scala-2.13
$ exists sbt-foo/target/scala-2.12 $ exists sbt-foo/target/scala-3.2.1
-$ exists sbt-foo/target/scala-2.13 -$ exists sbt-foo/target/scala-2.13
> clean > clean
> + libProj/compile > + libProj/compile
$ exists lib/target/scala-2.12 $ exists lib/target/scala-3.2.1
$ exists lib/target/scala-2.13 $ exists lib/target/scala-2.13
-$ exists sbt-foo/target/scala-2.12 -$ exists sbt-foo/target/scala-3.2.1
-$ exists sbt-foo/target/scala-2.13 -$ exists sbt-foo/target/scala-2.13
# test safe switching # test safe switching
> clean > clean
> ++ 2.12.12 -v compile > ++ 3.2.1 -v compile
$ exists lib/target/scala-2.12 $ exists lib/target/scala-3.2.1
-$ exists lib/target/scala-2.13 -$ exists lib/target/scala-2.13
$ exists sbt-foo/target/scala-2.12 $ exists sbt-foo/target/scala-3.2.1
-$ exists sbt-foo/target/scala-2.13 -$ exists sbt-foo/target/scala-2.13
# Test legacy cross build with command support # Test legacy cross build with command support
# > clean # > clean
# > + build # > + build
# $ exists lib/target/scala-2.12 # $ exists lib/target/scala-3.2.1
# $ exists lib/target/scala-2.13 # $ exists lib/target/scala-2.13
# $ exists sbt-foo/target/scala-2.12 # $ exists sbt-foo/target/scala-3.2.1
# -$ exists sbt-foo/target/scala-2.13 # -$ exists sbt-foo/target/scala-2.13
# Test ++ leaves crossScalaVersions unchanged # Test ++ leaves crossScalaVersions unchanged
> clean > clean
> ++2.12.12 > ++3.2.1
> +extrasProj/compile > +extrasProj/compile
$ exists extras/target/scala-2.13 $ exists extras/target/scala-2.13
$ exists extras/target/scala-2.12 $ exists extras/target/scala-3.2.1
# test safe switching # test safe switching
> clean > clean
> ++ 2.13.1 -v compile > ++ 2.13.1 -v compile
$ exists lib/target/scala-2.13 $ exists lib/target/scala-2.13
-$ exists lib/target/scala-2.12 -$ exists lib/target/scala-3.2.1
# -$ exists sbt-foo/target/scala-2.12 # -$ exists sbt-foo/target/scala-3.2.1
-$ exists sbt-foo/target/scala-2.13 -$ exists sbt-foo/target/scala-2.13
# test wildcard switching (2.12) # test wildcard switching (3.2.1
> clean > clean
> ++ 2.12.* -v compile > ++ 3.* -v compile
$ exists lib/target/scala-2.12 $ exists lib/target/scala-3.2.1
-$ exists lib/target/scala-2.13 -$ exists lib/target/scala-2.13
$ exists sbt-foo/target/scala-2.12 $ exists sbt-foo/target/scala-3.2.1
-$ exists sbt-foo/target/scala-2.13 -$ exists sbt-foo/target/scala-2.13
# test wildcard switching (2.13) # test wildcard switching (2.13)
> clean > clean
> ++ 2.13.x -v compile > ++ 2.13.x -v compile
$ exists lib/target/scala-2.13 $ exists lib/target/scala-2.13
-$ exists lib/target/scala-2.12 -$ exists lib/target/scala-3.2.1
# -$ exists sbt-foo/target/scala-2.12 # -$ exists sbt-foo/target/scala-3.2.1
-$ exists sbt-foo/target/scala-2.13 -$ exists sbt-foo/target/scala-2.13
# test wildcard switching (no matches) # test wildcard switching (no matches)
-> ++ 3.* -> ++ 4.*
# test wildcard switching (multiple matches) # test wildcard switching (multiple matches)
-> ++ 2.* > ++ 2.*

View File

@ -1,11 +1,12 @@
// tests that errors are properly propagated for dependsOn, map, and flatMap // tests that errors are properly propagated for dependsOn, map, and flatMap
import sbt.TupleSyntax.*
lazy val root = (project in file(".")). lazy val root = (project in file(".")).
settings( settings(
a := (baseDirectory map (b => if ((b / "succeed").exists) () else sys.error("fail"))).value, a := (baseDirectory mapN (b => if ((b / "succeed").exists) () else sys.error("fail"))).value,
b := (a.task(at => nop dependsOn(at))).value, b := (a.task(at => nop dependsOn(at))).value,
c := (a map { _ => () }).value, c := (a mapN { _ => () }).value,
d := (a flatMap { _ => task { () } }).value d := (a flatMapN { _ => task { () } }).value
) )
lazy val a = taskKey[Unit]("") lazy val a = taskKey[Unit]("")
lazy val b = taskKey[Unit]("") lazy val b = taskKey[Unit]("")
@ -17,7 +18,7 @@ lazy val input = (project in file("input")).
f := (if (Def.spaceDelimited().parsed.head == "succeed") () else sys.error("fail")), f := (if (Def.spaceDelimited().parsed.head == "succeed") () else sys.error("fail")),
j := sys.error("j"), j := sys.error("j"),
g := (f dependsOn(j)).evaluated, g := (f dependsOn(j)).evaluated,
h := (f map { _ => IO.touch(file("h")) }).evaluated h := (f mapTask { _ => IO.touch(file("h")) }).evaluated
) )
lazy val f = inputKey[Unit]("") lazy val f = inputKey[Unit]("")
lazy val g = inputKey[Unit]("") lazy val g = inputKey[Unit]("")

View File

@ -4,7 +4,6 @@ lazy val boink = project
lazy val woof = project lazy val woof = project
lazy val numConfigClasses = taskKey[Int]("counts number of config classes") lazy val numConfigClasses = taskKey[Int]("counts number of config classes")
lazy val configClassCountFile = settingKey[File]("File where we write the # of config classes") lazy val configClassCountFile = settingKey[File]("File where we write the # of config classes")
@ -13,13 +12,14 @@ lazy val saveNumConfigClasses = taskKey[Unit]("Saves the number of config classe
lazy val checkNumConfigClasses = taskKey[Unit]("Checks the number of config classes") lazy val checkNumConfigClasses = taskKey[Unit]("Checks the number of config classes")
lazy val checkDifferentConfigClasses = taskKey[Unit]("Checks that the number of config classes are different.") lazy val checkDifferentConfigClasses =
taskKey[Unit]("Checks that the number of config classes are different.")
configClassCountFile := (target.value / "config-count") configClassCountFile := (target.value / "config-count")
numConfigClasses := { numConfigClasses := {
val cdir = (ThisBuild / baseDirectory).value / "project/target/config-classes" val cdir = (ThisBuild / baseDirectory).value / "project/target/config-classes"
(cdir.allPaths --- cdir).get.length (cdir.allPaths --- cdir).get().length
} }
saveNumConfigClasses := { saveNumConfigClasses := {
@ -30,7 +30,8 @@ def previousConfigCount = Def.task {
val previousString = IO.read(configClassCountFile.value) val previousString = IO.read(configClassCountFile.value)
try Integer.parseInt(previousString) try Integer.parseInt(previousString)
catch { catch {
case t: Throwable => throw new RuntimeException(s"Failed to parse previous config file value: $previousString", t) case t: Throwable =>
throw new RuntimeException(s"Failed to parse previous config file value: $previousString", t)
} }
} }
@ -38,12 +39,18 @@ checkDifferentConfigClasses := {
val previousString = IO.read(configClassCountFile.value) val previousString = IO.read(configClassCountFile.value)
val previous = previousConfigCount.value val previous = previousConfigCount.value
val current = numConfigClasses.value val current = numConfigClasses.value
assert(previous != current, s"Failed to create new configuration classes. Expected: $previous, Found: $current") assert(
previous != current,
s"Failed to create new configuration classes. Expected: $previous, Found: $current"
)
} }
checkNumConfigClasses := { checkNumConfigClasses := {
val previousString = IO.read(configClassCountFile.value) val previousString = IO.read(configClassCountFile.value)
val previous = previousConfigCount.value val previous = previousConfigCount.value
val current = numConfigClasses.value val current = numConfigClasses.value
assert(previous == current, s"Failed to delete extra configuration classes. Expected: $previous, Found: $current") assert(
previous == current,
s"Failed to delete extra configuration classes. Expected: $previous, Found: $current"
)
} }

View File

@ -44,7 +44,7 @@ def expectedMappings = Def.task {
} }
} }
} }
val mc = (Compile / c / classDirectory).value -> apiBase("c") val mc = (c / Compile / classDirectory).value -> apiBase("c")
(mc +: ms).toMap (mc +: ms).toMap
} }

View File

@ -1,20 +1,22 @@
lazy val intTask = taskKey[Int]("int") lazy val intTask = taskKey[Int]("int")
lazy val root = (project in file(".")). lazy val root = (project in file("."))
dependsOn(b, c). .dependsOn(b, c)
settings( .settings(
Compile / intTask := { Compile / intTask := {
// a sequence of tasks could be joined together // a sequence of tasks could be joined together
Seq(b, c).map(p => Cmpile / p / intTask).join.map( as => (1 /: as)(_ + _) ).value Seq(b, c)
.map(p => p / Compile / intTask)
.join
.map(as => (1 /: as)(_ + _))
.value
} }
) )
lazy val b = (project in file("b")). lazy val b = (project in file("b")).settings(
settings( Compile / intTask := 1
Compile / intTask := 1 )
)
lazy val c = (project in file("c")). lazy val c = (project in file("c")).settings {
settings{ Compile / intTask := 2
Compile / intTask := 2 }
}

View File

@ -1,12 +1,11 @@
TaskKey[Unit]("checkName", "") := { TaskKey[Unit]("checkName", "") := {
assert(name.value == "hello-world", "Name is not hello-world, failed to set!") assert(name.value == "hello-world", "Name is not hello-world, failed to set!")
} }
val notExistingThing = settingKey[Int]("Something new") val notExistingThing = settingKey[Int]("Something new")
TaskKey[Unit]("checkBuildSbtDefined", "") := { TaskKey[Unit]("checkBuildSbtDefined", "") := {
assert(notExistingThing.?.value == Some(5), "Failed to set a settingKey defined in build.sbt") assert(notExistingThing.?.value == Some(5), "Failed to set a settingKey defined in build.sbt")
} }
TaskKey[Unit]("evil-clear-logger") := { TaskKey[Unit]("evil-clear-logger") := {
@ -20,14 +19,14 @@ TaskKey[Unit]("evil-clear-logger") := {
} }
commands ++= Seq( commands ++= Seq(
Command.command("helloWorldTest") { state: State => Command.command("helloWorldTest") { (state: State) =>
"""set name := "hello-world"""" :: """set name := "hello-world"""" ::
"checkName" :: "checkName" ::
state state
}, },
Command.command("buildSbtTest") { state: State => Command.command("buildSbtTest") { (state: State) =>
"""set notExistingThing := 5""" :: """set notExistingThing := 5""" ::
"checkBuildSbtDefined" :: "checkBuildSbtDefined" ::
state state
} }
) )

View File

@ -12,6 +12,7 @@ val checkPersist = inputKey[Unit]("")
val updateDemo = taskKey[Int]("") val updateDemo = taskKey[Int]("")
val check = inputKey[Unit]("") val check = inputKey[Unit]("")
val sample = AttributeKey[Int]("demo-key") val sample = AttributeKey[Int]("demo-key")
val dummyKey = taskKey[Unit]("")
def updateDemoInit = state map { s => (s get sample getOrElse 9) + 1 } def updateDemoInit = state map { s => (s get sample getOrElse 9) + 1 }
@ -22,7 +23,8 @@ lazy val root = (project in file(".")).
inMemorySetting, inMemorySetting,
persistedSetting, persistedSetting,
inMemoryCheck, inMemoryCheck,
persistedCheck persistedCheck,
dummyKey := (),
) )
def demoState(s: State, i: Int): State = s put (sample, i + 1) def demoState(s: State, i: Int): State = s put (sample, i + 1)
@ -43,7 +45,11 @@ def inMemoryCheck = checkKeep := (inputCheck( (ctx, s) => Space ~> str( getF
def persistedCheck = checkPersist := (inputCheck( (ctx, s) => Space ~> str(loadFromContext(persist, ctx, s)) )).evaluated def persistedCheck = checkPersist := (inputCheck( (ctx, s) => Space ~> str(loadFromContext(persist, ctx, s)) )).evaluated
def inputCheck[T](f: (ScopedKey[_], State) => Parser[T]): Initialize[InputTask[Unit]] = def inputCheck[T](f: (ScopedKey[_], State) => Parser[T]): Initialize[InputTask[Unit]] =
InputTask( resolvedScoped(ctx => (s: State) => f(ctx, s)) )( dummyTask ) InputTask.separate( resolvedScoped(ctx => (s: State) => f(ctx, s)) )( dummyTask )
def dummyTask = (key: Any) => maxErrors map { _ => () } import sbt.TupleSyntax.*
// def dummyTask = (key: Any) => maxErrors mapN { _ => () }
def dummyTask[A] = Def.setting {
(a: A) => dummyKey.taskValue
}
def str(o: Option[Int]) = o match { case None => "blue"; case Some(i) => i.toString } def str(o: Option[Int]) = o match { case None => "blue"; case Some(i) => i.toString }

View File

@ -23,4 +23,4 @@ taskA := (taskA triggeredBy taskB).value
taskE := (taskE runBefore taskF).value taskE := (taskE runBefore taskF).value
// test utils // test utils
def touch(f: File): File = { IO touch f; f } def touch(f: File): File = { IO.touch(f); f }

View File

@ -18,37 +18,38 @@ def testTask[T](name: String, expected: String, task: TaskKey[T]) = TaskKey[Unit
myTask := "root" myTask := "root"
testTask("testRunTaskRoot", "root", myTask) testTask("testRunTaskRoot", "root", myTask)
myTask in Compile := "root compile" Compile / myTask := "root compile"
testTask("testRunTaskRootCompile", "root compile", myTask in Compile) testTask("testRunTaskRootCompile", "root compile", Compile / myTask)
myTask in sub := "sub" sub / myTask := "sub"
testTask("testRunTaskSub", "sub", myTask in sub) testTask("testRunTaskSub", "sub", sub / myTask)
myTask in (sub, Compile) := "sub compile" sub / Compile / myTask := "sub compile"
testTask("testRunTaskSubCompile", "sub compile", myTask in (sub, Compile)) testTask("testRunTaskSubCompile", "sub compile", sub / Compile / myTask)
def argFunction(f: String => String) = Def.inputTask { def argFunction(f: String => String) = Def.inputTask {
import complete.Parsers._ import complete.Parsers._
f((OptSpace ~> StringBasic).parsed) f((OptSpace ~> StringBasic).parsed)
} }
def testInputTask[T](name: String, expected: String, task: InputKey[T], arg: String) = TaskKey[Unit](name) := { def testInputTask[T](name: String, expected: String, task: InputKey[T], arg: String) =
val s = state.value TaskKey[Unit](name) := {
val e = Project.extract(s) val s = state.value
val (_, result) = e.runInputTask(task, arg, s) val e = Project.extract(s)
if (expected != result) { val (_, result) = e.runInputTask(task, arg, s)
throw sys.error(s"Error in test $name: Expected $expected but got $result") if (expected != result) {
throw sys.error(s"Error in test $name: Expected $expected but got $result")
}
} }
}
myInputTask := argFunction(_.toUpperCase(Locale.ENGLISH)).evaluated myInputTask := argFunction(_.toUpperCase(Locale.ENGLISH)).evaluated
testInputTask("testRunInputTaskRoot", "FOO", myInputTask, "foo") testInputTask("testRunInputTaskRoot", "FOO", myInputTask, "foo")
Compile / myInputTask := argFunction(_.toLowerCase(Locale.ENGLISH)).evaluated Compile / myInputTask := argFunction(_.toLowerCase(Locale.ENGLISH)).evaluated
testInputTask("testRunInputTaskRootCompile", "foo", myInputTask in Compile, "FOO") testInputTask("testRunInputTaskRootCompile", "foo", Compile / myInputTask, "FOO")
sub / myInputTask := argFunction(_.head.toString).evaluated sub / myInputTask := argFunction(_.head.toString).evaluated
testInputTask("testRunInputTaskSub", "f", myInputTask in sub, "foo") testInputTask("testRunInputTaskSub", "f", sub / myInputTask, "foo")
sub / Compile / myInputTask := argFunction(_.tail).evaluated sub / Compile / myInputTask := argFunction(_.tail).evaluated
testInputTask("testRunInputTaskSubCompile", "oo", myInputTask in (sub, Compile), "foo") testInputTask("testRunInputTaskSubCompile", "oo", sub / Compile / myInputTask, "foo")

View File

@ -1,4 +1,8 @@
ThisBuild / scalaVersion := "2.12.17"
val dependency = project.settings(exportJars := true) val dependency = project.settings(exportJars := true)
val descendant = project.dependsOn(dependency).settings( val descendant = project
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test" .dependsOn(dependency)
) .settings(
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test"
)

View File

@ -1,7 +1,8 @@
ThisBuild / scalaVersion := "2.12.17"
ThisBuild / turbo := true ThisBuild / turbo := true
resolvers += "Local Maven" at (baseDirectory.value / "libraries" / "foo" / "ivy").toURI.toURL.toString resolvers += "Local Maven" at (baseDirectory.value / "libraries" / "foo" / "ivy").toURI.toURL.toString
libraryDependencies += "sbt" %% "foo-lib" % "0.1.0" libraryDependencies += "sbt" %% "foo-lib" % "0.1.0"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test" libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % Test

View File

@ -1,3 +1,5 @@
ThisBuild / scalaVersion := "2.12.17"
val test = (project in file(".")).settings( val test = (project in file(".")).settings(
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.7" % Test libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.7" % Test
) )

View File

@ -1,4 +1,8 @@
ThisBuild / scalaVersion := "2.12.17"
val dependency = project.settings(exportJars := true) val dependency = project.settings(exportJars := true)
val descendant = project.dependsOn(dependency).settings( val descendant = project
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test" .dependsOn(dependency)
) .settings(
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test"
)

View File

@ -1,4 +1,5 @@
ThisBuild / turbo := true ThisBuild / turbo := true
ThisBuild / scalaVersion := "2.12.17"
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.attribute.FileTime import java.nio.file.attribute.FileTime
@ -19,9 +20,12 @@ val snapshot = (project in file(".")).settings(
rewriteIvy := { rewriteIvy := {
val dir = Def.spaceDelimited().parsed.head val dir = Def.spaceDelimited().parsed.head
sbt.IO.delete(baseDirectory.value / "ivy") sbt.IO.delete(baseDirectory.value / "ivy")
sbt.IO.copyDirectory(baseDirectory.value / s"libraries/library-$dir/ivy", baseDirectory.value / "ivy") sbt.IO.copyDirectory(
baseDirectory.value / s"libraries/library-$dir/ivy",
baseDirectory.value / "ivy"
)
Files.walk(file("ivy").getCanonicalFile.toPath).iterator.asScala.foreach { f => Files.walk(file("ivy").getCanonicalFile.toPath).iterator.asScala.foreach { f =>
Files.setLastModifiedTime(f, FileTime.fromMillis(System.currentTimeMillis + 3000)) Files.setLastModifiedTime(f, FileTime.fromMillis(System.currentTimeMillis + 3000))
} }
} }
) )