Skip to content

Commit

Permalink
fix: Invalidate testQuick on resource file changes
Browse files Browse the repository at this point in the history
**Problem**
testQuick currently does not invalidate on resource file changes.

**Solution**
This includes resource digests into the input.
  • Loading branch information
eed3si9n committed Sep 15, 2024
1 parent 2cb36bc commit c13c25f
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 5 deletions.
9 changes: 8 additions & 1 deletion main/src/main/scala/sbt/Defaults.scala
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,14 @@ object Defaults extends BuildCommon {
PluginDiscovery.writeDescriptors(discoveredSbtPlugins.value, resourceManaged.value)
}).taskValue,
managedResources := generate(resourceGenerators).value,
resources := Classpaths.concat(managedResources, unmanagedResources).value
resources := Classpaths.concat(managedResources, unmanagedResources).value,
resourceDigests := {
val uifs = (unmanagedResources / inputFileStamps).value
val mifs = (managedResources / inputFileStamps).value
(uifs ++ mifs).sortBy(_._1.toString()).map { case (p, fileStamp) =>
FileStamp.toDigest(p, fileStamp)
}
},
)
// This exists for binary compatibility and probably never should have been public.
def addBaseSources: Seq[Def.Setting[Task[Seq[File]]]] = Nil
Expand Down
1 change: 1 addition & 0 deletions main/src/main/scala/sbt/Keys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ object Keys {
val managedResources = taskKey[Seq[File]]("Resources generated by the build.").withRank(BTask)
val resourceDirectories = settingKey[Seq[File]]("List of all resource directories, both managed and unmanaged.").withRank(BPlusSetting)
val resources = taskKey[Seq[File]]("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
@cacheLevel(include = Array.empty)
Expand Down
3 changes: 2 additions & 1 deletion main/src/main/scala/sbt/internal/IncrementalTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@ object IncrementalTest:
val cp = (Keys.test / fullClasspath).value
val testNames = Keys.definedTests.value.map(_.name).toVector.distinct
val converter = fileConverter.value
val rds = Keys.resourceDigests.value
val extra = Keys.extraTestDigests.value
val stamper = ClassStamper(cp, converter)
// TODO: Potentially do something about JUnit 5 and others which might not use class name
Map((testNames.flatMap: name =>
stamper.transitiveStamp(name, extra) match
stamper.transitiveStamp(name, extra ++ rds) match
case Some(ts) => Seq(name -> ts)
case None => Nil
): _*)
Expand Down
11 changes: 11 additions & 0 deletions main/src/main/scala/sbt/nio/FileStamp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import java.nio.file.{ Path, Paths }
import java.util.concurrent.ConcurrentHashMap

import sbt.internal.inc.{ EmptyStamp, Stamper, Hash => IncHash, LastModified => IncLastModified }
import sbt.internal.inc.JavaInterfaceUtil.given
import sbt.io.IO
import sbt.nio.file.FileAttributes
import sbt.util.Digest
import sjsonnew.{ Builder, JsonFormat, Unbuilder, deserializationError }
import xsbti.compile.analysis.{ Stamp => XStamp }
import xsbti.VirtualFileRef
Expand Down Expand Up @@ -103,6 +105,15 @@ object FileStamp {
private[sbt] final case class LastModified private[sbt] (time: Long) extends FileStamp
private[sbt] final case class Error(exception: IOException) extends FileStamp

def toDigest(path: Path, stamp: FileStamp): Digest = stamp match
case f: FileHashImpl =>
f.xstamp.getHash().toOption match
case Some(hash) => Digest.sha256Hash(hash.getBytes("UTF-8"))
case None => Digest.sha256Hash(path)
case FileStamp.Hash(hex) => Digest.sha256Hash(hex.getBytes("UTF-8"))
case FileStamp.Error(_) => Digest.zero
case FileStamp.LastModified(_) => Digest.sha256Hash(path)

object Formats {
implicit val seqPathJsonFormatter: JsonFormat[Seq[Path]] =
asStringArray(_.toString, Paths.get(_))
Expand Down
6 changes: 3 additions & 3 deletions sbt-app/src/sbt-test/classloader-cache/resources/test
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ $ copy-file changes/updated-main.txt src/main/resources/foo.txt

> run foo.txt updated-main

> test
> testQuick

$ copy-file changes/updated-test.txt src/test/resources/bar.txt

-> test
-> testQuick

$ copy-file changes/UpdatedResourceTest.scala src/test/scala/scripted/ResourceTest.scala

> test
> testQuick

0 comments on commit c13c25f

Please sign in to comment.