[2.0.x] Remove Path type from caching (#9036)

**Problem**
Like File, Path normally captures the absolute path,
so likely not a good candidate for caching.

**Solution**
Ban it.

---------

Co-authored-by: Anatolii Kmetiuk <anatoliikmt@proton.me>
This commit is contained in:
eugene yokota 2026-04-06 23:10:27 -04:00 committed by GitHub
parent 91be1a2f7e
commit 542591ea20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 22 additions and 4 deletions

View File

@ -3,6 +3,8 @@ package internal
package util
package appmacro
import java.io.File
import java.nio.file.{ Path as NioPath }
import scala.collection.mutable.ListBuffer
import scala.reflect.ClassTag
import scala.quoted.*
@ -177,11 +179,11 @@ trait Cont:
val (expr, treeType) = eitherTree match
case Left(l) => (l, TypeRepr.of[Effect[A]])
case Right(r) => (r, faTpe)
val fileRepr = TypeRepr.of[File]
val pathRepr = TypeRepr.of[NioPath]
def containsFileType[A1: Type]: Boolean =
val fileRepr = TypeRepr.of[java.io.File]
def containsFile(tpe: TypeRepr): Boolean =
if tpe =:= fileRepr then true
if tpe =:= fileRepr || tpe =:= pathRepr then true
else
tpe.dealias match
case AppliedType(_, args) => args.exists(containsFile)
@ -354,7 +356,7 @@ trait Cont:
)(body: Expr[A1], input: Expr[A2]): Expr[A1] =
if containsFileType[A1] then
report.errorAndAbort(
s"""java.io.File is not a valid output type for a cached task.
s"""java.io.File and Path are not valid output types for a cached task.
|Consider using one of the following alternatives:
| - xsbti.HashedVirtualFileRef
| - xsbti.VirtualFileRef

View File

@ -28,8 +28,11 @@ object Keys {
case object IgnoreSourceChanges extends WatchBuildSourceOption
case object WarnOnSourceChanges extends WatchBuildSourceOption
case object ReloadOnSourceChanges extends WatchBuildSourceOption
@transient
val allInputFiles =
taskKey[Seq[Path]]("All of the file inputs for a task excluding directories and hidden files.")
@transient
val changedInputFiles =
taskKey[Seq[(Path, FileStamp)] => FileChanges]("The changed files for a task")
val fileInputs = settingKey[Seq[Glob]](
@ -50,8 +53,10 @@ object Keys {
settingKey[PathFilter]("A filter to apply to the outputs of a task.")
val fileOutputExcludeFilter =
settingKey[PathFilter]("An exclusion filter to apply to the outputs of a task.")
@transient
val allOutputFiles =
taskKey[Seq[Path]]("All of the file outputs for a task excluding directories and hidden files.")
@transient
val changedOutputFiles =
taskKey[Seq[(Path, FileStamp)] => FileChanges](
"The files that have changed since the last task run."
@ -158,9 +163,12 @@ object Keys {
private[sbt] val dynamicFileOutputs =
taskKey[Seq[Path]]("The outputs of a task").withRank(Invisible)
@transient
val inputFileStamps =
taskKey[Seq[(Path, FileStamp)]]("Retrieves the hashes for a set of task input files")
.withRank(Invisible)
@transient
val outputFileStamps =
taskKey[Seq[(Path, FileStamp)]]("Retrieves the hashes for a set of task output files")
.withRank(Invisible)
@ -181,9 +189,11 @@ object Keys {
private[sbt] val managedFileStampCache = taskKey[FileStamp.Cache](
"Map of managed file stamps that may be cleared between task evaluation runs."
).withRank(Invisible)
@transient
private[sbt] val managedSourcePaths =
taskKey[Seq[Path]]("Transforms the managedSources to Seq[Path] to induce setting injection.")
.withRank(Invisible)
@transient
private[sbt] val dependencyClasspathFiles =
taskKey[Seq[Path]]("The dependency classpath for a task.").withRank(Invisible)
private[sbt] val compileOutputs = taskKey[Seq[Path]]("Compilation outputs").withRank(Invisible)

View File

@ -1,6 +1,7 @@
import java.nio.file.{ Path, Paths }
import sbt.internal.FileChangesMacro.inputFiles
@transient
val foo = taskKey[Seq[Path]]("Copy files")
foo / fileInputs += baseDirectory.value.toGlob / "base" / "*.txt"
foo / target := baseDirectory.value / "out"

View File

@ -2,6 +2,7 @@ import java.nio.file.{ Files, Path }
import sbt.internal.FileChangesMacro.inputFiles
import sbt.internal.FileChangesMacro.outputFiles
@transient
val copyPaths = taskKey[Seq[Path]]("Copy paths")
copyPaths / fileInputs += baseDirectory.value.toGlob / "inputs" / *
copyPaths := {

View File

@ -1,5 +1,6 @@
import java.nio.file.{ Files, Path }
@transient
val outputTask = taskKey[Seq[Path]]("A task that generates outputs")
outputTask := {
val dir = Files.createDirectories(streams.value.cacheDirectory.toPath)

View File

@ -1,5 +1,6 @@
import java.nio.file.Path
@transient
val foo = taskKey[Path]("foo")
// Check a direct override
foo / outputFileStamps := Nil
@ -7,12 +8,14 @@ foo := baseDirectory.value.toPath / "foo.txt"
TaskKey[Unit]("checkFoo") := assert((foo / outputFileStamps).value == Nil)
@transient
val bar = taskKey[Path]("bar")
// Check an append
bar / outputFileStamps ++= (baz / outputFileStamps).value
bar / outputFileStamps ++= (baz / outputFileStamps).value
bar := baseDirectory.value.toPath / "bar.txt"
@transient
val baz = taskKey[Path]("baz")
baz := baseDirectory.value.toPath / "baz.txt"