Fix test-quick

This commit is contained in:
Adrien Piquerez 2024-04-04 12:28:52 +02:00
parent b0f3cb0a8e
commit 1c03463e19
4 changed files with 33 additions and 42 deletions

View File

@ -1427,40 +1427,35 @@ object Defaults extends BuildCommon {
Def.task { Def.task {
val cp = (test / fullClasspath).value val cp = (test / fullClasspath).value
val s = (test / streams).value val s = (test / streams).value
val ans: Seq[Analysis] = cp val analyses: Seq[Analysis] = cp
.flatMap(_.metadata.get(Keys.analysis)) .flatMap(_.metadata.get(Keys.analysis))
.map: str => .map: str =>
RemoteCache.getCachedAnalysis(str).asInstanceOf[Analysis] RemoteCache.getCachedAnalysis(str).asInstanceOf[Analysis]
val succeeded = TestStatus.read(succeededFile(s.cacheDirectory)) val succeeded = TestStatus.read(succeededFile(s.cacheDirectory))
val stamps = collection.mutable.Map.empty[String, Long] val stamps = collection.mutable.Map.empty[String, Long]
def stamp(dep: String): Long = { def stamp(dep: String): Option[Long] =
val stamps = for (a <- ans) yield intlStamp(dep, a, Set.empty) analyses.flatMap(internalStamp(dep, _, Set.empty)).maxOption
if (stamps.isEmpty) Long.MinValue def internalStamp(c: String, analysis: Analysis, alreadySeen: Set[String]): Option[Long] = {
else stamps.max if (alreadySeen.contains(c)) None
}
def intlStamp(c: String, analysis: Analysis, s: Set[String]): Long = {
if (s contains c) Long.MinValue
else else
stamps.getOrElse( def computeAndStoreStamp: Option[Long] = {
c, { import analysis.{ apis, relations }
val x = { val internalDeps = relations
import analysis.{ apis, relations } .internalClassDeps(c)
relations.internalClassDeps(c).map(intlStamp(_, analysis, s + c)) ++ .flatMap(internalStamp(_, analysis, alreadySeen + c))
relations.externalDeps(c).map(stamp) ++ val externalDeps = relations.externalDeps(c).flatMap(stamp)
relations.productClassName.reverse(c).flatMap { pc => val classStamps = relations.productClassName.reverse(c).flatMap { pc =>
apis.internal.get(pc).map(_.compilationTimestamp) apis.internal.get(pc).map(_.compilationTimestamp)
} + Long.MinValue
}.max
if (x != Long.MinValue) {
stamps(c) = x
}
x
} }
) val maxStamp = (internalDeps ++ externalDeps ++ classStamps).maxOption
maxStamp.foreach(maxStamp => stamps(c) = maxStamp)
maxStamp
}
stamps.get(c).orElse(computeAndStoreStamp)
} }
def noSuccessYet(test: String) = succeeded.get(test) match { def noSuccessYet(test: String) = succeeded.get(test) match {
case None => true case None => true
case Some(ts) => stamps.synchronized(stamp(test)) > ts case Some(ts) => stamps.synchronized(stamp(test)).exists(_ > ts)
} }
args => args =>
for (filter <- selectedFilter(args)) for (filter <- selectedFilter(args))

View File

@ -22,16 +22,10 @@ import sbt.ProjectExtra.*
import sbt.ScopeFilter.Make._ import sbt.ScopeFilter.Make._
import sbt.SlashSyntax0._ import sbt.SlashSyntax0._
import sbt.coursierint.LMCoursier import sbt.coursierint.LMCoursier
import sbt.internal.inc.{ import sbt.internal.inc.{ CompileOutput, HashUtil, JarUtils, MappedFileConverter }
CompileOutput,
FileAnalysisStore,
HashUtil,
JarUtils,
MappedFileConverter
}
import sbt.internal.librarymanagement._ import sbt.internal.librarymanagement._
import sbt.internal.remotecache._ import sbt.internal.remotecache._
import sbt.internal.inc.Analysis import sbt.internal.inc.{ Analysis, MixedAnalyzingCompiler }
import sbt.io.IO import sbt.io.IO
import sbt.io.syntax._ import sbt.io.syntax._
import sbt.librarymanagement._ import sbt.librarymanagement._
@ -50,7 +44,7 @@ import sbt.util.{
} }
import sjsonnew.JsonFormat import sjsonnew.JsonFormat
import xsbti.{ HashedVirtualFileRef, VirtualFileRef } import xsbti.{ HashedVirtualFileRef, VirtualFileRef }
import xsbti.compile.{ AnalysisContents, CompileAnalysis, MiniSetup, MiniOptions } import xsbti.compile.{ AnalysisContents, AnalysisStore, CompileAnalysis, MiniSetup, MiniOptions }
import scala.collection.mutable import scala.collection.mutable
@ -83,13 +77,10 @@ object RemoteCache {
private[sbt] def getCachedAnalysis(ref: HashedVirtualFileRef): CompileAnalysis = private[sbt] def getCachedAnalysis(ref: HashedVirtualFileRef): CompileAnalysis =
analysisStore.getOrElseUpdate( analysisStore.getOrElseUpdate(
ref, { ref, {
val vfs = cacheStore.getBlobs(ref :: Nil) val outputDirectory = Def.cacheConfiguration.outputDirectory
if vfs.nonEmpty then cacheStore.syncBlobs(ref :: Nil, outputDirectory).headOption match
val outputDirectory = Def.cacheConfiguration.outputDirectory case Some(file) => analysisStore(file).get.get.getAnalysis
cacheStore.syncBlobs(vfs, outputDirectory).headOption match case None => Analysis.empty
case Some(file) => FileAnalysisStore.binary(file.toFile()).get.get.getAnalysis
case None => Analysis.empty
else Analysis.empty
} }
) )
@ -106,7 +97,7 @@ object RemoteCache {
false, false,
Array() Array()
) )
FileAnalysisStore.binary(file).set(AnalysisContents.create(analysis, setup)) analysisStore(file.toPath).set(AnalysisContents.create(analysis, setup))
val vf = tempConverter.toVirtualFile(file.toPath) val vf = tempConverter.toVirtualFile(file.toPath)
val refs = cacheStore.putBlobs(vf :: Nil) val refs = cacheStore.putBlobs(vf :: Nil)
refs.headOption match refs.headOption match
@ -115,6 +106,9 @@ object RemoteCache {
Some(ref) Some(ref)
case None => None case None => None
private def analysisStore(file: Path): AnalysisStore =
MixedAnalyzingCompiler.staticCachedStore(file, true)
private[sbt] def artifactToStr(art: Artifact): String = { private[sbt] def artifactToStr(art: Artifact): String = {
import LibraryManagementCodec._ import LibraryManagementCodec._
import sjsonnew.support.scalajson.unsafe._ import sjsonnew.support.scalajson.unsafe._

View File

@ -1,3 +1,5 @@
Global / cacheStores := Seq.empty
val scalatest = "org.scalatest" %% "scalatest" % "3.0.5" val scalatest = "org.scalatest" %% "scalatest" % "3.0.5"
ThisBuild / scalaVersion := "2.12.12" ThisBuild / scalaVersion := "2.12.12"

View File

@ -9,7 +9,7 @@ $ copy-file changed/A.scala src/main/scala/A.scala
> compile > compile
$ sleep 2000 $ sleep 2000
# Create is run. Delete is not since it doesn't have src/main dependency. # Create is run. Delete is not since it doesn't have src/main dependency.
> testQuick -> testQuick
> testOnly Delete > testOnly Delete
# Previous run of Create failed, re-run. # Previous run of Create failed, re-run.
> testQuick Create > testQuick Create