[2.0.x] Add VF keys (#8963)

**Problem**
java.io.File cannot participate in cached task.

**Solution**
This adds a few VF-equivalent keys so they can participate
in cached task.
This commit is contained in:
eugene yokota 2026-03-22 23:35:22 -04:00 committed by GitHub
parent 8f41553a32
commit ef9c5bfc9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 14 deletions

View File

@ -603,6 +603,11 @@ object Defaults extends BuildCommon {
.map(d => Globs(d.toPath, recursive = true, filter)) ++ baseSources .map(d => Globs(d.toPath, recursive = true, filter)) ++ baseSources
}, },
unmanagedSources := Def.uncached((unmanagedSources / inputFileStamps).value.map(_._1.toFile)), unmanagedSources := Def.uncached((unmanagedSources / inputFileStamps).value.map(_._1.toFile)),
unmanagedSourcesVF := Def.uncached {
val conv = fileConverter.value
unmanagedSources.value.toVector.map: x =>
(conv.toVirtualFile(x.toPath()): HashedVirtualFileRef)
},
managedSourceDirectories := Seq(sourceManaged.value), managedSourceDirectories := Seq(sourceManaged.value),
managedSources := { managedSources := {
val stamper = inputFileStamper.value val stamper = inputFileStamper.value
@ -613,13 +618,23 @@ object Defaults extends BuildCommon {
} }
Def.uncached(res) Def.uncached(res)
}, },
managedSourcesVF := Def.uncached {
val conv = fileConverter.value
managedSources.value.toVector.map: x =>
(conv.toVirtualFile(x.toPath()): HashedVirtualFileRef)
},
managedSourcePaths / outputFileStamper := sbt.nio.FileStamper.Hash, managedSourcePaths / outputFileStamper := sbt.nio.FileStamper.Hash,
managedSourcePaths := managedSources.value.map(_.toPath), managedSourcePaths := managedSources.value.map(_.toPath),
sourceGenerators :== Nil, sourceGenerators :== Nil,
sourceDirectories := Classpaths sourceDirectories := Classpaths
.concatSettings(unmanagedSourceDirectories, managedSourceDirectories) .concatSettings(unmanagedSourceDirectories, managedSourceDirectories)
.value, .value,
sources := Classpaths.concatDistinct(unmanagedSources, managedSources).value sources := Classpaths.concatDistinct(unmanagedSources, managedSources).value,
sourcesVF := Def.uncached {
val conv = fileConverter.value
sources.value.toVector.map: x =>
(conv.toVirtualFile(x.toPath()): HashedVirtualFileRef)
},
) )
lazy val resourceConfigPaths = Seq( lazy val resourceConfigPaths = Seq(
resourceDirectory := sourceDirectory.value / "resources", resourceDirectory := sourceDirectory.value / "resources",
@ -641,12 +656,25 @@ object Defaults extends BuildCommon {
unmanagedResources := Def.uncached( unmanagedResources := Def.uncached(
(unmanagedResources / inputFileStamps).value.map(_._1.toFile) (unmanagedResources / inputFileStamps).value.map(_._1.toFile)
), ),
unmanagedResourcesVF := Def.uncached {
val conv = fileConverter.value
unmanagedResources.value.toVector.map: x =>
(conv.toVirtualFile(x.toPath()): HashedVirtualFileRef)
},
resourceGenerators :== Nil, resourceGenerators :== Nil,
resourceGenerators += (Def.task { resourceGenerators += (Def.task {
PluginDiscovery.writeDescriptors(discoveredSbtPlugins.value, resourceManaged.value) PluginDiscovery.writeDescriptors(discoveredSbtPlugins.value, resourceManaged.value)
}).taskValue, }).taskValue,
managedResources := generate(resourceGenerators).value, managedResources := generate(resourceGenerators).value,
managedResourcesVF := Def.uncached {
val conv = fileConverter.value
managedResources.value.toVector.map: x =>
(conv.toVirtualFile(x.toPath()): HashedVirtualFileRef)
},
resources := Classpaths.concat(managedResources, unmanagedResources).value, resources := Classpaths.concat(managedResources, unmanagedResources).value,
resourcesVF := Def.uncached(
managedResourcesVF.value ++ unmanagedResourcesVF.value
),
resourceDigests := Def.uncached { resourceDigests := Def.uncached {
val uifs = (unmanagedResources / inputFileStamps).value val uifs = (unmanagedResources / inputFileStamps).value
val mifs = (managedResources / inputFileStamps).value val mifs = (managedResources / inputFileStamps).value
@ -976,6 +1004,11 @@ object Defaults extends BuildCommon {
tastyFiles.map(_.getAbsoluteFile) tastyFiles.map(_.getAbsoluteFile)
} else Nil } else Nil
}.value, }.value,
tastyFilesVF := Def.uncached {
val conv = fileConverter.value
tastyFiles.value.map: x =>
(conv.toVirtualFile(x.toPath()): HashedVirtualFileRef)
},
clean := { clean := {
(compileOutputs / clean).value (compileOutputs / clean).value
(products / clean).value (products / clean).value
@ -2118,7 +2151,12 @@ object Defaults extends BuildCommon {
case _ => () // do nothing case _ => () // do nothing
} }
out out
} },
(TaskZero / docVF) := Def.uncached {
val conv = fileConverter.value
val orig = (TaskZero / key).value
(conv.toVirtualFile(orig.toPath()): HashedVirtualFileRef)
},
) ++ compilersSetting ) ++ compilersSetting
) )
@ -2339,9 +2377,9 @@ object Defaults extends BuildCommon {
val cp0 = classpathTask.value val cp0 = classpathTask.value
val cp1 = backendOutput.value +: data(cp0) val cp1 = backendOutput.value +: data(cp0)
val cp = cp1.map(c.toPath).map(c.toVirtualFile) val cp = cp1.map(c.toPath).map(c.toVirtualFile)
val vs = sources.value.toVector map { x => val vs0 = sourcesVF.value
c.toVirtualFile(x.toPath) val vs = vs0.toVector.map: x =>
} c.toVirtualFile(c.toPath(x))
val eo = CompileOutput(c.toPath(earlyOutput.value)) val eo = CompileOutput(c.toPath(earlyOutput.value))
val eoOpt = val eoOpt =
if (exportPipelining.value) Some(eo) if (exportPipelining.value) Some(eo)
@ -2388,7 +2426,7 @@ object Defaults extends BuildCommon {
val c = fileConverter.value val c = fileConverter.value
CompileInputs2( CompileInputs2(
data(cp0).toVector, data(cp0).toVector,
inputs.options.sources.toVector, sourcesVF.value,
scalacOptions.value.toVector, scalacOptions.value.toVector,
javacOptions.value.toVector, javacOptions.value.toVector,
c.toVirtualFile(inputs.options.classesDirectory), c.toVirtualFile(inputs.options.classesDirectory),

View File

@ -158,12 +158,15 @@ object Keys {
val sourceDirectories = settingKey[Seq[File]]("List of all source directories, both managed and unmanaged.").withRank(AMinusSetting) val sourceDirectories = settingKey[Seq[File]]("List of all source directories, both managed and unmanaged.").withRank(AMinusSetting)
val unmanagedSourceDirectories = settingKey[Seq[File]]("Unmanaged source directories, which contain manually created sources.").withRank(ASetting) val unmanagedSourceDirectories = settingKey[Seq[File]]("Unmanaged source directories, which contain manually created sources.").withRank(ASetting)
@transient @transient
val unmanagedSources = taskKey[Seq[File]]("Unmanaged sources, which are manually created.").withRank(BPlusTask) val unmanagedSources = taskKey[Seq[File]]("Unmanaged sources, which are manually created.").withRank(DTask)
val unmanagedSourcesVF = taskKey[Vector[HashedVirtualFileRef]]("Unmanaged sources, which are manually created.").withRank(BPlusTask)
val managedSourceDirectories = settingKey[Seq[File]]("Managed source directories, which contain sources generated by the build.").withRank(BSetting) val managedSourceDirectories = settingKey[Seq[File]]("Managed source directories, which contain sources generated by the build.").withRank(BSetting)
@transient @transient
val managedSources = taskKey[Seq[File]]("Sources generated by the build.").withRank(BTask) val managedSources = taskKey[Seq[File]]("Sources generated by the build.").withRank(DTask)
val managedSourcesVF = taskKey[Vector[HashedVirtualFileRef]]("Sources generated by the build.").withRank(BTask)
@transient @transient
val sources = taskKey[Seq[File]]("All sources, both managed and unmanaged.").withRank(BTask) val sources = taskKey[Seq[File]]("All sources, both managed and unmanaged.").withRank(DTask)
val sourcesVF = taskKey[Vector[HashedVirtualFileRef]]("All sources, both managed and unmanaged.").withRank(BTask)
val sourcesInBase = settingKey[Boolean]("If true, sources from the project's base directory are included as main sources.") val sourcesInBase = settingKey[Boolean]("If true, sources from the project's base directory are included as main sources.")
// Filters // Filters
@ -175,13 +178,16 @@ object Keys {
val resourceManaged = settingKey[File]("Default managed resource directory, used when generating resources.").withRank(BSetting) val resourceManaged = settingKey[File]("Default managed resource directory, used when generating resources.").withRank(BSetting)
val unmanagedResourceDirectories = settingKey[Seq[File]]("Unmanaged resource directories, containing resources manually created by the user.").withRank(AMinusSetting) val unmanagedResourceDirectories = settingKey[Seq[File]]("Unmanaged resource directories, containing resources manually created by the user.").withRank(AMinusSetting)
@transient @transient
val unmanagedResources = taskKey[Seq[File]]("Unmanaged resources, which are manually created.").withRank(BPlusTask) val unmanagedResources = taskKey[Seq[File]]("Unmanaged resources, which are manually created.").withRank(DTask)
val unmanagedResourcesVF = taskKey[Vector[HashedVirtualFileRef]]("Unmanaged resources, which are manually created.").withRank(BPlusTask)
val managedResourceDirectories = settingKey[Seq[File]]("List of managed resource directories.").withRank(AMinusSetting) val managedResourceDirectories = settingKey[Seq[File]]("List of managed resource directories.").withRank(AMinusSetting)
@transient @transient
val managedResources = taskKey[Seq[File]]("Resources generated by the build.").withRank(BTask) val managedResources = taskKey[Seq[File]]("Resources generated by the build.").withRank(DTask)
val managedResourcesVF = taskKey[Vector[HashedVirtualFileRef]]("Resources generated by the build.").withRank(BTask)
val resourceDirectories = settingKey[Seq[File]]("List of all resource directories, both managed and unmanaged.").withRank(BPlusSetting) val resourceDirectories = settingKey[Seq[File]]("List of all resource directories, both managed and unmanaged.").withRank(BPlusSetting)
@transient @transient
val resources = taskKey[Seq[File]]("All resource files, both managed and unmanaged.").withRank(BTask) val resources = taskKey[Seq[File]]("All resource files, both managed and unmanaged.").withRank(DTask)
val resourcesVF = taskKey[Vector[HashedVirtualFileRef]]("All resource files, both managed and unmanaged.").withRank(BTask)
private[sbt] val resourceDigests = taskKey[Seq[Digest]]("All resource files, both managed and unmanaged.").withRank(BTask) private[sbt] val resourceDigests = taskKey[Seq[Digest]]("All resource files, both managed and unmanaged.").withRank(BTask)
// Output paths // Output paths
@ -265,6 +271,7 @@ object Keys {
val previousCompile = taskKey[PreviousResult]("Read the incremental compiler analysis from disk").withRank(DTask) val previousCompile = taskKey[PreviousResult]("Read the incremental compiler analysis from disk").withRank(DTask)
@transient @transient
val tastyFiles = taskKey[Seq[File]]("Returns the TASTy files produced by compilation").withRank(DTask) val tastyFiles = taskKey[Seq[File]]("Returns the TASTy files produced by compilation").withRank(DTask)
val tastyFilesVF = taskKey[Seq[HashedVirtualFileRef]]("Returns the TASTy files produced by compilation").withRank(DTask)
private[sbt] val compileScalaBackend = taskKey[CompileResult]("Compiles only Scala sources if pipelining is enabled. Compiles both Scala and Java sources otherwise").withRank(Invisible) private[sbt] val compileScalaBackend = taskKey[CompileResult]("Compiles only Scala sources if pipelining is enabled. Compiles both Scala and Java sources otherwise").withRank(Invisible)
private[sbt] val compileEarly = taskKey[CompileAnalysis]("Compiles only Scala sources if pipelining is enabled, and produce an early output (pickle JAR)").withRank(Invisible) private[sbt] val compileEarly = taskKey[CompileAnalysis]("Compiles only Scala sources if pipelining is enabled, and produce an early output (pickle JAR)").withRank(Invisible)
@ -294,6 +301,7 @@ object Keys {
val classpathEntryDefinesClassVF = taskKey[VirtualFile => DefinesClass]("Internal use: provides a function that determines whether the provided file contains a given class.").withRank(Invisible) val classpathEntryDefinesClassVF = taskKey[VirtualFile => DefinesClass]("Internal use: provides a function that determines whether the provided file contains a given class.").withRank(Invisible)
@transient @transient
val doc = taskKey[File]("Generates API documentation.").withRank(AMinusTask) val doc = taskKey[File]("Generates API documentation.").withRank(AMinusTask)
val docVF = taskKey[HashedVirtualFileRef]("Generates API documentation.").withRank(AMinusTask)
@transient @transient
val copyResources = taskKey[Seq[(File, File)]]("Copies resources to the output directory.").withRank(AMinusTask) val copyResources = taskKey[Seq[(File, File)]]("Copies resources to the output directory.").withRank(AMinusTask)
val aggregate = settingKey[Boolean]("Configures task aggregation.").withRank(BMinusSetting) val aggregate = settingKey[Boolean]("Configures task aggregation.").withRank(BMinusSetting)
@ -419,7 +427,7 @@ object Keys {
val defaultConfiguration = settingKey[Option[Configuration]]("Defines the configuration used when none is specified for a dependency in ivyXML.").withRank(CSetting) val defaultConfiguration = settingKey[Option[Configuration]]("Defines the configuration used when none is specified for a dependency in ivyXML.").withRank(CSetting)
@transient @transient
val products = taskKey[Seq[File]]("Build products that get packaged.").withRank(BMinusTask) val products = taskKey[Seq[File]]("Build products that get packaged.").withRank(DTask)
@transient @transient
val productDirectories = taskKey[Seq[File]]("Base directories of build products.").withRank(CTask) val productDirectories = taskKey[Seq[File]]("Base directories of build products.").withRank(CTask)
val exportJars = settingKey[Boolean]("Determines whether the exported classpath for this project contains classes (false) or a packaged jar (true).").withRank(BSetting) val exportJars = settingKey[Boolean]("Determines whether the exported classpath for this project contains classes (false) or a packaged jar (true).").withRank(BSetting)

View File

@ -1,5 +1,5 @@
-> compile -> compile
> 'set Compile / compile / sources := Def.uncached { val src = (Compile / compile / sources).value; src.filterNot(_.getName contains "C") }' > 'set Compile / compile / sourcesVF := { val src = (Compile / compile / sourcesVF).value; src.filterNot(_.name contains "C") }'
> compile > compile