mirror of https://github.com/sbt/sbt.git
[2.x] fix: Fixes cache invaliation on version change
**Problem** packageBin includes version into the file name, which ends up invalidating the cache. **Solution** Define packageInternal, which does not include version in the file name.
This commit is contained in:
parent
b76ac09d44
commit
7ef5a3b2d7
|
|
@ -112,6 +112,25 @@ private[librarymanagement] abstract class ArtifactFunctions {
|
|||
base + "-" + module.revision + classifierStr + "." + artifact.extension
|
||||
}
|
||||
|
||||
/**
|
||||
* Like `artifactName`, but omits the module's version.
|
||||
*/
|
||||
def internalArtifactName(
|
||||
scalaVersion: ScalaVersion,
|
||||
module: ModuleID,
|
||||
artifact: Artifact
|
||||
): String =
|
||||
import artifact.*
|
||||
val classifierStr = classifier match
|
||||
case None => ""
|
||||
case Some(c) => s"-${c}"
|
||||
val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary)
|
||||
val withPlatform = module.crossVersion match
|
||||
case _: Disabled => artifact.name
|
||||
case _ => CrossVersion.addPlatformSuffix(artifact.name, module.platformOpt, None)
|
||||
val base = CrossVersion.applyCross(withPlatform, cross)
|
||||
s"${base}${classifierStr}.${artifact.extension}"
|
||||
|
||||
val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType)
|
||||
@deprecated("Configuration should not be decided from the classifier.", "1.0")
|
||||
def classifierConf(classifier: String): Configuration =
|
||||
|
|
|
|||
|
|
@ -1770,6 +1770,8 @@ object Defaults extends BuildCommon with DefExtra {
|
|||
packageTaskSettings(packageBin, packageBinMappings) ++
|
||||
packageTaskSettings(packageSrc, packageSrcMappings) ++
|
||||
packageTaskSettings(packageDoc, packageDocMappings) ++
|
||||
packageTaskSettings(packageInternal, packageBinMappings) ++
|
||||
inTask(packageInternal)(Seq(artifactName :== Artifact.internalArtifactName)) ++
|
||||
Seq(Keys.`package` := packageBin.value)
|
||||
|
||||
def packageBinMappings: Initialize[Task[Seq[(HashedVirtualFileRef, String)]]] =
|
||||
|
|
|
|||
|
|
@ -324,6 +324,7 @@ object Keys {
|
|||
|
||||
// package keys
|
||||
val packageBin = taskKey[HashedVirtualFileRef]("Produces a main artifact, such as a binary jar.").withRank(ATask)
|
||||
val packageInternal = taskKey[HashedVirtualFileRef]("Produces a binary JAR for internal use (inter-project classpaths, BSP).").withRank(DTask)
|
||||
val `package` = taskKey[HashedVirtualFileRef]("Produces the main artifact, such as a binary jar. This is typically an alias for the task that actually does the packaging.").withRank(APlusTask)
|
||||
val packageDoc = taskKey[HashedVirtualFileRef]("Produces a documentation artifact, such as a jar containing API documentation.").withRank(AMinusTask)
|
||||
val packageSrc = taskKey[HashedVirtualFileRef]("Produces a source artifact, such as a jar containing sources and resources.").withRank(AMinusTask)
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ private[sbt] object ClasspathImpl {
|
|||
(Def
|
||||
.task {
|
||||
val converter = fileConverter.value
|
||||
val vf = (packageBin / artifactPath).value
|
||||
val vf = (packageInternal / artifactPath).value
|
||||
val jar = converter.toPath(vf)
|
||||
(TrackLevel.intersection(track, exportToInternal.value), vf, jar)
|
||||
})
|
||||
|
|
@ -141,13 +141,13 @@ private[sbt] object ClasspathImpl {
|
|||
Def.task {
|
||||
val converter = fileConverter.value
|
||||
val analysisFile = converter.toVirtualFile(compileAnalysisFile.value.toPath)
|
||||
Seq((packageBin.value, analysisFile))
|
||||
Seq((packageInternal.value, analysisFile))
|
||||
}
|
||||
case (TrackLevel.TrackIfMissing, _, jar) if !jar.toFile().exists =>
|
||||
Def.task {
|
||||
val converter = fileConverter.value
|
||||
val analysisFile = converter.toVirtualFile(compileAnalysisFile.value.toPath)
|
||||
Seq((packageBin.value, analysisFile))
|
||||
Seq((packageInternal.value, analysisFile))
|
||||
}
|
||||
case (_, vf, _) =>
|
||||
Def.task {
|
||||
|
|
|
|||
|
|
@ -824,7 +824,7 @@ object BuildServerProtocol {
|
|||
val internalDependencyClasspath = for {
|
||||
(ref, configs) <- bspInternalDependencyConfigurations.value
|
||||
config <- configs
|
||||
} yield ref / config / Keys.packageBin
|
||||
} yield ref / config / Keys.packageInternal
|
||||
(
|
||||
target,
|
||||
scalacOptions,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
package example
|
||||
|
||||
@main
|
||||
def main(args: String*): Unit =
|
||||
println(Foo.greeting)
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import sbt.internal.util.CacheEventSummary
|
||||
import complete.DefaultParsers.*
|
||||
|
||||
Global / localCacheDirectory := baseDirectory.value / "diskcache"
|
||||
|
||||
scalaVersion := "3.8.4"
|
||||
|
||||
lazy val checkMiss = inputKey[Unit]("Assert the exact onsite/miss count of the previous run")
|
||||
|
||||
lazy val foo = project
|
||||
|
||||
lazy val app = project.dependsOn(foo)
|
||||
|
||||
lazy val root = (project in file("."))
|
||||
.aggregate(foo, app)
|
||||
.settings(
|
||||
checkMiss := {
|
||||
val expected: Int = (Space ~> NatBasic).parsed
|
||||
val s = streams.value
|
||||
val config = Def.cacheConfiguration.value
|
||||
val prev = config.cacheEventLog.previous match
|
||||
case d: CacheEventSummary.Data => d
|
||||
case CacheEventSummary.Empty => sys.error("empty event log")
|
||||
s.log.info(s"missCount = ${prev.missCount}")
|
||||
assert(prev.missCount == expected, s"prev.missCount = ${prev.missCount} (expected $expected)")
|
||||
}
|
||||
)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package example
|
||||
|
||||
object Foo:
|
||||
def greeting: String = "hello"
|
||||
end Foo
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# warm the disk cache
|
||||
> app/compile
|
||||
|
||||
# after a clean, recompiling app (and foo) should fully restore from the disk cache
|
||||
> clean
|
||||
> app/compile
|
||||
> checkMiss 0
|
||||
|
||||
# bumping foo's version alone (e.g. what sbt-dynver would do on a new commit) must not
|
||||
# invalidate app's compile cache entry, since foo's jar content hasn't changed
|
||||
> set foo / version := "0.2.0"
|
||||
> clean
|
||||
> app/compile
|
||||
> checkMiss 0
|
||||
Loading…
Reference in New Issue