Merge pull request #4987 from eatkins/fix-cross-overcompilation

Store compile file stamps for each scala version
This commit is contained in:
eugene yokota 2019-08-27 08:39:37 -04:00 committed by GitHub
commit 110f54a044
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 10 deletions

View File

@ -47,6 +47,7 @@ import sbt.internal.server.{
LanguageServerReporter, LanguageServerReporter,
ServerHandler ServerHandler
} }
import sbt.nio.FileStamp.Formats.seqPathFileStampJsonFormatter
import sbt.internal.testing.TestLogger import sbt.internal.testing.TestLogger
import sbt.internal.util.Attributed.data import sbt.internal.util.Attributed.data
import sbt.internal.util.Types._ import sbt.internal.util.Types._
@ -617,31 +618,42 @@ object Defaults extends BuildCommon {
s"inc_compile$extra.zip" s"inc_compile$extra.zip"
}, },
externalHooks := { externalHooks := {
import sbt.nio.FileStamp.Formats.seqPathFileStampJsonFormatter import sjsonnew.BasicJsonProtocol.mapFormat
val currentInputs = val currentInputs =
(unmanagedSources / inputFileStamps).value ++ (managedSourcePaths / outputFileStamps).value (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 val inputChanges = previousInputs
.map(sbt.nio.Settings.changedFiles(_, currentInputs)) .map(sbt.nio.Settings.changedFiles(_, currentInputs))
.getOrElse(FileChanges.noPrevious(currentInputs.map(_._1))) .getOrElse(FileChanges.noPrevious(currentInputs.map(_._1)))
val currentOutputs = (dependencyClasspathFiles / outputFileStamps).value val currentOutputs = (dependencyClasspathFiles / outputFileStamps).value
val previousOutputs = (externalHooks / outputFileStamps).previous val previousOutputs = compileBinaryFileInputs.previous.flatMap(_.get(sv))
val outputChanges = previousOutputs val outputChanges = previousOutputs
.map(sbt.nio.Settings.changedFiles(_, currentOutputs)) .map(sbt.nio.Settings.changedFiles(_, currentOutputs))
.getOrElse(FileChanges.noPrevious(currentOutputs.map(_._1))) .getOrElse(FileChanges.noPrevious(currentOutputs.map(_._1)))
ExternalHooks.default.value(inputChanges, outputChanges, fileTreeView.value) 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. 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, compileSourceFileInputs := compileSourceFileInputs.triggeredBy(compile).value,
externalHooks / outputFileStamps := { compileBinaryFileInputs := {
import sjsonnew.BasicJsonProtocol.mapFormat
compile.value // ensures the inputFileStamps previous value is only set if compile succeeds. 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 := compileBinaryFileInputs := compileBinaryFileInputs.triggeredBy(compile).value,
(externalHooks / outputFileStamps).triggeredBy(compile).value,
incOptions := { incOptions.value.withExternalHooks(externalHooks.value) }, incOptions := { incOptions.value.withExternalHooks(externalHooks.value) },
compileIncSetup := compileIncSetupTask.value, compileIncSetup := compileIncSetupTask.value,
console := consoleTask.value, console := consoleTask.value,

View File

@ -168,6 +168,12 @@ object Keys {
private[sbt] val classpathFiles = private[sbt] val classpathFiles =
taskKey[Seq[Path]]("The classpath for a task.").withRank(Invisible) taskKey[Seq[Path]]("The classpath for a task.").withRank(Invisible)
private[sbt] val compileOutputs = taskKey[Seq[Path]]("Compilation outputs").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 = private[this] val hasCheckedMetaBuildMsg =
"Indicates whether or not we have called the checkBuildSources task. This is to avoid warning " + "Indicates whether or not we have called the checkBuildSources task. This is to avoid warning " +

View File

@ -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")
}
}

View File

@ -0,0 +1,3 @@
object Stamps {
val value = new java.util.HashMap[java.io.File, Long]
}

View File

@ -0,0 +1,3 @@
object A {
def a = 1
}

View File

@ -0,0 +1,7 @@
> +compile
> setLastModified
> +compile
> checkLastModified

View File

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