Skip to content

Commit

Permalink
Merge pull request #4987 from eatkins/fix-cross-overcompilation
Browse files Browse the repository at this point in the history
Store compile file stamps for each scala version
  • Loading branch information
eed3si9n committed Aug 27, 2019
2 parents c22e318 + bd4d04d commit 110f54a
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 10 deletions.
32 changes: 22 additions & 10 deletions main/src/main/scala/sbt/Defaults.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import sbt.internal.server.{
LanguageServerReporter,
ServerHandler
}
import sbt.nio.FileStamp.Formats.seqPathFileStampJsonFormatter
import sbt.internal.testing.TestLogger
import sbt.internal.util.Attributed.data
import sbt.internal.util.Types._
Expand Down Expand Up @@ -617,31 +618,42 @@ object Defaults extends BuildCommon {
s"inc_compile$extra.zip"
},
externalHooks := {
import sbt.nio.FileStamp.Formats.seqPathFileStampJsonFormatter
import sjsonnew.BasicJsonProtocol.mapFormat
val currentInputs =
(unmanagedSources / inputFileStamps).value ++ (managedSourcePaths / outputFileStamps).value
val previousInputs = (externalHooks / inputFileStamps).previous
val sv = scalaVersion.value
val previousInputs = compileSourceFileInputs.previous.flatMap(_.get(sv))
val inputChanges = previousInputs
.map(sbt.nio.Settings.changedFiles(_, currentInputs))
.getOrElse(FileChanges.noPrevious(currentInputs.map(_._1)))
val currentOutputs = (dependencyClasspathFiles / outputFileStamps).value
val previousOutputs = (externalHooks / outputFileStamps).previous
val previousOutputs = compileBinaryFileInputs.previous.flatMap(_.get(sv))
val outputChanges = previousOutputs
.map(sbt.nio.Settings.changedFiles(_, currentOutputs))
.getOrElse(FileChanges.noPrevious(currentOutputs.map(_._1)))
ExternalHooks.default.value(inputChanges, outputChanges, fileTreeView.value)
},
externalHooks / inputFileStamps := {
compileSourceFileInputs := {
import sjsonnew.BasicJsonProtocol.mapFormat
compile.value // ensures the inputFileStamps previous value is only set if compile succeeds.
(unmanagedSources / inputFileStamps).value ++ (managedSourcePaths / outputFileStamps).value
val version = scalaVersion.value
val versions = crossScalaVersions.value.toSet + version
val prev: Map[String, Seq[(java.nio.file.Path, sbt.nio.FileStamp)]] =
compileSourceFileInputs.previous.map(_.filterKeys(versions)).getOrElse(Map.empty)
prev + (version ->
((unmanagedSources / inputFileStamps).value ++ (managedSourcePaths / outputFileStamps).value))
},
externalHooks / inputFileStamps := (externalHooks / inputFileStamps).triggeredBy(compile).value,
externalHooks / outputFileStamps := {
compileSourceFileInputs := compileSourceFileInputs.triggeredBy(compile).value,
compileBinaryFileInputs := {
import sjsonnew.BasicJsonProtocol.mapFormat
compile.value // ensures the inputFileStamps previous value is only set if compile succeeds.
(dependencyClasspathFiles / outputFileStamps).value
val version = scalaVersion.value
val versions = crossScalaVersions.value.toSet + version
val prev: Map[String, Seq[(java.nio.file.Path, sbt.nio.FileStamp)]] =
compileBinaryFileInputs.previous.map(_.filterKeys(versions)).getOrElse(Map.empty)
prev + (version -> (dependencyClasspathFiles / outputFileStamps).value)
},
externalHooks / outputFileStamps :=
(externalHooks / outputFileStamps).triggeredBy(compile).value,
compileBinaryFileInputs := compileBinaryFileInputs.triggeredBy(compile).value,
incOptions := { incOptions.value.withExternalHooks(externalHooks.value) },
compileIncSetup := compileIncSetupTask.value,
console := consoleTask.value,
Expand Down
6 changes: 6 additions & 0 deletions main/src/main/scala/sbt/nio/Keys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ object Keys {
private[sbt] val classpathFiles =
taskKey[Seq[Path]]("The classpath for a task.").withRank(Invisible)
private[sbt] val compileOutputs = taskKey[Seq[Path]]("Compilation outputs").withRank(Invisible)
private[sbt] val compileSourceFileInputs =
taskKey[Map[String, Seq[(Path, FileStamp)]]]("Source file stamps stored by scala version")
.withRank(Invisible)
private[sbt] val compileBinaryFileInputs =
taskKey[Map[String, Seq[(Path, FileStamp)]]]("Source file stamps stored by scala version")
.withRank(Invisible)

private[this] val hasCheckedMetaBuildMsg =
"Indicates whether or not we have called the checkBuildSources task. This is to avoid warning " +
Expand Down
22 changes: 22 additions & 0 deletions sbt/src/sbt-test/actions/cross-incremental/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
scalaVersion := "2.12.8"
crossScalaVersions := List("2.12.8", "2.13.0")

val setLastModified = taskKey[Unit]("Sets the last modified time for classfiles")
setLastModified := {
val versions = crossScalaVersions.value
versions.map(_.split('.').take(2).mkString("scala-", ".", "")).foreach { v =>
val f = target.value / v / "classes" / "A.class"
Stamps.value.put(f, IO.getModifiedTimeOrZero(f))
}
}

val checkLastModified = taskKey[Unit]("Checks the last modified time for classfiles")
checkLastModified := {
val versions = crossScalaVersions.value
versions.map(_.split('.').take(2).mkString("scala-", ".", "")).foreach { v =>
val classFile = target.value / v / "classes" / "A.class"
val actual = IO.getModifiedTimeOrZero(classFile)
val previous = Stamps.value.get(classFile)
assert(actual == previous, s"$actual did not equal $previous for $classFile")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
object Stamps {
val value = new java.util.HashMap[java.io.File, Long]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
object A {
def a = 1
}
7 changes: 7 additions & 0 deletions sbt/src/sbt-test/actions/cross-incremental/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
> +compile

> setLastModified

> +compile

> checkLastModified
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ final class ScriptedTests(
val (group, name) = testName
s"$group/$name" match {
case "actions/add-alias" => LauncherBased // sbt/Package$
case "actions/cross-incremental" => LauncherBased // tbd
case "actions/cross-multiproject" => LauncherBased // tbd
case "actions/cross-multi-parser" =>
LauncherBased // java.lang.ClassNotFoundException: javax.tools.DiagnosticListener when run with java 11 and an old sbt launcher
Expand Down

0 comments on commit 110f54a

Please sign in to comment.