Don't overwrite nio build settings with injected settings

The current injection of the new nio keys will overwrite any definitions
of those keys in a build source. This is undesirable. The fix is to
create a mapping of scoped keys to settings and for each inject setting
key, if there is a previous key, put that definition after the injected
definition so that it can override it.
This commit is contained in:
Ethan Atkins
2019-10-08 09:47:59 -07:00
parent d3921d07ce
commit d698d6dcdd
7 changed files with 50 additions and 8 deletions
+20 -7
View File
@@ -27,13 +27,26 @@ import scala.collection.immutable.VectorBuilder
private[sbt] object Settings { private[sbt] object Settings {
private[sbt] def inject(transformed: Seq[Def.Setting[_]]): Seq[Def.Setting[_]] = { private[sbt] def inject(transformed: Seq[Def.Setting[_]]): Seq[Def.Setting[_]] = {
val fileOutputScopes = transformed.collect { val definedSettings = new java.util.HashMap[Def.ScopedKey[_], VectorBuilder[Def.Setting[_]]]
case s if s.key.key == fileOutputs.key && s.key.scope.task.toOption.isDefined => val fileOutputScopes = transformed.flatMap { s =>
s.key.scope val list = new VectorBuilder[Def.Setting[_]]
definedSettings.putIfAbsent(s.key, list) match {
case null => list += s
case l => l += s
}
if (s.key.key == fileOutputs.key && s.key.scope.task.toOption.isDefined) Some(s.key.scope)
else None
}.toSet }.toSet
transformed.flatMap { transformed.flatMap { s =>
case s if s.key.key == fileInputs.key => inputPathSettings(s) val inject =
case s => s :: maybeAddOutputsAndFileStamps(s, fileOutputScopes) if (s.key.key == fileInputs.key) inputPathSettings(s)
else maybeAddOutputsAndFileStamps(s, fileOutputScopes)
s +: inject.flatMap { setting =>
(definedSettings.get(setting.key) match {
case null => Vector(setting)
case set => setting +: set.result()
}): Seq[Def.Setting[_]]
}
} }
} }
@@ -126,7 +139,7 @@ private[sbt] object Settings {
private[sbt] def inputPathSettings(setting: Def.Setting[_]): Seq[Def.Setting[_]] = { private[sbt] def inputPathSettings(setting: Def.Setting[_]): Seq[Def.Setting[_]] = {
val scopedKey = setting.key val scopedKey = setting.key
val scope = scopedKey.scope val scope = scopedKey.scope
setting :: (Keys.allInputPathsAndAttributes in scope := { (Keys.allInputPathsAndAttributes in scope := {
val view = (fileTreeView in scope).value val view = (fileTreeView in scope).value
val inputs = (fileInputs in scope).value val inputs = (fileInputs in scope).value
val stamper = (inputFileStamper in scope).value val stamper = (inputFileStamper in scope).value
@@ -14,7 +14,7 @@ val compileAndCheckNoClassFileUpdates = taskKey[Unit]("Checks that there are no
compileAndCheckNoClassFileUpdates := { compileAndCheckNoClassFileUpdates := {
val current = (classFiles / outputFileStamps).value.toSet val current = (classFiles / outputFileStamps).value.toSet
val previous = (classFiles / outputFileStamps).previous.getOrElse(Nil).toSet val previous = (classFiles / outputFileStamps).previous.getOrElse(Nil).toSet
assert(current == previous) assert(current == previous, s"$current did not equal $previous")
} }
val checkLastModified = inputKey[Unit]("Check the last modified time for a file") val checkLastModified = inputKey[Unit]("Check the last modified time for a file")
@@ -25,6 +25,7 @@ checkLastModified := {
case (file, (negate, expectedLastModified)) => case (file, (negate, expectedLastModified)) =>
val sourceFile = baseDirectory.value / "src" / "main" / "scala" / file val sourceFile = baseDirectory.value / "src" / "main" / "scala" / file
val lastModified = IO.getModifiedTimeOrZero(sourceFile) val lastModified = IO.getModifiedTimeOrZero(sourceFile)
println(s"$lastModified $expectedLastModified")
negate match { negate match {
case Some(_) => assert(lastModified != expectedLastModified) case Some(_) => assert(lastModified != expectedLastModified)
case None => assert(lastModified == expectedLastModified) case None => assert(lastModified == expectedLastModified)
+24
View File
@@ -0,0 +1,24 @@
import java.nio.file.Path
val foo = taskKey[Path]("foo")
// Check a direct override
foo / outputFileStamps := Nil
foo := baseDirectory.value.toPath / "foo.txt"
TaskKey[Unit]("checkFoo") := assert((foo / outputFileStamps).value == Nil)
val bar = taskKey[Path]("bar")
// Check an append
bar / outputFileStamps ++= (baz / outputFileStamps).value
bar / outputFileStamps ++= (baz / outputFileStamps).value
bar := baseDirectory.value.toPath / "bar.txt"
val baz = taskKey[Path]("baz")
baz := baseDirectory.value.toPath / "baz.txt"
TaskKey[Unit]("checkBar") := {
val stamps = (bar / outputFileStamps).value
assert(stamps.length == 3)
val fileNames = stamps.map(_._1.getFileName.toString).toSet
assert(fileNames == Set("bar.txt", "baz.txt"))
}
+1
View File
@@ -0,0 +1 @@
foo
+3
View File
@@ -0,0 +1,3 @@
> checkBar
> checkFoo