[2.x] Add VF keys

**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-17 01:54:45 -04:00
parent ed501b71bd
commit 5a767e3442
3 changed files with 60 additions and 14 deletions

View File

@ -601,6 +601,11 @@ object Defaults extends BuildCommon with DefExtra {
.map(d => Globs(d.toPath, recursive = true, filter)) ++ baseSources
},
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),
managedSources := {
val stamper = inputFileStamper.value
@ -611,13 +616,23 @@ object Defaults extends BuildCommon with DefExtra {
}
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 := managedSources.value.map(_.toPath),
sourceGenerators :== Nil,
sourceDirectories := Classpaths
.concatSettings(unmanagedSourceDirectories, managedSourceDirectories)
.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(
resourceDirectory := sourceDirectory.value / "resources",
@ -639,12 +654,25 @@ object Defaults extends BuildCommon with DefExtra {
unmanagedResources := Def.uncached(
(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 += (Def.task {
PluginDiscovery.writeDescriptors(discoveredSbtPlugins.value, resourceManaged.value)
}).taskValue,
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,
resourcesVF := Def.uncached(
managedResourcesVF.value ++ unmanagedResourcesVF.value
),
resourceDigests := Def.uncached {
val uifs = (unmanagedResources / inputFileStamps).value
val mifs = (managedResources / inputFileStamps).value
@ -953,6 +981,11 @@ object Defaults extends BuildCommon with DefExtra {
tastyFiles.map(_.getAbsoluteFile)
} else Nil
}.value,
tastyFilesVF := Def.uncached {
val conv = fileConverter.value
tastyFiles.value.map: x =>
(conv.toVirtualFile(x.toPath()): HashedVirtualFileRef)
},
clean := {
(compileOutputs / clean).value
(products / clean).value
@ -2042,7 +2075,12 @@ object Defaults extends BuildCommon with DefExtra {
Seq("-project", project)
} else Seq.empty
},
(TaskZero / key) := Def.uncached(Compiler.docTask(key).value)
(TaskZero / key) := Def.uncached(Compiler.docTask(key).value),
(TaskZero / docVF) := Def.uncached {
val conv = fileConverter.value
val orig = (TaskZero / key).value
(conv.toVirtualFile(orig.toPath()): HashedVirtualFileRef)
},
) ++ compilersSetting
)
@ -2274,9 +2312,9 @@ object Defaults extends BuildCommon with DefExtra {
val cp0 = classpathTask.value
val cp1 = backendOutput.value +: data(cp0)
val cp = cp1.map(c.toPath).map(c.toVirtualFile)
val vs = sources.value.toVector map { x =>
c.toVirtualFile(x.toPath)
}
val vs0 = sourcesVF.value
val vs = vs0.toVector.map: x =>
c.toVirtualFile(c.toPath(x))
val eo = CompileOutput(c.toPath(earlyOutput.value))
val eoOpt =
if (exportPipelining.value) Some(eo)
@ -2323,7 +2361,7 @@ object Defaults extends BuildCommon with DefExtra {
val c = fileConverter.value
CompileInputs2(
data(cp0).toVector,
inputs.options.sources.toVector,
sourcesVF.value,
scalacOptions.value.toVector,
javacOptions.value.toVector,
c.toVirtualFile(inputs.options.classesDirectory),

View File

@ -155,12 +155,15 @@ object Keys {
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)
@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)
@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
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.")
// Filters
@ -172,13 +175,16 @@ object Keys {
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)
@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)
@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)
@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)
// Output paths
@ -262,6 +268,7 @@ object Keys {
val previousCompile = taskKey[PreviousResult]("Read the incremental compiler analysis from disk").withRank(DTask)
@transient
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 compileEarly = taskKey[CompileAnalysis]("Compiles only Scala sources if pipelining is enabled, and produce an early output (pickle JAR)").withRank(Invisible)
@ -291,6 +298,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)
@transient
val doc = taskKey[File]("Generates API documentation.").withRank(AMinusTask)
val docVF = taskKey[HashedVirtualFileRef]("Generates API documentation.").withRank(AMinusTask)
@transient
val copyResources = taskKey[Seq[(File, File)]]("Copies resources to the output directory.").withRank(AMinusTask)
val aggregate = settingKey[Boolean]("Configures task aggregation.").withRank(BMinusSetting)
@ -416,7 +424,7 @@ object Keys {
val defaultConfiguration = settingKey[Option[Configuration]]("Defines the configuration used when none is specified for a dependency in ivyXML.").withRank(CSetting)
@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
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)

View File

@ -1,5 +1,5 @@
-> 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