Default to cached task

This flips the default `:=` operation to the cached task.
To opt out of the cache, use `Def.uncached(...)` or
mark the key with `@cacheLevel(include = Array.empty)`
This commit is contained in:
Eugene Yokota 2025-06-09 02:04:42 -04:00
parent 580c357124
commit 6a7b56a645
103 changed files with 781 additions and 503 deletions

View File

@ -94,17 +94,25 @@ trait Cont:
import conv.qctx import conv.qctx
import qctx.reflect.* import qctx.reflect.*
given qctx.type = qctx given qctx.type = qctx
def msg: String =
s"given evidence sjsonnew.HashWriter[${TypeRepr.of[A].show}] is not found; " +
"opt out of caching by annotating the key with @cacheLevel(include = Array.empty), or as" +
"foo := Def.uncached(...), or provide a given value"
Expr Expr
.summon[HashWriter[A]] .summon[HashWriter[A]]
.getOrElse(sys.error(s"HashWriter[A] not found for ${TypeRepr.of[A].show}")) .getOrElse(report.errorAndAbort(msg))
def summonJsonFormat[A: Type]: Expr[JsonFormat[A]] = def summonJsonFormat[A: Type]: Expr[JsonFormat[A]] =
import conv.qctx import conv.qctx
import qctx.reflect.* import qctx.reflect.*
given qctx.type = qctx given qctx.type = qctx
def msg: String =
s"given evidence sjsonnew.JsonFormat[${TypeRepr.of[A].show}] is not found; " +
"opt out of caching by annotating the key with @cacheLevel(include = Array.empty), or as" +
"foo := Def.uncached(...), or provide a given value"
Expr Expr
.summon[JsonFormat[A]] .summon[JsonFormat[A]]
.getOrElse(sys.error(s"JsonFormat[A] not found for ${TypeRepr.of[A].show}")) .getOrElse(report.errorAndAbort(msg))
def summonClassTag[A: Type]: Expr[ClassTag[A]] = def summonClassTag[A: Type]: Expr[ClassTag[A]] =
import conv.qctx import conv.qctx
@ -112,7 +120,7 @@ trait Cont:
given qctx.type = qctx given qctx.type = qctx
Expr Expr
.summon[ClassTag[A]] .summon[ClassTag[A]]
.getOrElse(sys.error(s"ClassTag[A] not found for ${TypeRepr.of[A].show}")) .getOrElse(report.errorAndAbort(s"ClassTag[A] not found for ${TypeRepr.of[A].show}"))
/** /**
* Implementation of a macro that provides a direct syntax for applicative functors and monads. * Implementation of a macro that provides a direct syntax for applicative functors and monads.
@ -334,7 +342,11 @@ trait Cont:
cacheConfigExpr: Expr[BuildWideCacheConfiguration], cacheConfigExpr: Expr[BuildWideCacheConfiguration],
tags: List[CacheLevelTag], tags: List[CacheLevelTag],
)(body: Expr[A1], input: Expr[A2]): Expr[A1] = )(body: Expr[A1], input: Expr[A2]): Expr[A1] =
val codeContentHash = Expr[Long](body.show.##) val codeContentHash =
try Expr[Long](body.show.##)
catch
case e: Throwable =>
Expr[Long](Printer.TreeStructure.show(body.asTerm).##)
val extraHash = Expr[Long](0L) val extraHash = Expr[Long](0L)
val aJsonFormat = summonJsonFormat[A1] val aJsonFormat = summonJsonFormat[A1]
val aClassTag = summonClassTag[A1] val aClassTag = summonClassTag[A1]

View File

@ -102,6 +102,28 @@ trait ContextUtil[C <: Quotes & scala.Singleton](val valStart: Int):
case Apply(_, List(arg)) => extractTags(arg) case Apply(_, List(arg)) => extractTags(arg)
case _ => extractTags0(tree) case _ => extractTags0(tree)
def cacheLevels(tree: Term): Seq[CacheLevelTag] =
tree.underlying match
// handles foo / bar cases
case Apply(TypeApply(_, _), List(t @ Ident(_))) =>
t.symbol.getAnnotation(cacheLevelSym) match
case Some(_) => cacheLevelsForSym(t.symbol)
case None => CacheLevelTag.all.toList
case u =>
u.symbol.getAnnotation(cacheLevelSym) match
case Some(_) => cacheLevelsForSym(u.symbol)
case None => CacheLevelTag.all.toList
def cacheLevelsForSym(sym: Symbol): Seq[CacheLevelTag] =
sym.getAnnotation(cacheLevelSym) match
case Some(annot) =>
annot.asExprOf[cacheLevel] match
case '{ cacheLevel(include = Array.empty[CacheLevelTag](using $_)) } => Nil
case '{ cacheLevel(include = Array[CacheLevelTag]($include*)) } =>
include.value.get
case _ => report.errorAndAbort(Printer.TreeStructure.show(annot) + " does not match")
case None => CacheLevelTag.all.toList
enum OutputType: enum OutputType:
case File case File
case Directory case Directory
@ -178,5 +200,15 @@ end ContextUtil
object ContextUtil: object ContextUtil:
def appendScalacOptions(options: Seq[String]): Unit = def appendScalacOptions(options: Seq[String]): Unit =
Attic.appendItems(options.asJava); Attic.appendItems(options.asJava)
def isTaskCacheByDefault: Boolean =
val atticValues = Attic.getItems().asScala.toSet
val noDefaultMacroSetting = atticValues.contains("-Xmacro-settings:sbt:no-default-task-cache")
!noDefaultMacroSetting
end ContextUtil end ContextUtil
class ContextUtil0[C <: Quotes & scala.Singleton](override val qctx: C, valStart: Int)
extends ContextUtil[C](valStart):
// import qctx.reflect.*
end ContextUtil0

View File

@ -20,7 +20,8 @@ import sbt.util.{
AggregateActionCacheStore, AggregateActionCacheStore,
BuildWideCacheConfiguration, BuildWideCacheConfiguration,
cacheLevel, cacheLevel,
DiskActionCacheStore DiskActionCacheStore,
Uncached,
} }
import Util.* import Util.*
import sbt.util.Show import sbt.util.Show
@ -301,6 +302,9 @@ object Def extends BuildSyntax with Init with InitializeImplicits:
inline def cachedTask[A1](inline a1: A1): Def.Initialize[Task[A1]] = inline def cachedTask[A1](inline a1: A1): Def.Initialize[Task[A1]] =
${ TaskMacro.taskMacroImpl[A1]('a1, cached = true) } ${ TaskMacro.taskMacroImpl[A1]('a1, cached = true) }
inline def uncachedTask[A1](inline a1: A1): Def.Initialize[Task[A1]] =
${ TaskMacro.taskMacroImpl[A1]('a1, cached = false) }
inline def task[A1](inline a1: A1): Def.Initialize[Task[A1]] = inline def task[A1](inline a1: A1): Def.Initialize[Task[A1]] =
${ TaskMacro.taskMacroImpl[A1]('a1, cached = false) } ${ TaskMacro.taskMacroImpl[A1]('a1, cached = false) }
@ -465,6 +469,11 @@ object Def extends BuildSyntax with Init with InitializeImplicits:
private[sbt] def isDummy(t: Task[?]): Boolean = private[sbt] def isDummy(t: Task[?]): Boolean =
t.get(isDummyTask).getOrElse(false) t.get(isDummyTask).getOrElse(false)
/**
* Marker function to make the task uncached.
*/
inline def uncached[A1](inline a: A1): A1 = Uncached(a)
end Def end Def
sealed trait InitializeImplicits { self: Def.type => sealed trait InitializeImplicits { self: Def.type =>

View File

@ -157,6 +157,9 @@ sealed abstract class TaskKey[A1]
private[sbt] final inline def rescope(scope: Scope): TaskKey[A1] = private[sbt] final inline def rescope(scope: Scope): TaskKey[A1] =
Scoped.scopedTask(Scope.replaceThis(this.scope)(scope), this.key) Scoped.scopedTask(Scope.replaceThis(this.scope)(scope), this.key)
/**
* Appends a single value to the task key.
*/
inline def +=[A2](inline v: A2)(using Append.Value[A1, A2]): Setting[Task[A1]] = inline def +=[A2](inline v: A2)(using Append.Value[A1, A2]): Setting[Task[A1]] =
append1[A2](taskMacro(v)) append1[A2](taskMacro(v))
@ -165,6 +168,9 @@ sealed abstract class TaskKey[A1]
): Setting[Task[A1]] = ): Setting[Task[A1]] =
make(v)(ev.appendValue) make(v)(ev.appendValue)
/**
* Appends a sequence of values to the task key.
*/
inline def ++=[A2](inline vs: A2)(using Append.Values[A1, A2]): Setting[Task[A1]] = inline def ++=[A2](inline vs: A2)(using Append.Values[A1, A2]): Setting[Task[A1]] =
appendN(taskMacro[A2](vs)) appendN(taskMacro[A2](vs))
@ -427,8 +433,8 @@ object Scoped:
sealed trait DefinableTask[A1] { self: TaskKey[A1] => sealed trait DefinableTask[A1] { self: TaskKey[A1] =>
/** Internal function for the task macro. */ /** Internal function for the task macro. */
inline def taskMacro[A](inline a: A): Initialize[Task[A]] = inline def taskMacro[A2](inline a: A2): Initialize[Task[A2]] =
${ TaskMacro.taskMacroImpl[A]('a, cached = false) } ${ TaskMacro.taskMacroImpl[A2]('a, 'this) }
private[sbt] inline def :==(app: A1): Setting[Task[A1]] = private[sbt] inline def :==(app: A1): Setting[Task[A1]] =
set(Def.valueStrict(std.TaskExtra.constant(app))) set(Def.valueStrict(std.TaskExtra.constant(app)))

View File

@ -15,10 +15,9 @@ import sbt.internal.util.appmacro.{
Cont, Cont,
// Instance, // Instance,
// LinterDSL, // LinterDSL,
// MixedBuilder, ContextUtil,
// MonadInstance ContextUtil0,
} }
// import Instance.Transform
import sbt.internal.util.{ LinePosition, NoPosition, SourcePosition } import sbt.internal.util.{ LinePosition, NoPosition, SourcePosition }
import language.experimental.macros import language.experimental.macros
@ -49,6 +48,42 @@ object TaskMacro:
// import LinterDSL.{ Empty => EmptyLinter } // import LinterDSL.{ Empty => EmptyLinter }
def taskMacroImpl[A1: Type](t: Expr[A1], key: Expr[TaskKey[?]])(using
qctx: Quotes
): Expr[Initialize[Task[A1]]] =
import qctx.reflect.*
var isUncacheApplied = false
object appTransformer extends TreeMap:
override def transformTerm(tree: Term)(owner: Symbol): Term =
tree match
case Apply(TypeApply(s @ Select(Ident("Uncached"), "apply"), targ :: Nil), qual :: Nil)
if "sbt.util.Uncached$.apply" == s.symbol.fullName =>
isUncacheApplied = true
super.transformTerm(tree)(owner)
case _ =>
super.transformTerm(tree)(owner)
end appTransformer
val _ = appTransformer.transformTerm(t.asTerm)(Symbol.spliceOwner)
val cu0 = ContextUtil0(qctx, 0)
val cl = cu0.cacheLevels(key.asTerm)
val cached = ContextUtil.isTaskCacheByDefault && !isUncacheApplied && cl.nonEmpty
t match
case '{ if ($cond) then $thenp else $elsep } => taskIfImpl[A1](t, cached)
case _ =>
val convert1 = new FullConvert(qctx, 0)
if cached then
convert1.contMapN[A1, F, Id](
t,
convert1.appExpr,
Some('{
InputWrapper.`wrapInitTask_\u2603\u2603`[BuildWideCacheConfiguration](
Def.cacheConfiguration
)
})
)
else convert1.contMapN[A1, F, Id](t, convert1.appExpr, None)
def taskMacroImpl[A1: Type](t: Expr[A1], cached: Boolean)(using def taskMacroImpl[A1: Type](t: Expr[A1], cached: Boolean)(using
qctx: Quotes qctx: Quotes
): Expr[Initialize[Task[A1]]] = ): Expr[Initialize[Task[A1]]] =

View File

@ -10,6 +10,7 @@ package sbt.test
import java.io.File import java.io.File
import sjsonnew.* import sjsonnew.*
import sbt.Def
import sbt.Def.{ Setting, inputKey, settingKey, taskKey } import sbt.Def.{ Setting, inputKey, settingKey, taskKey }
import sbt.Scope.Global import sbt.Scope.Global
import sbt.ScopeAxis.Zero import sbt.ScopeAxis.Zero
@ -56,7 +57,7 @@ object SlashSyntaxTest extends sbt.SlashSyntax {
Compile / bar := { Compile / bar := {
(Compile / foo).previous.getOrElse(2) (Compile / foo).previous.getOrElse(2)
}, },
Test / buildInfo := Nil, Test / buildInfo := Def.uncached(Nil),
baz := { baz := {
val _ = (Test / buildInfo).taskValue val _ = (Test / buildInfo).taskValue
(Compile / run).evaluated (Compile / run).evaluated

View File

@ -73,7 +73,7 @@ object Assign {
// ak += z.value + (if (y.value) set.value else plain.value), // ak += z.value + (if (y.value) set.value else plain.value),
ck := new File(ck.value, "asdf"), ck := new File(ck.value, "asdf"),
ak := sk.value.size, ak := Def.uncached(sk.value.size),
// bk ++= Seq(z.value) // bk ++= Seq(z.value)
intTask := ak.previous.get, intTask := ak.previous.get,
bgList := { mk.value.toString.toList.map(_.toInt) }, bgList := { mk.value.toString.toList.map(_.toInt) },

View File

@ -399,12 +399,12 @@ object Cross {
val scope = Scope(Select(project), Zero, Zero, Zero) val scope = Scope(Select(project), Zero, Zero, Zero)
instance match { instance match {
case Some((home, inst)) => case Some((home, inst1)) =>
Seq( Seq(
scope / scalaVersion := version, scope / scalaVersion := version,
scope / crossScalaVersions := scalaVersions, scope / crossScalaVersions := scalaVersions,
scope / scalaHome := Some(home), scope / scalaHome := Some(home),
scope / scalaInstance := inst, scope / scalaInstance := Def.uncached(inst1),
) )
case None => case None =>
Seq( Seq(

View File

@ -70,6 +70,7 @@ import sbt.librarymanagement.CrossVersion.{ binarySbtVersion, binaryScalaVersion
import sbt.librarymanagement.* import sbt.librarymanagement.*
import sbt.librarymanagement.ivy.* import sbt.librarymanagement.ivy.*
import sbt.librarymanagement.syntax.* import sbt.librarymanagement.syntax.*
import sbt.librarymanagement.LibraryManagementCodec.given
import sbt.nio.FileStamp import sbt.nio.FileStamp
import sbt.nio.Keys.* import sbt.nio.Keys.*
import sbt.nio.file.syntax.* import sbt.nio.file.syntax.*
@ -166,24 +167,27 @@ object Defaults extends BuildCommon {
outputFileStamper :== sbt.nio.FileStamper.LastModified, outputFileStamper :== sbt.nio.FileStamper.LastModified,
onChangedBuildSource :== SysProp.onChangedBuildSource, onChangedBuildSource :== SysProp.onChangedBuildSource,
clean := { () }, clean := { () },
unmanagedFileStampCache := unmanagedFileStampCache := Def.uncached(
state.value.get(persistentFileStampCache).getOrElse(new sbt.nio.FileStamp.Cache), state.value.get(persistentFileStampCache).getOrElse(new sbt.nio.FileStamp.Cache)
managedFileStampCache := new sbt.nio.FileStamp.Cache, ),
managedFileStampCache := Def.uncached(new sbt.nio.FileStamp.Cache),
) ++ globalIvyCore ++ globalJvmCore ++ Watch.defaults ) ++ globalIvyCore ++ globalJvmCore ++ Watch.defaults
) ++ globalSbtCore ) ++ globalSbtCore
private[sbt] lazy val globalJvmCore: Seq[Setting[?]] = private[sbt] lazy val globalJvmCore: Seq[Setting[?]] =
Seq( Seq(
compilerCache := state.value compilerCache := Def.uncached(
state.value
.get(Keys.stateCompilerCache) .get(Keys.stateCompilerCache)
.getOrElse(CompilerCache.fresh), .getOrElse(CompilerCache.fresh)
),
sourcesInBase :== true, sourcesInBase :== true,
autoAPIMappings := false, autoAPIMappings := false,
apiMappings := Map.empty, apiMappings := Map.empty,
autoScalaLibrary :== true, autoScalaLibrary :== true,
managedScalaInstance :== true, managedScalaInstance :== true,
allowUnsafeScalaLibUpgrade :== false, allowUnsafeScalaLibUpgrade :== false,
classpathEntryDefinesClass := { (file: File) => classpathEntryDefinesClass := Def.uncached { (file: File) =>
sys.error("use classpathEntryDefinesClassVF instead") sys.error("use classpathEntryDefinesClassVF instead")
}, },
extraIncOptions :== Seq("JAVA_CLASS_VERSION" -> sys.props("java.class.version")), extraIncOptions :== Seq("JAVA_CLASS_VERSION" -> sys.props("java.class.version")),
@ -216,8 +220,8 @@ object Defaults extends BuildCommon {
unmanagedSources / includeFilter :== ("*.java" | "*.scala"), unmanagedSources / includeFilter :== ("*.java" | "*.scala"),
unmanagedJars / includeFilter :== "*.jar" | "*.so" | "*.dll" | "*.jnilib" | "*.zip", unmanagedJars / includeFilter :== "*.jar" | "*.so" | "*.dll" | "*.jnilib" | "*.zip",
unmanagedResources / includeFilter :== AllPassFilter, unmanagedResources / includeFilter :== AllPassFilter,
bgList := { bgJobService.value.jobs }, bgList := Def.uncached { bgJobService.value.jobs },
ps := psTask.value, ps := Def.uncached(psTask.value),
bgStop := bgStopTask.evaluated, bgStop := bgStopTask.evaluated,
bgWaitFor := bgWaitForTask.evaluated, bgWaitFor := bgWaitForTask.evaluated,
bgCopyClasspath :== true, bgCopyClasspath :== true,
@ -285,7 +289,7 @@ object Defaults extends BuildCommon {
platform :== Platform.jvm, platform :== Platform.jvm,
// coursier settings // coursier settings
csrExtraCredentials :== Nil, csrExtraCredentials :== Nil,
csrLogger := LMCoursier.coursierLoggerTask.value, csrLogger := Def.uncached(LMCoursier.coursierLoggerTask.value),
csrMavenProfiles :== Set.empty, csrMavenProfiles :== Set.empty,
csrReconciliations :== LMCoursier.relaxedForAllModules, csrReconciliations :== LMCoursier.relaxedForAllModules,
csrMavenDependencyOverride :== false, csrMavenDependencyOverride :== false,
@ -309,14 +313,14 @@ object Defaults extends BuildCommon {
private[sbt] lazy val globalSbtCore: Seq[Setting[?]] = globalDefaults( private[sbt] lazy val globalSbtCore: Seq[Setting[?]] = globalDefaults(
Seq( Seq(
outputStrategy :== None, // TODO - This might belong elsewhere. outputStrategy :== None, // TODO - This might belong elsewhere.
buildStructure := Project.structure(state.value), buildStructure := Def.uncached(Project.structure(state.value)),
settingsData := buildStructure.value.data, settingsData := Def.uncached(buildStructure.value.data),
allScopes := ScopeFilter.allScopes.value, allScopes := ScopeFilter.allScopes.value,
checkBuildSources / aggregate :== false, checkBuildSources / aggregate :== false,
checkBuildSources / changedInputFiles / aggregate := false, checkBuildSources / changedInputFiles / aggregate := false,
checkBuildSources / Continuous.dynamicInputs := None, checkBuildSources / Continuous.dynamicInputs := Def.uncached(None),
checkBuildSources / fileInputs := CheckBuildSources.buildSourceFileInputs.value, checkBuildSources / fileInputs := CheckBuildSources.buildSourceFileInputs.value,
checkBuildSources := CheckBuildSources.needReloadImpl.value, checkBuildSources := Def.uncached(CheckBuildSources.needReloadImpl.value),
fileCacheSize := "128M", fileCacheSize := "128M",
trapExit :== true, trapExit :== true,
connectInput :== false, connectInput :== false,
@ -374,15 +378,17 @@ object Defaults extends BuildCommon {
commandProgress := Seq(), commandProgress := Seq(),
// progressState is deprecated // progressState is deprecated
SettingKey[Option[ProgressState]]("progressState") := None, SettingKey[Option[ProgressState]]("progressState") := None,
Previous.cache := new Previous( Previous.cache := Def.uncached(
new Previous(
Def.streamsManagerKey.value, Def.streamsManagerKey.value,
Previous.references.value.getReferences Previous.references.value.getReferences
)
), ),
Previous.references :== new Previous.References, Previous.references :== new Previous.References,
concurrentRestrictions := defaultRestrictions.value, concurrentRestrictions := defaultRestrictions.value,
parallelExecution :== true, parallelExecution :== true,
fileTreeView :== FileTreeView.default, fileTreeView :== FileTreeView.default,
Continuous.dynamicInputs := Continuous.dynamicInputsImpl.value, Continuous.dynamicInputs := Def.uncached(Continuous.dynamicInputsImpl.value),
logBuffered :== false, logBuffered :== false,
commands :== Nil, commands :== Nil,
showSuccess :== true, showSuccess :== true,
@ -423,7 +429,7 @@ object Defaults extends BuildCommon {
pollInterval :== Watch.defaultPollInterval, pollInterval :== Watch.defaultPollInterval,
canonicalInput :== true, canonicalInput :== true,
echoInput :== true, echoInput :== true,
terminal := state.value.get(terminalKey).getOrElse(Terminal(ITerminal.get)), terminal := Def.uncached(state.value.get(terminalKey).getOrElse(Terminal(ITerminal.get))),
InstallSbtn.installSbtn := InstallSbtn.installSbtnImpl.evaluated, InstallSbtn.installSbtn := InstallSbtn.installSbtnImpl.evaluated,
InstallSbtn.installSbtn / aggregate := false, InstallSbtn.installSbtn / aggregate := false,
) ++ LintUnused.lintSettings ) ++ LintUnused.lintSettings
@ -433,7 +439,9 @@ object Defaults extends BuildCommon {
private[sbt] lazy val buildLevelJvmSettings: Seq[Setting[?]] = Seq( private[sbt] lazy val buildLevelJvmSettings: Seq[Setting[?]] = Seq(
exportPipelining := usePipelining.value, exportPipelining := usePipelining.value,
sourcePositionMappers := Nil, // Never set a default sourcePositionMapper, see #6352! Whatever you are trying to solve, do it in the foldMappers method. sourcePositionMappers := Def.uncached(
Nil
), // Never set a default sourcePositionMapper, see #6352! Whatever you are trying to solve, do it in the foldMappers method.
// The virtual file value cache needs to be global or sbt will run out of direct byte buffer memory. // The virtual file value cache needs to be global or sbt will run out of direct byte buffer memory.
classpathDefinesClassCache := VirtualFileValueCache.definesClassCache(fileConverter.value), classpathDefinesClassCache := VirtualFileValueCache.definesClassCache(fileConverter.value),
fullServerHandlers := { fullServerHandlers := {
@ -451,7 +459,7 @@ object Defaults extends BuildCommon {
}, },
timeWrappedStamper := Stamps timeWrappedStamper := Stamps
.timeWrapBinaryStamps(Stamps.uncachedStamps(fileConverter.value), fileConverter.value), .timeWrapBinaryStamps(Stamps.uncachedStamps(fileConverter.value), fileConverter.value),
reusableStamper := { reusableStamper := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val unmanagedCache = unmanagedFileStampCache.value val unmanagedCache = unmanagedFileStampCache.value
val managedCache = managedFileStampCache.value val managedCache = managedFileStampCache.value
@ -604,7 +612,7 @@ object Defaults extends BuildCommon {
unmanagedSourceDirectories.value unmanagedSourceDirectories.value
.map(d => Globs(d.toPath, recursive = true, filter)) ++ baseSources .map(d => Globs(d.toPath, recursive = true, filter)) ++ baseSources
}, },
unmanagedSources := (unmanagedSources / inputFileStamps).value.map(_._1.toFile), unmanagedSources := Def.uncached((unmanagedSources / inputFileStamps).value.map(_._1.toFile)),
managedSourceDirectories := Seq(sourceManaged.value), managedSourceDirectories := Seq(sourceManaged.value),
managedSources := { managedSources := {
val stamper = inputFileStamper.value val stamper = inputFileStamper.value
@ -613,7 +621,7 @@ object Defaults extends BuildCommon {
res.foreach { f => res.foreach { f =>
cache.putIfAbsent(f.toPath, stamper) cache.putIfAbsent(f.toPath, stamper)
} }
res Def.uncached(res)
}, },
managedSourcePaths / outputFileStamper := sbt.nio.FileStamper.Hash, managedSourcePaths / outputFileStamper := sbt.nio.FileStamper.Hash,
managedSourcePaths := managedSources.value.map(_.toPath), managedSourcePaths := managedSources.value.map(_.toPath),
@ -640,14 +648,16 @@ object Defaults extends BuildCommon {
} }
unmanagedResourceDirectories.value.map(d => Globs(d.toPath, recursive = true, filter)) unmanagedResourceDirectories.value.map(d => Globs(d.toPath, recursive = true, filter))
}, },
unmanagedResources := (unmanagedResources / inputFileStamps).value.map(_._1.toFile), unmanagedResources := Def.uncached(
(unmanagedResources / inputFileStamps).value.map(_._1.toFile)
),
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,
resources := Classpaths.concat(managedResources, unmanagedResources).value, resources := Classpaths.concat(managedResources, unmanagedResources).value,
resourceDigests := { resourceDigests := Def.uncached {
val uifs = (unmanagedResources / inputFileStamps).value val uifs = (unmanagedResources / inputFileStamps).value
val mifs = (managedResources / inputFileStamps).value val mifs = (managedResources / inputFileStamps).value
(uifs ++ mifs).sortBy(_._1.toString()).map { (p, fileStamp) => (uifs ++ mifs).sortBy(_._1.toString()).map { (p, fileStamp) =>
@ -694,7 +704,7 @@ object Defaults extends BuildCommon {
} }
else topLoader else topLoader
}, },
scalaInstance := Compiler.scalaInstanceTask.value, scalaInstance := Def.uncached(Compiler.scalaInstanceTask.value),
crossVersion := (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled), crossVersion := (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled),
pluginCrossBuild / sbtBinaryVersion := binarySbtVersion( pluginCrossBuild / sbtBinaryVersion := binarySbtVersion(
(pluginCrossBuild / sbtVersion).value (pluginCrossBuild / sbtVersion).value
@ -732,7 +742,7 @@ object Defaults extends BuildCommon {
} }
clean.value clean.value
}, },
scalaCompilerBridgeBinaryJar := { scalaCompilerBridgeBinaryJar := Def.uncached {
val sv = scalaVersion.value val sv = scalaVersion.value
val managed = managedScalaInstance.value val managed = managedScalaInstance.value
val hasSbtBridge = ScalaArtifacts.isScala3(sv) || ZincLmUtil.hasScala2SbtBridge(sv) val hasSbtBridge = ScalaArtifacts.isScala3(sv) || ZincLmUtil.hasScala2SbtBridge(sv)
@ -752,7 +762,7 @@ object Defaults extends BuildCommon {
if (ScalaArtifacts.isScala3(scalaVersion.value)) List(TastyFiles.instance) if (ScalaArtifacts.isScala3(scalaVersion.value)) List(TastyFiles.instance)
else Nil else Nil
}, },
consoleProject / scalaCompilerBridgeBinaryJar := None, consoleProject / scalaCompilerBridgeBinaryJar := Def.uncached(None),
consoleProject / scalaCompilerBridgeSource := ZincLmUtil.getDefaultBridgeSourceModule( consoleProject / scalaCompilerBridgeSource := ZincLmUtil.getDefaultBridgeSourceModule(
appConfiguration.value.provider.scalaProvider.version appConfiguration.value.provider.scalaProvider.version
), ),
@ -762,7 +772,7 @@ object Defaults extends BuildCommon {
private lazy val compileBaseGlobal: Seq[Setting[?]] = globalDefaults( private lazy val compileBaseGlobal: Seq[Setting[?]] = globalDefaults(
Seq( Seq(
auxiliaryClassFiles :== Nil, auxiliaryClassFiles :== Nil,
incOptions := IncOptions.of(), incOptions := Def.uncached(IncOptions.of()),
compileOrder :== CompileOrder.Mixed, compileOrder :== CompileOrder.Mixed,
javacOptions :== Nil, javacOptions :== Nil,
scalacOptions :== Nil, scalacOptions :== Nil,
@ -829,7 +839,7 @@ object Defaults extends BuildCommon {
} }
def compilersSetting = { def compilersSetting = {
compilers := { compilers := Def.uncached {
val st = state.value val st = state.value
val g = BuildPaths.getGlobalBase(st) val g = BuildPaths.getGlobalBase(st)
val zincDir = BuildPaths.getZincDirectory(st, g) val zincDir = BuildPaths.getZincDirectory(st, g)
@ -882,11 +892,11 @@ object Defaults extends BuildCommon {
inTask(compile)(compileInputsSettings) ++ inTask(compile)(compileInputsSettings) ++
inTask(compileJava)( inTask(compileJava)(
Seq( Seq(
compileInputs := { compileInputs := Def.uncached {
val opts = (compileJava / compileOptions).value val opts = (compileJava / compileOptions).value
(compile / compileInputs).value.withOptions(opts) (compile / compileInputs).value.withOptions(opts)
}, },
compileOptions := { compileOptions := Def.uncached {
val opts = (compile / compileOptions).value val opts = (compile / compileOptions).value
val cp0 = dependencyClasspath.value val cp0 = dependencyClasspath.value
val cp1 = backendOutput.value +: data(cp0) val cp1 = backendOutput.value +: data(cp0)
@ -897,7 +907,7 @@ object Defaults extends BuildCommon {
) )
) ++ ) ++
configGlobal ++ compileAnalysisSettings ++ Seq( configGlobal ++ compileAnalysisSettings ++ Seq(
compileOutputs := { compileOutputs := Def.uncached {
import scala.jdk.CollectionConverters.* import scala.jdk.CollectionConverters.*
val c = fileConverter.value val c = fileConverter.value
val (_, vfDir, packedDir) = compileIncremental.value val (_, vfDir, packedDir) = compileIncremental.value
@ -907,7 +917,7 @@ object Defaults extends BuildCommon {
c.toPath(vfDir) :+ c.toPath(vfDir) :+
c.toPath(packedDir) c.toPath(packedDir)
}, },
compileOutputs := compileOutputs.triggeredBy(compile).value, compileOutputs := Def.uncached(compileOutputs.triggeredBy(compile).value),
tastyFiles := Def.taskIf { tastyFiles := Def.taskIf {
if (ScalaArtifacts.isScala3(scalaVersion.value)) { if (ScalaArtifacts.isScala3(scalaVersion.value)) {
val _ = compile.value val _ = compile.value
@ -921,8 +931,8 @@ object Defaults extends BuildCommon {
(compileOutputs / clean).value (compileOutputs / clean).value
(products / clean).value (products / clean).value
}, },
earlyOutputPing := Def.promise[Boolean], earlyOutputPing := Def.uncached(Def.promise[Boolean]),
compileProgress := { compileProgress := Def.uncached {
val s = streams.value val s = streams.value
val promise = earlyOutputPing.value val promise = earlyOutputPing.value
val mn = moduleName.value val mn = moduleName.value
@ -935,19 +945,19 @@ object Defaults extends BuildCommon {
} }
} }
}, },
compileEarly := compileEarlyTask.value, compileEarly := Def.uncached(compileEarlyTask.value),
compile := compileTask.value, compile := Def.uncached(compileTask.value),
compileScalaBackend := compileScalaBackendTask.value, compileScalaBackend := Def.uncached(compileScalaBackendTask.value),
compileJava := compileJavaTask.value, compileJava := Def.uncached(compileJavaTask.value),
compileSplit := { compileSplit := {
// conditional task // conditional task
if (incOptions.value.pipelining) compileJava.value if (incOptions.value.pipelining) Def.uncached(compileJava.value)
else compileScalaBackend.value else Def.uncached(compileScalaBackend.value)
}, },
internalDependencyConfigurations := InternalDependencies.configurations.value, internalDependencyConfigurations := InternalDependencies.configurations.value,
manipulateBytecode := compileSplit.value, manipulateBytecode := Def.uncached(compileSplit.value),
printWarnings := printWarningsTask.value, printWarnings := printWarningsTask.value,
compileAnalysisFilename := { compileAnalysisFilename := Def.uncached {
// Here, if the user wants cross-scala-versioning, we also append it // Here, if the user wants cross-scala-versioning, we also append it
// to the analysis cache, so we keep the scala versions separated. // to the analysis cache, so we keep the scala versions separated.
val binVersion = scalaBinaryVersion.value val binVersion = scalaBinaryVersion.value
@ -962,9 +972,9 @@ object Defaults extends BuildCommon {
compileAnalysisFile := { compileAnalysisFile := {
compileAnalysisTargetRoot.value / compileAnalysisFilename.value compileAnalysisTargetRoot.value / compileAnalysisFilename.value
}, },
externalHooks := IncOptions.defaultExternal, externalHooks := Def.uncached(IncOptions.defaultExternal),
zincCompilationListeners := Seq.empty, zincCompilationListeners := Seq.empty,
incOptions := { incOptions := Def.uncached {
val old = incOptions.value val old = incOptions.value
val extHooks = externalHooks.value val extHooks = externalHooks.value
val newExtHooks = extHooks.withInvalidationProfiler(() => val newExtHooks = extHooks.withInvalidationProfiler(() =>
@ -988,21 +998,23 @@ object Defaults extends BuildCommon {
val old = scalacOptions.value val old = scalacOptions.value
val converter = fileConverter.value val converter = fileConverter.value
if (exportPipelining.value) if (exportPipelining.value)
Def.uncached(
Vector( Vector(
"-Ypickle-java", "-Ypickle-java",
"-Ypickle-write", "-Ypickle-write",
earlyOutput.value.toString earlyOutput.value.toString
) ++ old ) ++ old
else old )
else Def.uncached(old)
}, },
persistJarClasspath :== true, persistJarClasspath :== true,
classpathEntryDefinesClassVF := { classpathEntryDefinesClassVF := Def.uncached {
val cache = val cache =
if persistJarClasspath.value then classpathDefinesClassCache.value if persistJarClasspath.value then classpathDefinesClassCache.value
else VirtualFileValueCache.definesClassCache(fileConverter.value) else VirtualFileValueCache.definesClassCache(fileConverter.value)
cache.get cache.get
}, },
compileIncSetup := compileIncSetupTask.value, compileIncSetup := Def.uncached(compileIncSetupTask.value),
console := consoleTask.value, console := consoleTask.value,
collectAnalyses := Definition.collectAnalysesTask.map(_ => ()).value, collectAnalyses := Definition.collectAnalysesTask.map(_ => ()).value,
consoleQuick := consoleQuickTask.value, consoleQuick := consoleQuickTask.value,
@ -1011,12 +1023,12 @@ object Defaults extends BuildCommon {
.storeAs(discoveredMainClasses) .storeAs(discoveredMainClasses)
.triggeredBy(compile) .triggeredBy(compile)
.value, .value,
discoveredSbtPlugins := discoverSbtPluginNames.value, discoveredSbtPlugins := Def.uncached(discoverSbtPluginNames.value),
// This fork options, scoped to the configuration is used for tests // This fork options, scoped to the configuration is used for tests
forkOptions := forkOptionsTask.value, forkOptions := Def.uncached(forkOptionsTask.value),
selectMainClass := mainClass.value orElse askForMainClass(discoveredMainClasses.value), selectMainClass := mainClass.value orElse askForMainClass(discoveredMainClasses.value),
run / mainClass := (run / selectMainClass).value, run / mainClass := (run / selectMainClass).value,
mainClass := { mainClass := Def.uncached {
val logWarning = state.value.currentCommand.forall(!_.commandLine.split(" ").exists { val logWarning = state.value.currentCommand.forall(!_.commandLine.split(" ").exists {
case "run" | "runMain" => true case "run" | "runMain" => true
case r => case r =>
@ -1052,7 +1064,7 @@ object Defaults extends BuildCommon {
// clean := Def.taskDyn(Clean.task(resolvedScoped.value.scope, full = true)).value, // clean := Def.taskDyn(Clean.task(resolvedScoped.value.scope, full = true)).value,
clean := Clean.scopedTask.value, clean := Clean.scopedTask.value,
consoleProject := consoleProjectTask.value, consoleProject := consoleProjectTask.value,
transitiveDynamicInputs := WatchTransitiveDependencies.task.value, transitiveDynamicInputs := Def.uncached(WatchTransitiveDependencies.task.value),
) )
def generate(generators: SettingKey[Seq[Task[Seq[File]]]]): Initialize[Task[Seq[File]]] = def generate(generators: SettingKey[Seq[Task[Seq[File]]]]): Initialize[Task[Seq[File]]] =
@ -1080,7 +1092,7 @@ object Defaults extends BuildCommon {
testFrameworks :== sbt.TestFrameworks.All, testFrameworks :== sbt.TestFrameworks.All,
testListeners :== Nil, testListeners :== Nil,
testOptions :== Nil, testOptions :== Nil,
testOptionDigests := Nil, testOptionDigests :== Nil,
testResultLogger :== TestResultLogger.Default, testResultLogger :== TestResultLogger.Default,
testOnly / testFilter :== (IncrementalTest.selectedFilter), testOnly / testFilter :== (IncrementalTest.selectedFilter),
extraTestDigests :== Nil, extraTestDigests :== Nil,
@ -1091,13 +1103,13 @@ object Defaults extends BuildCommon {
testTaskOptions(testOnly), testTaskOptions(testOnly),
testTaskOptions(testQuick), testTaskOptions(testQuick),
testDefaults, testDefaults,
testLoader := ClassLoaders.testTask.value, testLoader := Def.uncached(ClassLoaders.testTask.value),
loadedTestFrameworks := { loadedTestFrameworks := Def.uncached {
val loader = testLoader.value val loader = testLoader.value
val log = streams.value.log val log = streams.value.log
testFrameworks.value.flatMap(f => f.create(loader, log).map(x => (f, x))).toMap testFrameworks.value.flatMap(f => f.create(loader, log).map(x => (f, x))).toMap
}, },
definedTests := detectTests.value, definedTests := Def.uncached(detectTests.value),
definedTestNames := definedTests definedTestNames := definedTests
.map(_.map(_.name).distinct) .map(_.map(_.name).distinct)
.storeAs(definedTestNames) .storeAs(definedTestNames)
@ -1106,9 +1118,9 @@ object Defaults extends BuildCommon {
definedTestDigests := IncrementalTest.definedTestDigestTask definedTestDigests := IncrementalTest.definedTestDigestTask
.triggeredBy(compile) .triggeredBy(compile)
.value, .value,
testQuick / testFilter := IncrementalTest.filterTask.value, testQuick / testFilter := Def.uncached(IncrementalTest.filterTask.value),
extraTestDigests ++= IncrementalTest.extraTestDigestsTask.value, extraTestDigests ++= IncrementalTest.extraTestDigestsTask.value,
executeTests := { executeTests := Def.uncached({
import sbt.TupleSyntax.* import sbt.TupleSyntax.*
( (
test / streams, test / streams,
@ -1137,10 +1149,10 @@ object Defaults extends BuildCommon {
c, c,
) )
} }
}.value, }.value),
// ((streams in test, loadedTestFrameworks, testLoader, testGrouping in test, testExecution in test, fullClasspath in test, javaHome in test, testForkedParallel, javaOptions in test) flatMap allTestGroupsTask).value, // ((streams in test, loadedTestFrameworks, testLoader, testGrouping in test, testExecution in test, fullClasspath in test, javaHome in test, testForkedParallel, javaOptions in test) flatMap allTestGroupsTask).value,
Test / testFull / testResultLogger :== TestResultLogger.SilentWhenNoTests, // https://github.com/sbt/sbt/issues/1185 Test / testFull / testResultLogger :== TestResultLogger.SilentWhenNoTests, // https://github.com/sbt/sbt/issues/1185
testFull := { testFull := Def.uncached {
val trl = (Test / testFull / testResultLogger).value val trl = (Test / testFull / testResultLogger).value
val taskName = Project.showContextKey(state.value).show(resolvedScoped.value) val taskName = Project.showContextKey(state.value).show(resolvedScoped.value)
try trl.run(streams.value.log, executeTests.value, taskName) try trl.run(streams.value.log, executeTests.value, taskName)
@ -1175,7 +1187,7 @@ object Defaults extends BuildCommon {
def testTaskOptions(key: Scoped): Seq[Setting[?]] = def testTaskOptions(key: Scoped): Seq[Setting[?]] =
inTask(key)( inTask(key)(
Seq( Seq(
testListeners := { testListeners := Def.uncached {
val stateLogLevel = state.value.get(Keys.logLevel.key).getOrElse(Level.Info) val stateLogLevel = state.value.get(Keys.logLevel.key).getOrElse(Level.Info)
TestLogger.make( TestLogger.make(
streams.value.log, streams.value.log,
@ -1192,8 +1204,11 @@ object Defaults extends BuildCommon {
) +: ) +:
(TaskZero / testListeners).value (TaskZero / testListeners).value
}, },
testOptions := Tests.Listeners(testListeners.value) +: (TaskZero / testOptions).value, testOptions := Def.uncached(
testOptionDigests := { Tests.Listeners(testListeners.value) +: (TaskZero / testOptions).value
),
// This needs to be uncached since testOptions is uncahed.
testOptionDigests := Def.uncached {
(TaskZero / testOptions).value.flatMap { (TaskZero / testOptions).value.flatMap {
case Tests.Setup(_, digest) => Seq(digest) case Tests.Setup(_, digest) => Seq(digest)
case Tests.Cleanup(_, digest) => Seq(digest) case Tests.Cleanup(_, digest) => Seq(digest)
@ -1206,11 +1221,11 @@ object Defaults extends BuildCommon {
case _ => Nil case _ => Nil
} }
}, },
testExecution := testExecutionTask(key).value testExecution := Def.uncached(testExecutionTask(key).value),
) )
) ++ inScope(GlobalScope)( ) ++ inScope(GlobalScope)(
Seq( Seq(
derive(testGrouping := singleTestGroupDefault.value) derive(testGrouping := Def.uncached(singleTestGroupDefault.value))
) )
) )
@ -1741,7 +1756,7 @@ object Defaults extends BuildCommon {
(TaskZero / key) := packageTask.value, (TaskZero / key) := packageTask.value,
packageConfiguration := packageConfigurationTask.value, packageConfiguration := packageConfigurationTask.value,
mappings := mappingsTask.value, mappings := mappingsTask.value,
packagedArtifact := artifact.value -> key.value, packagedArtifact := Def.uncached(artifact.value -> key.value),
artifact := artifactSetting.value, artifact := artifactSetting.value,
artifactPath := artifactPathSetting(artifact).value artifactPath := artifactPathSetting(artifact).value
) )
@ -1837,7 +1852,8 @@ object Defaults extends BuildCommon {
scalaRun: Initialize[Task[ScalaRun]] scalaRun: Initialize[Task[ScalaRun]]
): Initialize[InputTask[Unit]] = RunUtil.serverSideRunTask(classpath, mainClassTask, scalaRun) ): Initialize[InputTask[Unit]] = RunUtil.serverSideRunTask(classpath, mainClassTask, scalaRun)
def runnerTask: Setting[Task[ScalaRun]] = runner := runnerInit.value def runnerTask: Setting[Task[ScalaRun]] =
runner := Def.uncached(runnerInit.value)
def runnerInit: Initialize[Task[ScalaRun]] = Def.task { def runnerInit: Initialize[Task[ScalaRun]] = Def.task {
val tmp = taskTemporaryDirectory.value val tmp = taskTemporaryDirectory.value
@ -1930,7 +1946,7 @@ object Defaults extends BuildCommon {
} }
} else compileOptions } else compileOptions
}, },
(TaskZero / key) := { (TaskZero / key) := Def.uncached {
val s = streams.value val s = streams.value
val cs: Compilers = compilers.value val cs: Compilers = compilers.value
val srcs = sources.value val srcs = sources.value
@ -2103,16 +2119,16 @@ object Defaults extends BuildCommon {
def compileIncrementalTaskSettings = inTask(compileIncremental)( def compileIncrementalTaskSettings = inTask(compileIncremental)(
Seq( Seq(
(TaskZero / compileIncremental) := { TaskZero / compileIncremental := Def.uncached {
val bspTask = (compile / bspCompileTask).value val bspTask = (compile / bspCompileTask).value
val result = cachedCompileIncrementalTask.result.value val result = cachedCompileIncrementalTask.result.value
val reporter = (compile / bspReporter).value val reporter = (compile / bspReporter).value
val store = analysisStore(compileAnalysisFile)
val ci = (compile / compileInputs).value val ci = (compile / compileInputs).value
val c = fileConverter.value val c = fileConverter.value
val dir = c.toPath(backendOutput.value).toFile val dir = c.toPath(backendOutput.value).toFile
result match result match
case Result.Value(res) => case Result.Value(res) =>
val store = analysisStore(compileAnalysisFile)
val analysis = store.unsafeGet().getAnalysis() val analysis = store.unsafeGet().getAnalysis()
reporter.sendSuccessReport(analysis) reporter.sendSuccessReport(analysis)
bspTask.notifySuccess(analysis) bspTask.notifySuccess(analysis)
@ -2238,7 +2254,7 @@ object Defaults extends BuildCommon {
compileInputsSettings(dependencyPicklePath) compileInputsSettings(dependencyPicklePath)
def compileInputsSettings(classpathTask: TaskKey[Classpath]): Seq[Setting[?]] = { def compileInputsSettings(classpathTask: TaskKey[Classpath]): Seq[Setting[?]] = {
Seq( Seq(
compileOptions := { compileOptions := Def.uncached {
val c = fileConverter.value val c = fileConverter.value
val cp0 = classpathTask.value val cp0 = classpathTask.value
val cp1 = backendOutput.value +: data(cp0) val cp1 = backendOutput.value +: data(cp0)
@ -2267,14 +2283,14 @@ object Defaults extends BuildCommon {
eoOpt.toOptional, eoOpt.toOptional,
) )
}, },
compilerReporter := { compilerReporter := Def.uncached {
new ManagedLoggedReporter( new ManagedLoggedReporter(
maxErrors.value, maxErrors.value,
streams.value.log, streams.value.log,
foldMappers(sourcePositionMappers.value, reportAbsolutePath.value, fileConverter.value) foldMappers(sourcePositionMappers.value, reportAbsolutePath.value, fileConverter.value)
) )
}, },
compileInputs := { compileInputs := Def.uncached {
val options = compileOptions.value val options = compileOptions.value
val setup = compileIncSetup.value val setup = compileIncSetup.value
val prev = previousCompile.value val prev = previousCompile.value
@ -2286,7 +2302,7 @@ object Defaults extends BuildCommon {
) )
}, },
// todo: Zinc's hashing should automatically handle directories // todo: Zinc's hashing should automatically handle directories
compileInputs2 := { compileInputs2 := Def.uncached {
val cp0 = classpathTask.value val cp0 = classpathTask.value
val inputs = compileInputs.value val inputs = compileInputs.value
val c = fileConverter.value val c = fileConverter.value
@ -2300,6 +2316,7 @@ object Defaults extends BuildCommon {
) )
}, },
bspCompileTask := bspCompileTask :=
Def.uncached(
BspCompileTask.start( BspCompileTask.start(
bspTargetIdentifier.value, bspTargetIdentifier.value,
thisProjectRef.value, thisProjectRef.value,
@ -2307,6 +2324,7 @@ object Defaults extends BuildCommon {
compileInputs.value compileInputs.value
) )
) )
)
} }
private[sbt] def foldMappers( private[sbt] def foldMappers(
@ -2330,7 +2348,7 @@ object Defaults extends BuildCommon {
private[sbt] def none[A]: Option[A] = (None: Option[A]) private[sbt] def none[A]: Option[A] = (None: Option[A])
private[sbt] def jnone[A]: Optional[A] = none[A].toOptional private[sbt] def jnone[A]: Optional[A] = none[A].toOptional
def compileAnalysisSettings: Seq[Setting[?]] = Seq( def compileAnalysisSettings: Seq[Setting[?]] = Seq(
previousCompile := { previousCompile := Def.uncached {
val setup = compileIncSetup.value val setup = compileIncSetup.value
val store = analysisStore(compileAnalysisFile) val store = analysisStore(compileAnalysisFile)
val prev = store.get().toOption match { val prev = store.get().toOption match {
@ -2442,9 +2460,13 @@ object Defaults extends BuildCommon {
// 1. runnerSettings is added unscoped via JvmPlugin. // 1. runnerSettings is added unscoped via JvmPlugin.
// 2. In addition it's added scoped to run task. // 2. In addition it's added scoped to run task.
lazy val runnerSettings: Seq[Setting[?]] = Seq(runnerTask, forkOptions := forkOptionsTask.value) lazy val runnerSettings: Seq[Setting[?]] =
Seq(runnerTask, forkOptions := Def.uncached(forkOptionsTask.value))
private lazy val newRunnerSettings: Seq[Setting[?]] = private lazy val newRunnerSettings: Seq[Setting[?]] =
Seq(runner := ClassLoaders.runner.value, forkOptions := forkOptionsTask.value) Seq(
runner := Def.uncached(ClassLoaders.runner.value),
forkOptions := Def.uncached(forkOptionsTask.value)
)
lazy val baseTasks: Seq[Setting[?]] = projectTasks ++ packageBase lazy val baseTasks: Seq[Setting[?]] = projectTasks ++ packageBase
@ -2551,23 +2573,25 @@ object Classpaths {
// Included as part of JvmPlugin#projectSettings. // Included as part of JvmPlugin#projectSettings.
lazy val configSettings: Seq[Setting[?]] = classpaths ++ Seq( lazy val configSettings: Seq[Setting[?]] = classpaths ++ Seq(
products := makeProducts.value, products := makeProducts.value,
pickleProducts := makePickleProducts.value, pickleProducts := Def.uncached(makePickleProducts.value),
productDirectories := classDirectory.value :: Nil, productDirectories := classDirectory.value :: Nil,
classpathConfiguration := findClasspathConfig( classpathConfiguration := Def.uncached(
findClasspathConfig(
internalConfigurationMap.value, internalConfigurationMap.value,
configuration.value, configuration.value,
classpathConfiguration.?.value, classpathConfiguration.?.value,
update.value update.value
) )
) )
)
private def classpaths: Seq[Setting[?]] = private def classpaths: Seq[Setting[?]] =
Seq( Seq(
externalDependencyClasspath := concat(unmanagedClasspath, managedClasspath).value, externalDependencyClasspath := concat(unmanagedClasspath, managedClasspath).value,
dependencyClasspath := concat(internalDependencyClasspath, externalDependencyClasspath).value, dependencyClasspath := concat(internalDependencyClasspath, externalDependencyClasspath).value,
fullClasspath := concatDistinct(exportedProducts, dependencyClasspath).value, fullClasspath := concatDistinct(exportedProducts, dependencyClasspath).value,
internalDependencyClasspath := ClasspathImpl.internalDependencyClasspathTask.value, internalDependencyClasspath := ClasspathImpl.internalDependencyClasspathTask.value,
unmanagedClasspath := ClasspathImpl.unmanagedDependenciesTask.value, unmanagedClasspath := Def.uncached(ClasspathImpl.unmanagedDependenciesTask.value),
managedClasspath := { managedClasspath := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val isMeta = isMetaBuild.value val isMeta = isMetaBuild.value
val force = reresolveSbtArtifacts.value val force = reresolveSbtArtifacts.value
@ -2601,21 +2625,27 @@ object Classpaths {
exportedProductJarsNoTracking := ClasspathImpl exportedProductJarsNoTracking := ClasspathImpl
.trackedExportedJarProducts(TrackLevel.NoTracking) .trackedExportedJarProducts(TrackLevel.NoTracking)
.value, .value,
internalDependencyAsJars := internalDependencyJarsTask.value, internalDependencyAsJars := Def.uncached(internalDependencyJarsTask.value),
dependencyClasspathAsJars := concat( dependencyClasspathAsJars := Def.uncached(
concat(
internalDependencyAsJars, internalDependencyAsJars,
externalDependencyClasspath externalDependencyClasspath
).value, ).value
fullClasspathAsJars := concatDistinct(exportedProductJars, dependencyClasspathAsJars).value, ),
unmanagedJars := findUnmanagedJars( fullClasspathAsJars := Def.uncached(
concatDistinct(exportedProductJars, dependencyClasspathAsJars).value
),
unmanagedJars := Def.uncached(
findUnmanagedJars(
configuration.value, configuration.value,
unmanagedBase.value, unmanagedBase.value,
(unmanagedJars / includeFilter).value, (unmanagedJars / includeFilter).value,
(unmanagedJars / excludeFilter).value, (unmanagedJars / excludeFilter).value,
fileConverter.value, fileConverter.value,
) )
)
).map(exportVirtualClasspath) ++ Seq( ).map(exportVirtualClasspath) ++ Seq(
externalDependencyClasspath / outputFileStamps := { externalDependencyClasspath / outputFileStamps := Def.uncached {
val stamper = timeWrappedStamper.value val stamper = timeWrappedStamper.value
val converter = fileConverter.value val converter = fileConverter.value
externalDependencyClasspath.value.flatMap: vf => externalDependencyClasspath.value.flatMap: vf =>
@ -2626,7 +2656,7 @@ object Classpaths {
val converter = fileConverter.value val converter = fileConverter.value
data(dependencyClasspath.value).map(converter.toPath) data(dependencyClasspath.value).map(converter.toPath)
}, },
dependencyClasspathFiles / outputFileStamps := { dependencyClasspathFiles / outputFileStamps := Def.uncached {
val stamper = timeWrappedStamper.value val stamper = timeWrappedStamper.value
val converter = fileConverter.value val converter = fileConverter.value
dependencyClasspathFiles.value.flatMap: p => dependencyClasspathFiles.value.flatMap: p =>
@ -2724,9 +2754,10 @@ object Classpaths {
} }
val jvmPublishSettings: Seq[Setting[?]] = Seq( val jvmPublishSettings: Seq[Setting[?]] = Seq(
artifacts := artifactDefs(defaultArtifactTasks).value, artifacts := artifactDefs(defaultArtifactTasks).value,
packagedArtifacts := Def packagedArtifacts := {
.ifS(publishSbtPluginMavenStyle)(mavenArtifactsOfSbtPlugin)(packagedDefaultArtifacts) if publishSbtPluginMavenStyle.value then Def.uncached(mavenArtifactsOfSbtPlugin.value)
.value, else Def.uncached(packagedDefaultArtifacts.value)
},
// publishLocal needs legacy artifacts (see https://github.com/sbt/sbt/issues/7285) // publishLocal needs legacy artifacts (see https://github.com/sbt/sbt/issues/7285)
publishLocal / packagedArtifacts ++= { publishLocal / packagedArtifacts ++= {
if (sbtPlugin.value && !sbtPluginPublishLegacyMavenStyle.value) { if (sbtPlugin.value && !sbtPluginPublishLegacyMavenStyle.value) {
@ -2808,21 +2839,21 @@ object Classpaths {
def ivyPublishSettings: Seq[Setting[?]] = publishGlobalDefaults ++ Seq( def ivyPublishSettings: Seq[Setting[?]] = publishGlobalDefaults ++ Seq(
artifacts :== Nil, artifacts :== Nil,
packagedArtifacts :== Map.empty, packagedArtifacts :== Map.empty,
makePom := { makePom := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val config = makePomConfiguration.value val config = makePomConfiguration.value
val publisher = Keys.publisher.value val publisher = Keys.publisher.value
publisher.makePomFile(ivyModule.value, config, streams.value.log) publisher.makePomFile(ivyModule.value, config, streams.value.log)
converter.toVirtualFile(config.file.get.toPath()) converter.toVirtualFile(config.file.get.toPath())
}, },
(makePom / packagedArtifact) := ((makePom / artifact).value -> makePom.value), (makePom / packagedArtifact) := Def.uncached((makePom / artifact).value -> makePom.value),
deliver := deliverTask(makeIvyXmlConfiguration).value, deliver := deliverTask(makeIvyXmlConfiguration).value,
deliverLocal := deliverTask(makeIvyXmlLocalConfiguration).value, deliverLocal := deliverTask(makeIvyXmlLocalConfiguration).value,
makeIvyXml := deliverTask(makeIvyXmlConfiguration).value, makeIvyXml := deliverTask(makeIvyXmlConfiguration).value,
publish := publishOrSkip(publishConfiguration, publish / skip).value, publish := publishOrSkip(publishConfiguration, publish / skip).value,
publishLocal := publishOrSkip(publishLocalConfiguration, publishLocal / skip).value, publishLocal := publishOrSkip(publishLocalConfiguration, publishLocal / skip).value,
publishM2 := publishOrSkip(publishM2Configuration, publishM2 / skip).value, publishM2 := publishOrSkip(publishM2Configuration, publishM2 / skip).value,
credentials ++= { credentials ++= Def.uncached {
val alreadyContainsCentralCredentials: Boolean = credentials.value.exists { val alreadyContainsCentralCredentials: Boolean = credentials.value.exists {
case d: DirectCredentials => d.host == Sona.host case d: DirectCredentials => d.host == Sona.host
case _ => false case _ => false
@ -2931,7 +2962,8 @@ object Classpaths {
developers.value.toVector developers.value.toVector
), ),
overrideBuildResolvers := appConfiguration(isOverrideRepositories).value, overrideBuildResolvers := appConfiguration(isOverrideRepositories).value,
externalResolvers := (( externalResolvers := Def.uncached(
(
externalResolvers.?.value, externalResolvers.?.value,
resolvers.value, resolvers.value,
appResolvers.value, appResolvers.value,
@ -2940,7 +2972,8 @@ object Classpaths {
case (_, rs, Some(ars)) => ars ++ rs case (_, rs, Some(ars)) => ars ++ rs
case (_, rs, _) => case (_, rs, _) =>
Resolver.combineDefaultResolvers(rs.toVector, mavenCentral = true) Resolver.combineDefaultResolvers(rs.toVector, mavenCentral = true)
}), }
),
appResolvers := { appResolvers := {
val ac = appConfiguration.value val ac = appConfiguration.value
appRepositories(ac) map { ars => appRepositories(ac) map { ars =>
@ -2948,11 +2981,11 @@ object Classpaths {
Resolver.reorganizeAppResolvers(ars, useMavenCentral) Resolver.reorganizeAppResolvers(ars, useMavenCentral)
} }
}, },
bootResolvers := { bootResolvers := Def.uncached {
appConfiguration.map(bootRepositories).value appConfiguration.map(bootRepositories).value
}, },
fullResolvers := fullResolvers :=
(Def.task { Def.uncached((Def.task {
val proj = projectResolver.value val proj = projectResolver.value
val rs = externalResolvers.value val rs = externalResolvers.value
def pluginResolvers: Vector[Resolver] = def pluginResolvers: Vector[Resolver] =
@ -2972,7 +3005,7 @@ object Classpaths {
val base = if (sbtPlugin.value) sbtResolvers.value ++ rs ++ pr else rs ++ pr val base = if (sbtPlugin.value) sbtResolvers.value ++ rs ++ pr else rs ++ pr
(proj +: base).distinct (proj +: base).distinct
} }
}).value, }).value),
moduleName := normalizedName.value, moduleName := normalizedName.value,
outputPath := { outputPath := {
val p = platform.value val p = platform.value
@ -3002,13 +3035,13 @@ object Classpaths {
val st = state.value val st = state.value
BuildPaths.getDependencyDirectory(st, BuildPaths.getGlobalBase(st)) BuildPaths.getDependencyDirectory(st, BuildPaths.getGlobalBase(st))
}, },
otherResolvers := Resolver.publishMavenLocal +: publishTo.value.toVector, otherResolvers := Def.uncached(Resolver.publishMavenLocal +: publishTo.value.toVector),
projectResolver := projectResolverTask.value, projectResolver := Def.uncached(projectResolverTask.value),
projectDependencies := projectDependenciesTask.value, projectDependencies := Def.uncached(projectDependenciesTask.value),
// TODO - Is this the appropriate split? Ivy defines this simply as // TODO - Is this the appropriate split? Ivy defines this simply as
// just project + library, while the JVM plugin will define it as // just project + library, while the JVM plugin will define it as
// having the additional sbtPlugin + autoScala magikz. // having the additional sbtPlugin + autoScala magikz.
allDependencies := { allDependencies := Def.uncached {
projectDependencies.value ++ libraryDependencies.value projectDependencies.value ++ libraryDependencies.value
}, },
allExcludeDependencies := excludeDependencies.value, allExcludeDependencies := excludeDependencies.value,
@ -3033,7 +3066,7 @@ object Classpaths {
makePom / artifact := Artifact.pom(moduleName.value), makePom / artifact := Artifact.pom(moduleName.value),
projectID := defaultProjectID.value, projectID := defaultProjectID.value,
projectID := pluginProjectID.value, projectID := pluginProjectID.value,
projectDescriptors := depMap.value, projectDescriptors := Def.uncached(depMap.value),
updateConfiguration := { updateConfiguration := {
// Tell the UpdateConfiguration which artifact types are special (for sources and javadocs) // Tell the UpdateConfiguration which artifact types are special (for sources and javadocs)
val specialArtifactTypes = sourceArtifactTypes.value.toSet union docArtifactTypes.value.toSet val specialArtifactTypes = sourceArtifactTypes.value.toSet union docArtifactTypes.value.toSet
@ -3055,9 +3088,9 @@ object Classpaths {
) )
else None else None
}, },
dependencyResolution := dependencyResolutionTask.value, dependencyResolution := Def.uncached(dependencyResolutionTask.value),
publisher := IvyPublisher(ivyConfiguration.value), publisher := Def.uncached(IvyPublisher(ivyConfiguration.value)),
ivyConfiguration := mkIvyConfiguration.value, ivyConfiguration := Def.uncached(mkIvyConfiguration.value),
ivyConfigurations := { ivyConfigurations := {
val confs = thisProject.value.configurations val confs = thisProject.value.configurations
(confs ++ confs.map(internalConfigurationMap.value) ++ (if (autoCompilerPlugins.value) (confs ++ confs.map(internalConfigurationMap.value) ++ (if (autoCompilerPlugins.value)
@ -3106,7 +3139,7 @@ object Classpaths {
confs ++ extraSources.toSeq ++ extraDocs.toSeq confs ++ extraSources.toSeq ++ extraDocs.toSeq
}, },
moduleSettings := moduleSettings0.value, moduleSettings := Def.uncached(moduleSettings0.value),
makePomConfiguration := { makePomConfiguration := {
val converter = fileConverter.value val converter = fileConverter.value
val out = converter.toPath((makePom / artifactPath).value) val out = converter.toPath((makePom / artifactPath).value)
@ -3119,7 +3152,7 @@ object Classpaths {
.withAllRepositories(pomAllRepositories.value) .withAllRepositories(pomAllRepositories.value)
.withConfigurations(Configurations.defaultMavenConfigurations) .withConfigurations(Configurations.defaultMavenConfigurations)
}, },
makeIvyXmlConfiguration := { makeIvyXmlConfiguration := Def.uncached {
makeIvyXmlConfig( makeIvyXmlConfig(
publishMavenStyle.value, publishMavenStyle.value,
sbt.Classpaths.deliverPattern(target.value), sbt.Classpaths.deliverPattern(target.value),
@ -3130,7 +3163,7 @@ object Classpaths {
isSnapshot.value isSnapshot.value
) )
}, },
publishConfiguration := { publishConfiguration := Def.uncached {
val s = streams.value val s = streams.value
val vs = versionScheme.value val vs = versionScheme.value
if (vs.isEmpty) if (vs.isEmpty)
@ -3155,7 +3188,7 @@ object Classpaths {
isSnapshot.value isSnapshot.value
) )
}, },
makeIvyXmlLocalConfiguration := { makeIvyXmlLocalConfiguration := Def.uncached {
makeIvyXmlConfig( makeIvyXmlConfig(
false, // publishMavenStyle.value, false, // publishMavenStyle.value,
sbt.Classpaths.deliverPattern(target.value), sbt.Classpaths.deliverPattern(target.value),
@ -3167,7 +3200,7 @@ object Classpaths {
optResolverName = Some("local") optResolverName = Some("local")
) )
}, },
publishLocalConfiguration := { publishLocalConfiguration := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val artifacts = (publishLocal / packagedArtifacts).value.toVector.map { (a, vf) => val artifacts = (publishLocal / packagedArtifacts).value.toVector.map { (a, vf) =>
a -> converter.toPath(vf).toFile a -> converter.toPath(vf).toFile
@ -3183,7 +3216,7 @@ object Classpaths {
overwrite = isSnapshot.value overwrite = isSnapshot.value
) )
}, },
publishM2Configuration := { publishM2Configuration := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val artifacts = (publishM2 / packagedArtifacts).value.toVector.map { (a, vf) => val artifacts = (publishM2 / packagedArtifacts).value.toVector.map { (a, vf) =>
a -> converter.toPath(vf).toFile a -> converter.toPath(vf).toFile
@ -3200,22 +3233,24 @@ object Classpaths {
overwrite = isSnapshot.value overwrite = isSnapshot.value
) )
}, },
ivySbt := ivySbt0.value, ivySbt := Def.uncached(ivySbt0.value),
ivyModule := { val is = ivySbt.value; new is.Module(moduleSettings.value) }, ivyModule := Def.uncached { val is = ivySbt.value; new is.Module(moduleSettings.value) },
allCredentials := LMCoursier.allCredentialsTask.value, allCredentials := Def.uncached(LMCoursier.allCredentialsTask.value),
transitiveUpdate := transitiveUpdateTask.value, transitiveUpdate := Def.uncached(transitiveUpdateTask.value),
updateCacheName := { updateCacheName := {
val binVersion = scalaBinaryVersion.value val binVersion = scalaBinaryVersion.value
val suffix = if (crossPaths.value) s"_$binVersion" else "" val suffix = if (crossPaths.value) s"_$binVersion" else ""
s"update_cache$suffix" s"update_cache$suffix"
}, },
dependencyPositions := dependencyPositionsTask.value, dependencyPositions := Def.uncached(dependencyPositionsTask.value),
update / unresolvedWarningConfiguration := UnresolvedWarningConfiguration( update / unresolvedWarningConfiguration := Def.uncached(
UnresolvedWarningConfiguration(
dependencyPositions.value dependencyPositions.value
)
), ),
updateFull := updateTask.value, updateFull := Def.uncached(updateTask.value),
update := updateWithoutDetails("update").value, update := Def.uncached(updateWithoutDetails("update").value),
update := { update := Def.uncached {
val report = update.value val report = update.value
val log = streams.value.log val log = streams.value.log
ConflictWarning(conflictWarning.value, report, log) ConflictWarning(conflictWarning.value, report, log)
@ -3223,7 +3258,7 @@ object Classpaths {
}, },
update / evictionWarningOptions := evictionWarningOptions.value, update / evictionWarningOptions := evictionWarningOptions.value,
evicted / evictionWarningOptions := EvictionWarningOptions.full, evicted / evictionWarningOptions := EvictionWarningOptions.full,
evicted := { evicted := Def.uncached {
import ShowLines.* import ShowLines.*
val report = updateTask.value val report = updateTask.value
val log = streams.value.log val log = streams.value.log
@ -3236,7 +3271,7 @@ object Classpaths {
) ++ ) ++
inTask(updateClassifiers)( inTask(updateClassifiers)(
Seq( Seq(
classifiersModule := { classifiersModule := Def.uncached {
val key = (m: ModuleID) => (m.organization, m.name, m.revision) val key = (m: ModuleID) => (m.organization, m.name, m.revision)
val projectDeps = projectDependencies.value.iterator.map(key).toSet val projectDeps = projectDependencies.value.iterator.map(key).toSet
val externalModules = update.value.allModules.filterNot(m => projectDeps contains key(m)) val externalModules = update.value.allModules.filterNot(m => projectDeps contains key(m))
@ -3248,19 +3283,27 @@ object Classpaths {
transitiveClassifiers.value.toVector transitiveClassifiers.value.toVector
) )
}, },
dependencyResolution := dependencyResolutionTask.value, dependencyResolution := Def.uncached(dependencyResolutionTask.value),
csrConfiguration := LMCoursier.updateClassifierConfigurationTask.value, csrConfiguration := Def.uncached(LMCoursier.updateClassifierConfigurationTask.value),
TaskZero / updateClassifiers := LibraryManagement.updateClassifiersTask.value, TaskZero / updateClassifiers := Def.uncached(LibraryManagement.updateClassifiersTask.value),
) )
) ++ Seq( ) ++ Seq(
csrProject := CoursierInputsTasks.coursierProjectTask.value, csrProject := Def.uncached(CoursierInputsTasks.coursierProjectTask.value),
csrConfiguration := LMCoursier.coursierConfigurationTask.value, csrConfiguration := Def.uncached(LMCoursier.coursierConfigurationTask.value),
csrResolvers := CoursierRepositoriesTasks.coursierResolversTask(fullResolvers).value, csrResolvers := Def.uncached(
csrRecursiveResolvers := CoursierRepositoriesTasks.coursierRecursiveResolversTask.value, CoursierRepositoriesTasks.coursierResolversTask(fullResolvers).value
csrSbtResolvers := CoursierRepositoriesTasks.coursierSbtResolversTask.value, ),
csrInterProjectDependencies := CoursierInputsTasks.coursierInterProjectDependenciesTask.value, csrRecursiveResolvers := Def.uncached(
csrExtraProjects := CoursierInputsTasks.coursierExtraProjectsTask.value, CoursierRepositoriesTasks.coursierRecursiveResolversTask.value
csrFallbackDependencies := CoursierInputsTasks.coursierFallbackDependenciesTask.value, ),
csrSbtResolvers := Def.uncached(CoursierRepositoriesTasks.coursierSbtResolversTask.value),
csrInterProjectDependencies := Def.uncached(
CoursierInputsTasks.coursierInterProjectDependenciesTask.value
),
csrExtraProjects := Def.uncached(CoursierInputsTasks.coursierExtraProjectsTask.value),
csrFallbackDependencies := Def.uncached(
CoursierInputsTasks.coursierFallbackDependenciesTask.value
),
) ++ ) ++
IvyXml.generateIvyXmlSettings() ++ IvyXml.generateIvyXmlSettings() ++
LMCoursier.publicationsSetting(Seq(Compile, Test).map(c => c -> CConfiguration(c.name))) LMCoursier.publicationsSetting(Seq(Compile, Test).map(c => c -> CConfiguration(c.name)))
@ -3273,7 +3316,7 @@ object Classpaths {
scalaVersion.value scalaVersion.value
), ),
// Override the default to handle mixing in the sbtPlugin + scala dependencies. // Override the default to handle mixing in the sbtPlugin + scala dependencies.
allDependencies := { allDependencies := Def.uncached {
val base = projectDependencies.value ++ libraryDependencies.value val base = projectDependencies.value ++ libraryDependencies.value
val isPlugin = sbtPlugin.value val isPlugin = sbtPlugin.value
val sbtdeps = val sbtdeps =
@ -3405,7 +3448,7 @@ object Classpaths {
sbtClassifiersGlobalDefaults ++ sbtClassifiersGlobalDefaults ++
inTask(updateSbtClassifiers)( inTask(updateSbtClassifiers)(
Seq( Seq(
externalResolvers := { externalResolvers := Def.uncached {
val boot = bootResolvers.value val boot = bootResolvers.value
val explicit = buildStructure.value val explicit = buildStructure.value
.units(thisProjectRef.value.build) .units(thisProjectRef.value.build)
@ -3415,7 +3458,8 @@ object Classpaths {
.resolvers .resolvers
explicit orElse boot getOrElse externalResolvers.value explicit orElse boot getOrElse externalResolvers.value
}, },
ivyConfiguration := InlineIvyConfiguration( ivyConfiguration := Def.uncached(
InlineIvyConfiguration(
lock = Option(lock(appConfiguration.value)), lock = Option(lock(appConfiguration.value)),
log = Option(streams.value.log), log = Option(streams.value.log),
updateOptions = UpdateOptions(), updateOptions = UpdateOptions(),
@ -3426,9 +3470,10 @@ object Classpaths {
checksums = checksums.value.toVector, checksums = checksums.value.toVector,
managedChecksums = false, managedChecksums = false,
resolutionCacheDir = Some(target.value / "resolution-cache"), resolutionCacheDir = Some(target.value / "resolution-cache"),
)
), ),
ivySbt := ivySbt0.value, ivySbt := Def.uncached(ivySbt0.value),
classifiersModule := classifiersModuleTask.value, classifiersModule := Def.uncached(classifiersModuleTask.value),
// Redefine scalaVersion and scalaBinaryVersion specifically for the dependency graph used for updateSbtClassifiers task. // Redefine scalaVersion and scalaBinaryVersion specifically for the dependency graph used for updateSbtClassifiers task.
// to fix https://github.com/sbt/sbt/issues/2686 // to fix https://github.com/sbt/sbt/issues/2686
scalaVersion := appConfiguration.value.provider.scalaProvider.version, scalaVersion := appConfiguration.value.provider.scalaProvider.version,
@ -3446,9 +3491,10 @@ object Classpaths {
).withScalaOrganization(scalaOrganization.value) ).withScalaOrganization(scalaOrganization.value)
) )
}, },
dependencyResolution := dependencyResolutionTask.value, dependencyResolution := Def.uncached(dependencyResolutionTask.value),
csrConfiguration := LMCoursier.updateSbtClassifierConfigurationTask.value, csrConfiguration := Def.uncached(LMCoursier.updateSbtClassifierConfigurationTask.value),
(TaskZero / updateSbtClassifiers) := (Def (TaskZero / updateSbtClassifiers) := Def.uncached(
(Def
.task { .task {
val lm = dependencyResolution.value val lm = dependencyResolution.value
val s = streams.value val s = streams.value
@ -3489,19 +3535,24 @@ object Classpaths {
.tag(Tags.Update, Tags.Network)) .tag(Tags.Update, Tags.Network))
.value .value
) )
)
) ++ ) ++
inTask(scalaCompilerBridgeScope)( inTask(scalaCompilerBridgeScope)(
Seq( Seq(
dependencyResolution := dependencyResolutionTask.value, dependencyResolution := Def.uncached(dependencyResolutionTask.value),
csrConfiguration := LMCoursier.scalaCompilerBridgeConfigurationTask.value, csrConfiguration := Def.uncached(LMCoursier.scalaCompilerBridgeConfigurationTask.value),
csrResolvers := csrResolvers :=
CoursierRepositoriesTasks.coursierResolversTask(scalaCompilerBridgeResolvers).value, Def.uncached(
externalResolvers := scalaCompilerBridgeResolvers.value, CoursierRepositoriesTasks.coursierResolversTask(scalaCompilerBridgeResolvers).value
),
externalResolvers := Def.uncached(scalaCompilerBridgeResolvers.value),
) )
) ++ Seq( ) ++ Seq(
bootIvyConfiguration := (updateSbtClassifiers / ivyConfiguration).value, bootIvyConfiguration := Def.uncached((updateSbtClassifiers / ivyConfiguration).value),
bootDependencyResolution := (updateSbtClassifiers / dependencyResolution).value, bootDependencyResolution := Def.uncached(
scalaCompilerBridgeResolvers := { (updateSbtClassifiers / dependencyResolution).value
),
scalaCompilerBridgeResolvers := Def.uncached {
val boot = bootResolvers.value val boot = bootResolvers.value
val explicit = buildStructure.value val explicit = buildStructure.value
.units(thisProjectRef.value.build) .units(thisProjectRef.value.build)
@ -3519,7 +3570,9 @@ object Classpaths {
} }
(xs ++ ext).distinct (xs ++ ext).distinct
}, },
scalaCompilerBridgeDependencyResolution := (scalaCompilerBridgeScope / dependencyResolution).value scalaCompilerBridgeDependencyResolution := Def.uncached(
(scalaCompilerBridgeScope / dependencyResolution).value
),
) )
val moduleIdJsonKeyFormat: sjsonnew.JsonKeyFormat[ModuleID] = val moduleIdJsonKeyFormat: sjsonnew.JsonKeyFormat[ModuleID] =
@ -4223,7 +4276,7 @@ object Classpaths {
} }
lazy val compilerPluginConfig = Seq( lazy val compilerPluginConfig = Seq(
scalacOptions := { scalacOptions := Def.uncached {
given FileConverter = fileConverter.value given FileConverter = fileConverter.value
val options = scalacOptions.value val options = scalacOptions.value
val newPlugins = autoPlugins( val newPlugins = autoPlugins(
@ -4468,7 +4521,7 @@ trait BuildExtra extends BuildCommon with DefExtra {
/** Constructs a setting that declares a new artifact `a` that is generated by `taskDef`. */ /** Constructs a setting that declares a new artifact `a` that is generated by `taskDef`. */
def addArtifact(a: Artifact, taskDef: TaskKey[HashedVirtualFileRef]): SettingsDefinition = { def addArtifact(a: Artifact, taskDef: TaskKey[HashedVirtualFileRef]): SettingsDefinition = {
val pkgd = packagedArtifacts := packagedArtifacts.value.updated(a, taskDef.value) val pkgd = packagedArtifacts := Def.uncached(packagedArtifacts.value.updated(a, taskDef.value))
Seq(artifacts += a, pkgd) Seq(artifacts += a, pkgd)
} }
@ -4476,13 +4529,19 @@ trait BuildExtra extends BuildCommon with DefExtra {
def addArtifact( def addArtifact(
artifact: Initialize[Artifact], artifact: Initialize[Artifact],
taskDef: Initialize[Task[HashedVirtualFileRef]] taskDef: Initialize[Task[HashedVirtualFileRef]]
): SettingsDefinition = { ): SettingsDefinition =
val artLocal = SettingKey.local[Artifact] val artLocal = SettingKey.local[Artifact]
val taskLocal = TaskKey.local[HashedVirtualFileRef] val taskLocal = TaskKey.local[HashedVirtualFileRef]
val art = artifacts := artLocal.value +: artifacts.value val art = artifacts := artLocal.value +: artifacts.value
val pkgd = packagedArtifacts := packagedArtifacts.value.updated(artLocal.value, taskLocal.value) val pkgd = packagedArtifacts := Def.uncached(
Seq(artLocal := artifact.value, taskLocal := taskDef.value, art, pkgd) packagedArtifacts.value.updated(artLocal.value, taskLocal.value)
} )
Seq(
artLocal := artifact.value,
taskLocal := taskDef.value,
art,
pkgd,
)
def runInputTask( def runInputTask(
config: Configuration, config: Configuration,
@ -4522,7 +4581,7 @@ trait BuildExtra extends BuildCommon with DefExtra {
} }
} }
}.evaluated }.evaluated
) ++ inTask(scoped)((config / forkOptions) := forkOptionsTask.value) ) ++ inTask(scoped)((config / forkOptions) := Def.uncached(forkOptionsTask.value))
} }
// public API // public API
@ -4544,7 +4603,7 @@ trait BuildExtra extends BuildCommon with DefExtra {
r.run(mainClass, cp.files, arguments, s.log).get r.run(mainClass, cp.files, arguments, s.log).get
} }
}.value }.value
) ++ inTask(scoped)((config / forkOptions) := forkOptionsTask.value) ) ++ inTask(scoped)((config / forkOptions) := Def.uncached(forkOptionsTask.value))
def initScoped[T](sk: ScopedKey[?], i: Initialize[T]): Initialize[T] = def initScoped[T](sk: ScopedKey[?], i: Initialize[T]): Initialize[T] =
initScope(fillTaskAxis(sk.scope, sk.key), i) initScope(fillTaskAxis(sk.scope, sk.key), i)
@ -4556,7 +4615,7 @@ trait BuildExtra extends BuildCommon with DefExtra {
* This is useful for reducing Test/compile time when not running test. * This is useful for reducing Test/compile time when not running test.
*/ */
def noTestCompletion(config: Configuration = Test): Setting[?] = def noTestCompletion(config: Configuration = Test): Setting[?] =
inConfig(config)(Seq(definedTests := detectTests.value)).head inConfig(config)(Seq(definedTests := Def.uncached(detectTests.value))).head
def filterKeys(ss: Seq[Setting[?]], transitive: Boolean = false)( def filterKeys(ss: Seq[Setting[?]], transitive: Boolean = false)(
f: ScopedKey[?] => Boolean f: ScopedKey[?] => Boolean

View File

@ -629,7 +629,7 @@ object EvaluateTask {
// if the return type Seq[Setting[_]] is not explicitly given, scalac hangs // if the return type Seq[Setting[_]] is not explicitly given, scalac hangs
val injectStreams: ScopedKey[?] => Seq[Setting[?]] = scoped => val injectStreams: ScopedKey[?] => Seq[Setting[?]] = scoped =>
if (scoped.key == streams.key) { if (scoped.key == streams.key) {
Seq(scoped.scope / streams := { Seq(scoped.scope / streams := Def.uncached {
(streamsManager.map { mgr => (streamsManager.map { mgr =>
val stream = mgr(scoped) val stream = mgr(scoped)
stream.open() stream.open()

View File

@ -180,8 +180,12 @@ object Keys {
// Output paths // Output paths
@cacheLevel(include = Array.empty) @cacheLevel(include = Array.empty)
val classDirectory = settingKey[File]("Directory for compiled classes and copied resources.").withRank(AMinusSetting) val classDirectory = settingKey[File]("Directory for compiled classes and copied resources.").withRank(AMinusSetting)
@cacheLevel(include = Array.empty)
val earlyOutput = settingKey[VirtualFile]("JAR file for pickles used for build pipelining") val earlyOutput = settingKey[VirtualFile]("JAR file for pickles used for build pipelining")
val backendOutput = settingKey[VirtualFile]("Output directory of the compiler backend") val backendOutput = settingKey[VirtualFile]("Output directory of the compiler backend")
@cacheLevel(include = Array.empty)
val cleanFiles = taskKey[Seq[File]]("The files to recursively delete during a clean.").withRank(BSetting) val cleanFiles = taskKey[Seq[File]]("The files to recursively delete during a clean.").withRank(BSetting)
val cleanKeepFiles = settingKey[Seq[File]]("Files or directories to keep during a clean. Must be direct children of target.").withRank(CSetting) val cleanKeepFiles = settingKey[Seq[File]]("Files or directories to keep during a clean. Must be direct children of target.").withRank(CSetting)
val cleanKeepGlobs = settingKey[Seq[Glob]]("Globs to keep during a clean. Must be direct children of target.").withRank(CSetting) val cleanKeepGlobs = settingKey[Seq[Glob]]("Globs to keep during a clean. Must be direct children of target.").withRank(CSetting)
@ -209,6 +213,7 @@ object Keys {
val compileInputs = taskKey[Inputs]("Collects all inputs needed for compilation.").withRank(DTask) val compileInputs = taskKey[Inputs]("Collects all inputs needed for compilation.").withRank(DTask)
val compileInputs2 = taskKey[CompileInputs2]("") val compileInputs2 = taskKey[CompileInputs2]("")
val scalaHome = settingKey[Option[File]]("If Some, defines the local Scala installation to use for compilation, running, and testing.").withRank(ASetting) val scalaHome = settingKey[Option[File]]("If Some, defines the local Scala installation to use for compilation, running, and testing.").withRank(ASetting)
@cacheLevel(include = Array.empty)
val scalaInstance = taskKey[ScalaInstance]("Defines the Scala instance to use for compilation, running, and testing.").withRank(DTask) val scalaInstance = taskKey[ScalaInstance]("Defines the Scala instance to use for compilation, running, and testing.").withRank(DTask)
val scalaOrganization = settingKey[String]("Organization/group ID of the Scala used in the project. Default value is 'org.scala-lang'. This is an advanced setting used for clones of the Scala Language. It should be disregarded in standard use cases.").withRank(CSetting) val scalaOrganization = settingKey[String]("Organization/group ID of the Scala used in the project. Default value is 'org.scala-lang'. This is an advanced setting used for clones of the Scala Language. It should be disregarded in standard use cases.").withRank(CSetting)
val scalaVersion = settingKey[String]("The version of Scala used for building.").withRank(APlusSetting) val scalaVersion = settingKey[String]("The version of Scala used for building.").withRank(APlusSetting)
@ -301,7 +306,11 @@ object Keys {
val artifact = settingKey[Artifact]("Describes an artifact.").withRank(BMinusSetting) val artifact = settingKey[Artifact]("Describes an artifact.").withRank(BMinusSetting)
val artifactClassifier = settingKey[Option[String]]("Sets the classifier used by the default artifact definition.").withRank(BSetting) val artifactClassifier = settingKey[Option[String]]("Sets the classifier used by the default artifact definition.").withRank(BSetting)
val artifactName = settingKey[(ScalaVersion, ModuleID, Artifact) => String]("Function that produces the artifact name from its definition.").withRank(CSetting) val artifactName = settingKey[(ScalaVersion, ModuleID, Artifact) => String]("Function that produces the artifact name from its definition.").withRank(CSetting)
@cacheLevel(include = Array.empty)
val mappings = taskKey[Seq[(HashedVirtualFileRef, String)]]("Defines the mappings from a file to a path, used by packaging, for example.").withRank(BTask) val mappings = taskKey[Seq[(HashedVirtualFileRef, String)]]("Defines the mappings from a file to a path, used by packaging, for example.").withRank(BTask)
@cacheLevel(include = Array.empty)
val fileMappings = taskKey[Seq[(File, File)]]("Defines the mappings from a file to a file, used for copying files, for example.").withRank(BMinusTask) val fileMappings = taskKey[Seq[(File, File)]]("Defines the mappings from a file to a file, used for copying files, for example.").withRank(BMinusTask)
// Run Keys // Run Keys
@ -356,6 +365,8 @@ object Keys {
val testOptions = taskKey[Seq[TestOption]]("Options for running tests.").withRank(BPlusTask) val testOptions = taskKey[Seq[TestOption]]("Options for running tests.").withRank(BPlusTask)
private[sbt] val testOptionDigests = taskKey[Seq[Digest]]("Digest for testOptions").withRank(DTask) private[sbt] val testOptionDigests = taskKey[Seq[Digest]]("Digest for testOptions").withRank(DTask)
val testFrameworks = settingKey[Seq[TestFramework]]("Registered, although not necessarily present, test frameworks.").withRank(CTask) val testFrameworks = settingKey[Seq[TestFramework]]("Registered, although not necessarily present, test frameworks.").withRank(CTask)
@cacheLevel(include = Array.empty)
val testListeners = taskKey[Seq[TestReportListener]]("Defines test listeners.").withRank(DTask) val testListeners = taskKey[Seq[TestReportListener]]("Defines test listeners.").withRank(DTask)
val testForkedParallel = settingKey[Boolean]("Whether forked tests should be executed in parallel").withRank(CTask) val testForkedParallel = settingKey[Boolean]("Whether forked tests should be executed in parallel").withRank(CTask)
val testExecution = taskKey[Tests.Execution]("Settings controlling test execution").withRank(DTask) val testExecution = taskKey[Tests.Execution]("Settings controlling test execution").withRank(DTask)
@ -486,6 +497,8 @@ object Keys {
val csrExtraProjects = taskKey[Seq[lmcoursier.definitions.Project]]("").withRank(CTask) val csrExtraProjects = taskKey[Seq[lmcoursier.definitions.Project]]("").withRank(CTask)
val csrFallbackDependencies = taskKey[Seq[FallbackDependency]]("") val csrFallbackDependencies = taskKey[Seq[FallbackDependency]]("")
val csrLogger = taskKey[Option[CacheLogger]]("") val csrLogger = taskKey[Option[CacheLogger]]("")
@cacheLevel(include = Array.empty)
val csrExtraCredentials = taskKey[Seq[lmcoursier.credentials.Credentials]]("") val csrExtraCredentials = taskKey[Seq[lmcoursier.credentials.Credentials]]("")
val csrPublications = taskKey[Seq[(lmcoursier.definitions.Configuration, lmcoursier.definitions.Publication)]]("") val csrPublications = taskKey[Seq[(lmcoursier.definitions.Configuration, lmcoursier.definitions.Publication)]]("")
val csrReconciliations = settingKey[Seq[(ModuleMatchers, Reconciliation)]]("Strategy to reconcile version conflicts.") val csrReconciliations = settingKey[Seq[(ModuleMatchers, Reconciliation)]]("Strategy to reconcile version conflicts.")
@ -535,7 +548,10 @@ object Keys {
val packagedArtifacts = taskKey[Map[Artifact, HashedVirtualFileRef]]("Packages all artifacts for publishing and maps the Artifact definition to the generated file.").withRank(CTask) val packagedArtifacts = taskKey[Map[Artifact, HashedVirtualFileRef]]("Packages all artifacts for publishing and maps the Artifact definition to the generated file.").withRank(CTask)
val publishMavenStyle = settingKey[Boolean]("Configures whether to generate and publish a pom (true) or Ivy file (false).").withRank(BSetting) val publishMavenStyle = settingKey[Boolean]("Configures whether to generate and publish a pom (true) or Ivy file (false).").withRank(BSetting)
val sbtPluginPublishLegacyMavenStyle = settingKey[Boolean]("Configuration for generating the legacy pom of sbt plugins, to publish to Maven").withRank(CSetting) val sbtPluginPublishLegacyMavenStyle = settingKey[Boolean]("Configuration for generating the legacy pom of sbt plugins, to publish to Maven").withRank(CSetting)
@cacheLevel(include = Array.empty)
val credentials = taskKey[Seq[Credentials]]("The credentials to use for updating and publishing.").withRank(BMinusTask) val credentials = taskKey[Seq[Credentials]]("The credentials to use for updating and publishing.").withRank(BMinusTask)
@cacheLevel(include = Array.empty)
val allCredentials = taskKey[Seq[Credentials]]("Aggregated credentials across current and root subprojects. Do not rewire this task.").withRank(DTask) val allCredentials = taskKey[Seq[Credentials]]("Aggregated credentials across current and root subprojects. Do not rewire this task.").withRank(DTask)
val makePom = taskKey[HashedVirtualFileRef]("Generates a pom for publishing when publishing Maven-style.").withRank(BPlusTask) val makePom = taskKey[HashedVirtualFileRef]("Generates a pom for publishing when publishing Maven-style.").withRank(BPlusTask)
@ -564,9 +580,15 @@ object Keys {
val appResolvers = settingKey[Option[Seq[Resolver]]]("The resolvers configured for this application by the sbt launcher.").withRank(BMinusSetting) val appResolvers = settingKey[Option[Seq[Resolver]]]("The resolvers configured for this application by the sbt launcher.").withRank(BMinusSetting)
val externalResolvers = taskKey[Seq[Resolver]]("The external resolvers for automatically managed dependencies.").withRank(BMinusSetting) val externalResolvers = taskKey[Seq[Resolver]]("The external resolvers for automatically managed dependencies.").withRank(BMinusSetting)
val resolvers = settingKey[Seq[Resolver]]("The user-defined additional resolvers for automatically managed dependencies.").withRank(BMinusTask) val resolvers = settingKey[Seq[Resolver]]("The user-defined additional resolvers for automatically managed dependencies.").withRank(BMinusTask)
@cacheLevel(include = Array.empty)
val projectResolver = taskKey[Resolver]("Resolver that handles inter-project dependencies.").withRank(DTask) val projectResolver = taskKey[Resolver]("Resolver that handles inter-project dependencies.").withRank(DTask)
val fullResolvers = taskKey[Seq[Resolver]]("Combines the project resolver, default resolvers, and user-defined resolvers.").withRank(CTask) val fullResolvers = taskKey[Seq[Resolver]]("Combines the project resolver, default resolvers, and user-defined resolvers.").withRank(CTask)
@cacheLevel(include = Array.empty)
val otherResolvers = taskKey[Seq[Resolver]]("Resolvers not included in the main resolver chain, such as those in module configurations.").withRank(CSetting) val otherResolvers = taskKey[Seq[Resolver]]("Resolvers not included in the main resolver chain, such as those in module configurations.").withRank(CSetting)
@cacheLevel(include = Array.empty)
val scalaCompilerBridgeResolvers = taskKey[Seq[Resolver]]("Resolvers used to resolve compiler bridges.").withRank(CSetting) val scalaCompilerBridgeResolvers = taskKey[Seq[Resolver]]("Resolvers used to resolve compiler bridges.").withRank(CSetting)
val includePluginResolvers = settingKey[Boolean]("Include the resolvers from the metabuild.").withRank(CSetting) val includePluginResolvers = settingKey[Boolean]("Include the resolvers from the metabuild.").withRank(CSetting)
val moduleConfigurations = settingKey[Seq[ModuleConfiguration]]("Defines module configurations, which override resolvers on a per-module basis.").withRank(BMinusSetting) val moduleConfigurations = settingKey[Seq[ModuleConfiguration]]("Defines module configurations, which override resolvers on a per-module basis.").withRank(BMinusSetting)
@ -585,6 +607,8 @@ object Keys {
val scalaModuleInfo = settingKey[Option[ScalaModuleInfo]]("Configures how Scala dependencies are checked, filtered, and injected.").withRank(CSetting) val scalaModuleInfo = settingKey[Option[ScalaModuleInfo]]("Configures how Scala dependencies are checked, filtered, and injected.").withRank(CSetting)
val ivyValidate = settingKey[Boolean]("Enables/disables Ivy validation of module metadata.").withRank(BSetting) val ivyValidate = settingKey[Boolean]("Enables/disables Ivy validation of module metadata.").withRank(BSetting)
val ivyLoggingLevel = settingKey[UpdateLogging]("The logging level for updating.").withRank(BSetting) val ivyLoggingLevel = settingKey[UpdateLogging]("The logging level for updating.").withRank(BSetting)
@cacheLevel(include = Array.empty)
val publishTo = taskKey[Option[Resolver]]("The resolver to publish to.").withRank(ASetting) val publishTo = taskKey[Option[Resolver]]("The resolver to publish to.").withRank(ASetting)
val artifacts = settingKey[Seq[Artifact]]("The artifact definitions for the current module. Must be consistent with " + packagedArtifacts.key.label + ".").withRank(BSetting) val artifacts = settingKey[Seq[Artifact]]("The artifact definitions for the current module. Must be consistent with " + packagedArtifacts.key.label + ".").withRank(BSetting)
val projectDescriptors = taskKey[Map[ModuleRevisionId, ModuleDescriptor]]("Project dependency map for the inter-project resolver.").withRank(DTask) val projectDescriptors = taskKey[Map[ModuleRevisionId, ModuleDescriptor]]("Project dependency map for the inter-project resolver.").withRank(DTask)
@ -641,6 +665,8 @@ object Keys {
val streams = taskKey[TaskStreams]("Provides streams for logging and persisting data.").withRank(DTask) val streams = taskKey[TaskStreams]("Provides streams for logging and persisting data.").withRank(DTask)
val taskDefinitionKey = Def.taskDefinitionKey val taskDefinitionKey = Def.taskDefinitionKey
val (executionRoots, dummyRoots) = Def.dummy[Seq[ScopedKey[?]]]("executionRoots", "The list of root tasks for this task execution. Roots are the top-level tasks that were directly requested to be run.") val (executionRoots, dummyRoots) = Def.dummy[Seq[ScopedKey[?]]]("executionRoots", "The list of root tasks for this task execution. Roots are the top-level tasks that were directly requested to be run.")
@cacheLevel(include = Array.empty)
val state = Def.stateKey val state = Def.stateKey
val streamsManager = Def.streamsManagerKey val streamsManager = Def.streamsManagerKey
// wrapper to work around SI-2915 // wrapper to work around SI-2915

View File

@ -90,7 +90,7 @@ object DefaultOptions {
def credentials(state: State): Credentials = def credentials(state: State): Credentials =
Credentials(getGlobalSettingsDirectory(state, getGlobalBase(state)) / ".credentials") Credentials(getGlobalSettingsDirectory(state, getGlobalBase(state)) / ".credentials")
def addCredentials: Setting[?] = Keys.credentials += { credentials(Keys.state.value) } def addCredentials: Setting[?] = Keys.credentials += credentials(Keys.state.value)
def shellPrompt(version: String): State => String = def shellPrompt(version: String): State => String =
s => s"${s.configuration.provider.id.name}:${Project.extract(s).currentProject.id}:${version}> " s => s"${s.configuration.provider.id.name}:${Project.extract(s).currentProject.id}:${version}> "

View File

@ -37,6 +37,7 @@ import sbt.nio.Keys.{ inputFileStamps, outputFileStamps }
import sbt.std.TaskExtra.* import sbt.std.TaskExtra.*
import sbt.util.InterfaceUtil.toOption import sbt.util.InterfaceUtil.toOption
import sbt.util.{ DiskActionCacheStore, Logger } import sbt.util.{ DiskActionCacheStore, Logger }
import sbt.util.CacheImplicits.given
import sjsonnew.JsonFormat import sjsonnew.JsonFormat
import xsbti.{ FileConverter, HashedVirtualFileRef, VirtualFileRef } import xsbti.{ FileConverter, HashedVirtualFileRef, VirtualFileRef }
import xsbti.compile.CompileAnalysis import xsbti.compile.CompileAnalysis
@ -74,7 +75,7 @@ object RemoteCache {
lazy val globalSettings: Seq[Def.Setting[?]] = Seq( lazy val globalSettings: Seq[Def.Setting[?]] = Seq(
remoteCacheId := "", remoteCacheId := "",
remoteCacheIdCandidates := Nil, remoteCacheIdCandidates :== Nil,
pushRemoteCacheTo :== None, pushRemoteCacheTo :== None,
localCacheDirectory :== defaultCacheLocation, localCacheDirectory :== defaultCacheLocation,
pushRemoteCache / ivyPaths := { pushRemoteCache / ivyPaths := {
@ -139,14 +140,14 @@ object RemoteCache {
} }
}) })
.value, .value,
pushRemoteCacheConfiguration / remoteCacheArtifacts := { pushRemoteCacheConfiguration / remoteCacheArtifacts := Def.uncached {
enabledOnly(remoteCacheArtifact.toSettingKey, defaultArtifactTasks).apply(_.join).value enabledOnly(remoteCacheArtifact.toSettingKey, defaultArtifactTasks).apply(_.join).value
}, },
pushRemoteCacheConfiguration / publishMavenStyle := true, pushRemoteCacheConfiguration / publishMavenStyle := true,
Compile / packageCache / pushRemoteCacheArtifact := true, Compile / packageCache / pushRemoteCacheArtifact := true,
Compile / packageCache / artifact := Artifact(moduleName.value, cachedCompileClassifier), Compile / packageCache / artifact := Artifact(moduleName.value, cachedCompileClassifier),
remoteCachePom / pushRemoteCacheArtifact := true, remoteCachePom / pushRemoteCacheArtifact := true,
remoteCachePom := { remoteCachePom := Def.uncached {
val s = streams.value val s = streams.value
val converter = fileConverter.value val converter = fileConverter.value
val config = (remoteCachePom / makePomConfiguration).value val config = (remoteCachePom / makePomConfiguration).value
@ -163,14 +164,14 @@ object RemoteCache {
val out = converter.toPath((remoteCachePom / artifactPath).value) val out = converter.toPath((remoteCachePom / artifactPath).value)
config.withFile(out.toFile()) config.withFile(out.toFile())
}, },
remoteCachePom / remoteCacheArtifact := { remoteCachePom / remoteCacheArtifact := Def.uncached {
PomRemoteCacheArtifact((makePom / artifact).value, remoteCachePom) PomRemoteCacheArtifact((makePom / artifact).value, remoteCachePom)
}, },
remoteCacheResolvers := pushRemoteCacheTo.value.toVector, remoteCacheResolvers := pushRemoteCacheTo.value.toVector,
) ++ inTask(pushRemoteCache)( ) ++ inTask(pushRemoteCache)(
Seq( Seq(
ivyPaths := (Scope.Global / pushRemoteCache / ivyPaths).value, ivyPaths := (Scope.Global / pushRemoteCache / ivyPaths).value,
ivyConfiguration := { ivyConfiguration := Def.uncached {
val config0 = Classpaths.mkIvyConfiguration.value val config0 = Classpaths.mkIvyConfiguration.value
config0 config0
.withResolvers(remoteCacheResolvers.value.toVector) .withResolvers(remoteCacheResolvers.value.toVector)
@ -179,7 +180,7 @@ object RemoteCache {
.withPaths(ivyPaths.value) .withPaths(ivyPaths.value)
.withUpdateOptions(UpdateOptions().withGigahorse(true)) .withUpdateOptions(UpdateOptions().withGigahorse(true))
}, },
ivySbt := { ivySbt := Def.uncached {
Credentials.register(credentials.value, streams.value.log) Credentials.register(credentials.value, streams.value.log)
val config0 = ivyConfiguration.value val config0 = ivyConfiguration.value
new IvySbt(config0) new IvySbt(config0)
@ -187,8 +188,8 @@ object RemoteCache {
) )
) ++ inTask(pullRemoteCache)( ) ++ inTask(pullRemoteCache)(
Seq( Seq(
dependencyResolution := Defaults.dependencyResolutionTask.value, dependencyResolution := Def.uncached(Defaults.dependencyResolutionTask.value),
csrConfiguration := { csrConfiguration := Def.uncached {
val rs = pushRemoteCacheTo.value.toVector ++ remoteCacheResolvers.value.toVector val rs = pushRemoteCacheTo.value.toVector ++ remoteCacheResolvers.value.toVector
LMCoursier.scalaCompilerBridgeConfigurationTask.value LMCoursier.scalaCompilerBridgeConfigurationTask.value
.withResolvers(rs) .withResolvers(rs)
@ -207,7 +208,7 @@ object RemoteCache {
): Seq[Def.Setting[?]] = ): Seq[Def.Setting[?]] =
inTask(packageCache)( inTask(packageCache)(
Seq( Seq(
(Defaults.TaskZero / packageCache) := { (Defaults.TaskZero / packageCache) := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val original = (Defaults.TaskZero / packageBin).value val original = (Defaults.TaskZero / packageBin).value
val originalFile = converter.toPath(original) val originalFile = converter.toPath(original)
@ -233,13 +234,13 @@ object RemoteCache {
converter.toVirtualFile(artpFile) converter.toVirtualFile(artpFile)
}, },
pushRemoteCacheArtifact := true, pushRemoteCacheArtifact := true,
remoteCacheArtifact := cacheArtifactTask.value, remoteCacheArtifact := Def.uncached(cacheArtifactTask.value),
packagedArtifact := (artifact.value -> packageCache.value), packagedArtifact := Def.uncached(artifact.value -> packageCache.value),
artifactPath := Defaults.artifactPathSetting(artifact).value artifactPath := Defaults.artifactPathSetting(artifact).value
) )
) ++ inTask(pushRemoteCache)( ) ++ inTask(pushRemoteCache)(
Seq( Seq(
moduleSettings := { moduleSettings := Def.uncached {
val smi = scalaModuleInfo.value val smi = scalaModuleInfo.value
ModuleDescriptorConfiguration(remoteCacheProjectId.value, projectInfo.value) ModuleDescriptorConfiguration(remoteCacheProjectId.value, projectInfo.value)
.withScalaModuleInfo(smi) .withScalaModuleInfo(smi)
@ -257,7 +258,7 @@ object RemoteCache {
) )
) ++ Seq( ) ++ Seq(
remoteCacheIdCandidates := List(remoteCacheId.value), remoteCacheIdCandidates := List(remoteCacheId.value),
remoteCacheProjectId := { remoteCacheProjectId := Def.uncached {
val o = organization.value val o = organization.value
val m = moduleName.value val m = moduleName.value
val id = remoteCacheId.value val id = remoteCacheId.value
@ -265,7 +266,7 @@ object RemoteCache {
val v = toVersion(id) val v = toVersion(id)
ModuleID(o, m, v).cross(c) ModuleID(o, m, v).cross(c)
}, },
remoteCacheId := { remoteCacheId := Def.uncached {
val inputs = (unmanagedSources / inputFileStamps).value val inputs = (unmanagedSources / inputFileStamps).value
val cp = (externalDependencyClasspath / outputFileStamps).?.value.getOrElse(Nil) val cp = (externalDependencyClasspath / outputFileStamps).?.value.getOrElse(Nil)
val extraInc = (extraIncOptions.value) flatMap { (k, v) => val extraInc = (extraIncOptions.value) flatMap { (k, v) =>
@ -273,7 +274,7 @@ object RemoteCache {
} }
combineHash(extractHash(inputs) ++ extractHash(cp) ++ extraInc) combineHash(extractHash(inputs) ++ extractHash(cp) ++ extraInc)
}, },
pushRemoteCacheConfiguration := { pushRemoteCacheConfiguration := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val artifacts = val artifacts =
(pushRemoteCacheConfiguration / packagedArtifacts).value.toVector.map { (a, vf) => (pushRemoteCacheConfiguration / packagedArtifacts).value.toVector.map { (a, vf) =>
@ -291,7 +292,7 @@ object RemoteCache {
isSnapshot.value isSnapshot.value
) )
}, },
pushRemoteCacheConfiguration / packagedArtifacts := pushRemoteCacheConfiguration / packagedArtifacts := Def.uncached(
(Def (Def
.task { (pushRemoteCacheConfiguration / remoteCacheArtifacts).value }) .task { (pushRemoteCacheConfiguration / remoteCacheArtifacts).value })
.flatMapTask { case artifacts => .flatMapTask { case artifacts =>
@ -300,11 +301,12 @@ object RemoteCache {
.join .join
.apply(_.join.map(_.toMap)) .apply(_.join.map(_.toMap))
} }
.value, .value
pushRemoteCacheConfiguration / remoteCacheArtifacts := { ),
pushRemoteCacheConfiguration / remoteCacheArtifacts := Def.uncached {
List((packageCache / remoteCacheArtifact).value) List((packageCache / remoteCacheArtifact).value)
}, },
pullRemoteCache := { pullRemoteCache := Def.uncached {
import scala.jdk.CollectionConverters.* import scala.jdk.CollectionConverters.*
val log = streams.value.log val log = streams.value.log
val r = remoteCacheResolvers.value.head val r = remoteCacheResolvers.value.head

View File

@ -62,16 +62,18 @@ object ScriptedPlugin extends AutoPlugin {
override lazy val projectSettings: Seq[Setting[?]] = Seq( override lazy val projectSettings: Seq[Setting[?]] = Seq(
ivyConfigurations ++= Seq(ScriptedConf, ScriptedLaunchConf), ivyConfigurations ++= Seq(ScriptedConf, ScriptedLaunchConf),
scriptedSbt := (pluginCrossBuild / sbtVersion).value, scriptedSbt := (pluginCrossBuild / sbtVersion).value,
sbtLauncher := getJars(ScriptedLaunchConf) sbtLauncher := Def.uncached(
getJars(ScriptedLaunchConf)
.map(_.get().head) .map(_.get().head)
.value, .value
),
sbtTestDirectory := sourceDirectory.value / "sbt-test", sbtTestDirectory := sourceDirectory.value / "sbt-test",
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"org.scala-sbt" %% "scripted-sbt" % scriptedSbt.value % ScriptedConf, "org.scala-sbt" %% "scripted-sbt" % scriptedSbt.value % ScriptedConf,
"org.scala-sbt" % "sbt-launch" % scriptedSbt.value % ScriptedLaunchConf "org.scala-sbt" % "sbt-launch" % scriptedSbt.value % ScriptedLaunchConf
), ),
scriptedClasspath := getJars(ScriptedConf).value, scriptedClasspath := Def.uncached(getJars(ScriptedConf).value),
scriptedTests := scriptedTestsTask.value, scriptedTests := Def.uncached(scriptedTestsTask.value),
scriptedParallelInstances := 1, scriptedParallelInstances := 1,
scriptedBatchExecution := { scriptedBatchExecution := {
val binVersion = CrossVersionUtil.binarySbtVersion(scriptedSbt.value) val binVersion = CrossVersionUtil.binarySbtVersion(scriptedSbt.value)
@ -82,8 +84,8 @@ object ScriptedPlugin extends AutoPlugin {
case _ => false case _ => false
} }
}, },
scriptedRun := scriptedRunTask.value, scriptedRun := Def.uncached(scriptedRunTask.value),
scriptedDependencies := { scriptedDependencies := Def.uncached {
def use[A](@deprecated("unused", "") x: A*): Unit = () // avoid unused warnings def use[A](@deprecated("unused", "") x: A*): Unit = () // avoid unused warnings
val analysis = (Test / Keys.compile).value val analysis = (Test / Keys.compile).value
val pub = publishLocal.all(ScopeFilter(projects = inDependencies(ThisProject))).value val pub = publishLocal.all(ScopeFilter(projects = inDependencies(ThisProject))).value

View File

@ -257,7 +257,9 @@ object LMCoursier {
} }
def publicationsSetting(packageConfigs: Seq[(Configuration, CConfiguration)]): Def.Setting[?] = { def publicationsSetting(packageConfigs: Seq[(Configuration, CConfiguration)]): Def.Setting[?] = {
csrPublications := CoursierArtifactsTasks.coursierPublicationsTask(packageConfigs*).value csrPublications := Def.uncached(
CoursierArtifactsTasks.coursierPublicationsTask(packageConfigs*).value
)
} }
// This emulates Ivy's credential registration which basically keeps mutating global registry // This emulates Ivy's credential registration which basically keeps mutating global registry

View File

@ -16,6 +16,7 @@ import Def.Setting
import sbt.io.Hash import sbt.io.Hash
import sbt.internal.util.{ Attributed, StringAttributeMap } import sbt.internal.util.{ Attributed, StringAttributeMap }
import sbt.internal.inc.{ FileAnalysisStore, ReflectUtilities } import sbt.internal.inc.{ FileAnalysisStore, ReflectUtilities }
import sbt.util.CacheImplicits.given
import xsbti.{ FileConverter, VirtualFileRef } import xsbti.{ FileConverter, VirtualFileRef }
import xsbti.compile.CompileAnalysis import xsbti.compile.CompileAnalysis

View File

@ -97,6 +97,8 @@ object BuildUtil {
:: "import _root_.sbt.BareBuildSyntax.*" :: "import _root_.sbt.BareBuildSyntax.*"
:: "import _root_.sbt.Keys.*" :: "import _root_.sbt.Keys.*"
:: "import _root_.sbt.nio.Keys.*" :: "import _root_.sbt.nio.Keys.*"
:: "import _root_.sbt.util.CacheImplicits.given"
:: "import _root_.sbt.librarymanagement.LibraryManagementCodec.given"
:: Nil) :: Nil)
def getImports(unit: BuildUnit): Seq[String] = def getImports(unit: BuildUnit): Seq[String] =

View File

@ -22,6 +22,7 @@ import Keys.*
import Configurations.{ Compile, Runtime } import Configurations.{ Compile, Runtime }
import sbt.ProjectExtra.{ extract, runUnloadHooks, setProject } import sbt.ProjectExtra.{ extract, runUnloadHooks, setProject }
import sbt.SlashSyntax0.* import sbt.SlashSyntax0.*
import sbt.librarymanagement.LibraryManagementCodec.given
import java.io.File import java.io.File
import org.apache.ivy.core.module.{ descriptor, id } import org.apache.ivy.core.module.{ descriptor, id }
import descriptor.ModuleDescriptor, id.ModuleRevisionId import descriptor.ModuleDescriptor, id.ModuleRevisionId

View File

@ -52,7 +52,7 @@ object IvyConsole {
val depSettings: Seq[Setting[?]] = Seq( val depSettings: Seq[Setting[?]] = Seq(
libraryDependencies ++= managed.reverse, libraryDependencies ++= managed.reverse,
resolvers ++= repos.reverse.toVector, resolvers ++= repos.reverse.toVector,
Compile / unmanagedJars ++= { Compile / unmanagedJars ++= Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val u = unmanaged.reverse.map(_.toPath).map(converter.toVirtualFile) val u = unmanaged.reverse.map(_.toPath).map(converter.toVirtualFile)
u: Seq[HashedVirtualFileRef] u: Seq[HashedVirtualFileRef]

View File

@ -1331,7 +1331,7 @@ private[sbt] object Load {
Seq( Seq(
sbtPlugin :== true, sbtPlugin :== true,
isMetaBuild :== true, isMetaBuild :== true,
pluginData := { pluginData := Def.uncached {
val prod = (Configurations.Runtime / exportedProducts).value val prod = (Configurations.Runtime / exportedProducts).value
val cp = (Configurations.Runtime / fullClasspath).value val cp = (Configurations.Runtime / fullClasspath).value
val opts = (Configurations.Compile / scalacOptions).value val opts = (Configurations.Compile / scalacOptions).value
@ -1357,7 +1357,7 @@ private[sbt] object Load {
converter, converter,
) )
}, },
scalacOptions += "-Wconf:cat=unused-nowarn:s", scalacOptions += Def.uncached("-Wconf:cat=unused-nowarn:s"),
onLoadMessage := ("loading project definition from " + baseDirectory.value) onLoadMessage := ("loading project definition from " + baseDirectory.value)
) )
) )

View File

@ -54,8 +54,9 @@ object Script {
val embeddedSettings = blocks(script).flatMap { block => val embeddedSettings = blocks(script).flatMap { block =>
evaluate(eval(), vf, block.lines, currentUnit.imports, block.offset + 1)(currentLoader) evaluate(eval(), vf, block.lines, currentUnit.imports, block.offset + 1)(currentLoader)
} }
val scriptAsSource = (Compile / sources) := script :: Nil val scriptAsSource = (Compile / sources) := Def.uncached(script :: Nil)
val asScript = scalacOptions ++= Seq("-Xscript", script.getName.stripSuffix(".scala")) val asScript =
scalacOptions ++= Def.uncached(Seq("-Xscript", script.getName.stripSuffix(".scala")))
val scriptSettings = Seq( val scriptSettings = Seq(
asScript, asScript,
scriptAsSource, scriptAsSource,

View File

@ -193,7 +193,7 @@ object IvyXml {
task: TaskKey[T], task: TaskKey[T],
shadedConfigOpt: Option[Configuration] shadedConfigOpt: Option[Configuration]
): Setting[Task[T]] = ): Setting[Task[T]] =
task := task.dependsOnTask { task := Def.uncached(task.dependsOnTask {
Def.task { Def.task {
val currentProject = { val currentProject = {
val proj = csrProject.value val proj = csrProject.value
@ -207,7 +207,7 @@ object IvyXml {
sbt.Keys.streams.value.log sbt.Keys.streams.value.log
) )
} }
}.value }.value)
private lazy val needsIvyXmlLocal = Seq(publishLocalConfiguration) ++ getPubConf( private lazy val needsIvyXmlLocal = Seq(publishLocalConfiguration) ++ getPubConf(
"makeIvyXmlLocalConfiguration" "makeIvyXmlLocalConfiguration"

View File

@ -336,7 +336,7 @@ object BuildServerProtocol {
bspInternalDependencyConfigurations := internalDependencyConfigurationsSetting.value, bspInternalDependencyConfigurations := internalDependencyConfigurationsSetting.value,
bspScalaTestClassesItem := scalaTestClassesTask.value, bspScalaTestClassesItem := scalaTestClassesTask.value,
bspScalaMainClassesItem := scalaMainClassesTask.value, bspScalaMainClassesItem := scalaMainClassesTask.value,
Keys.compile / bspReporter := { Keys.compile / bspReporter := Def.uncached {
val targetId = bspTargetIdentifier.value val targetId = bspTargetIdentifier.value
val bspCompileStateInstance = bspCompileState.value val bspCompileStateInstance = bspCompileState.value
val converter = fileConverter.value val converter = fileConverter.value

View File

@ -20,6 +20,7 @@ import sbt.internal.util.AttributeKey
import sbt.internal.util.complete.Parser import sbt.internal.util.complete.Parser
import sbt.nio.file.{ FileAttributes, FileTreeView, Glob, PathFilter } import sbt.nio.file.{ FileAttributes, FileTreeView, Glob, PathFilter }
import sbt.* import sbt.*
import sbt.util.cacheLevel
import scala.concurrent.duration.FiniteDuration import scala.concurrent.duration.FiniteDuration
@ -39,6 +40,8 @@ object Keys {
settingKey[PathFilter]("A filter to apply to the input sources of a task.") settingKey[PathFilter]("A filter to apply to the input sources of a task.")
val fileInputExcludeFilter = val fileInputExcludeFilter =
settingKey[PathFilter]("An exclusion filter to apply to the input sources of a task.") settingKey[PathFilter]("An exclusion filter to apply to the input sources of a task.")
@cacheLevel(include = Array.empty)
val inputFileStamper = settingKey[FileStamper]( val inputFileStamper = settingKey[FileStamper](
"Toggles the file stamping implementation used to determine whether or not a file has been modified." "Toggles the file stamping implementation used to determine whether or not a file has been modified."
) )
@ -169,9 +172,13 @@ object Keys {
private[sbt] val allInputPathsAndAttributes = private[sbt] val allInputPathsAndAttributes =
taskKey[Seq[(Path, FileAttributes)]]("Get all of the file inputs for a task") taskKey[Seq[(Path, FileAttributes)]]("Get all of the file inputs for a task")
.withRank(Invisible) .withRank(Invisible)
@cacheLevel(include = Array.empty)
private[sbt] val unmanagedFileStampCache = taskKey[FileStamp.Cache]( private[sbt] val unmanagedFileStampCache = taskKey[FileStamp.Cache](
"Map of managed file stamps that may be cleared between task evaluation runs." "Map of managed file stamps that may be cleared between task evaluation runs."
).withRank(Invisible) ).withRank(Invisible)
@cacheLevel(include = Array.empty)
private[sbt] val managedFileStampCache = taskKey[FileStamp.Cache]( private[sbt] val managedFileStampCache = taskKey[FileStamp.Cache](
"Map of managed file stamps that may be cleared between task evaluation runs." "Map of managed file stamps that may be cleared between task evaluation runs."
).withRank(Invisible) ).withRank(Invisible)

View File

@ -127,7 +127,7 @@ private[sbt] object Settings {
scopedKey.scope.task.toOption.toSeq.map { key => scopedKey.scope.task.toOption.toSeq.map { key =>
val updatedKey = Def.ScopedKey(scopedKey.scope.copy(task = Zero), key) val updatedKey = Def.ScopedKey(scopedKey.scope.copy(task = Zero), key)
scopedKey.scope / transitiveDynamicInputs := scopedKey.scope / transitiveDynamicInputs :=
WatchTransitiveDependencies.task(updatedKey).value Def.uncached(WatchTransitiveDependencies.task(updatedKey).value)
} }
case dynamicDependency.key => (scopedKey.scope / dynamicDependency := { () }) :: Nil case dynamicDependency.key => (scopedKey.scope / dynamicDependency := { () }) :: Nil
case transitiveClasspathDependency.key => case transitiveClasspathDependency.key =>
@ -158,7 +158,7 @@ private[sbt] object Settings {
private[sbt] def inputPathSettings(setting: Def.Setting[?]): Seq[Def.Setting[?]] = { private[sbt] def inputPathSettings(setting: Def.Setting[?]): Seq[Def.Setting[?]] = {
val scopedKey = setting.key val scopedKey = setting.key
val scope = scopedKey.scope val scope = scopedKey.scope
(scope / Keys.allInputPathsAndAttributes := { (scope / Keys.allInputPathsAndAttributes := Def.uncached {
val view = (scope / fileTreeView).value val view = (scope / fileTreeView).value
val inputs = (scope / fileInputs).value val inputs = (scope / fileInputs).value
val stamper = (scope / inputFileStamper).value val stamper = (scope / inputFileStamper).value
@ -186,7 +186,7 @@ private[sbt] object Settings {
* @return a task definition that retrieves all of the input paths scoped to the input key. * @return a task definition that retrieves all of the input paths scoped to the input key.
*/ */
private def allFilesImpl(scope: Scope): Def.Setting[?] = { private def allFilesImpl(scope: Scope): Def.Setting[?] = {
addTaskDefinition(scope / Keys.allInputFiles := { addTaskDefinition(scope / Keys.allInputFiles := Def.uncached {
val filter = val filter =
(scope / fileInputIncludeFilter).value && !(scope / fileInputExcludeFilter).value (scope / fileInputIncludeFilter).value && !(scope / fileInputExcludeFilter).value
(scope / Keys.allInputPathsAndAttributes).value.collect { (scope / Keys.allInputPathsAndAttributes).value.collect {
@ -218,7 +218,7 @@ private[sbt] object Settings {
changeKey: TaskKey[Seq[(Path, FileStamp)] => FileChanges], changeKey: TaskKey[Seq[(Path, FileStamp)] => FileChanges],
stampKey: TaskKey[Seq[(Path, FileStamp)]] stampKey: TaskKey[Seq[(Path, FileStamp)]]
): Def.Setting[?] = ): Def.Setting[?] =
addTaskDefinition(scope / changeKey := { addTaskDefinition(scope / changeKey := Def.uncached {
val current = (scope / stampKey).value val current = (scope / stampKey).value
changedFiles(_, current) changedFiles(_, current)
}) })
@ -262,7 +262,7 @@ private[sbt] object Settings {
* @return a task specific clean implementation * @return a task specific clean implementation
*/ */
private[sbt] def cleanImpl(scope: Scope): Def.Setting[?] = addTaskDefinition { private[sbt] def cleanImpl(scope: Scope): Def.Setting[?] = addTaskDefinition {
scope / sbt.Keys.clean := Clean.task(scope, full = false).value scope / sbt.Keys.clean := Def.uncached(Clean.task(scope, full = false).value)
} }
/** /**
@ -275,7 +275,7 @@ private[sbt] object Settings {
private[sbt] def cleanImpl[T: JsonFormat: ToSeqPath](taskKey: TaskKey[T]): Def.Setting[?] = { private[sbt] def cleanImpl[T: JsonFormat: ToSeqPath](taskKey: TaskKey[T]): Def.Setting[?] = {
val taskScope = taskKey.scope.rescope(taskKey.key) val taskScope = taskKey.scope.rescope(taskKey.key)
addTaskDefinition( addTaskDefinition(
taskScope / sbt.Keys.clean := taskScope / sbt.Keys.clean := Def.uncached(
// the clean file task needs to run first because the previous cache gets blown away // the clean file task needs to run first because the previous cache gets blown away
// by the second task // by the second task
Def Def
@ -287,6 +287,7 @@ private[sbt] object Settings {
} }
.value .value
) )
)
} }
/** /**
@ -300,7 +301,7 @@ private[sbt] object Settings {
private[sbt] def fileStamps(scopedKey: Def.ScopedKey[?]): Def.Setting[?] = { private[sbt] def fileStamps(scopedKey: Def.ScopedKey[?]): Def.Setting[?] = {
import scala.collection.parallel.CollectionConverters.* import scala.collection.parallel.CollectionConverters.*
val scope = scopedKey.scope val scope = scopedKey.scope
addTaskDefinition(scope / Keys.inputFileStamps := { addTaskDefinition(scope / Keys.inputFileStamps := Def.uncached {
val cache = (scope / unmanagedFileStampCache).value val cache = (scope / unmanagedFileStampCache).value
val stamper = (scope / Keys.inputFileStamper).value val stamper = (scope / Keys.inputFileStamper).value
val stampFile: Path => Option[(Path, FileStamp)] = val stampFile: Path => Option[(Path, FileStamp)] =
@ -335,7 +336,7 @@ private[sbt] object Settings {
} }
private def allOutputPathsImpl(scope: Scope): Def.Setting[?] = private def allOutputPathsImpl(scope: Scope): Def.Setting[?] =
addTaskDefinition(scope / allOutputFiles := { addTaskDefinition(scope / allOutputFiles := Def.uncached {
val filter = val filter =
(scope / fileOutputIncludeFilter).value && !(scope / fileOutputExcludeFilter).value (scope / fileOutputIncludeFilter).value && !(scope / fileOutputExcludeFilter).value
val view = (scope / fileTreeView).value val view = (scope / fileTreeView).value
@ -361,7 +362,7 @@ private[sbt] object Settings {
}) })
private def outputFileStampsImpl(scope: Scope): Def.Setting[?] = private def outputFileStampsImpl(scope: Scope): Def.Setting[?] =
addTaskDefinition(scope / outputFileStamps := { addTaskDefinition(scope / outputFileStamps := Def.uncached {
val stamper: Path => Option[FileStamp] = (scope / outputFileStamper).value match { val stamper: Path => Option[FileStamp] = (scope / outputFileStamper).value match {
case LastModified => FileStamp.lastModified case LastModified => FileStamp.lastModified
case Hash => FileStamp.hash case Hash => FileStamp.hash

View File

@ -38,11 +38,11 @@ object DependencyTreeSettings {
// dependency tree // dependency tree
dependencyTreeIgnoreMissingUpdate / updateOptions := updateOptions.value dependencyTreeIgnoreMissingUpdate / updateOptions := updateOptions.value
.withCachedResolution(false), .withCachedResolution(false),
dependencyTreeIgnoreMissingUpdate / ivyConfiguration := { dependencyTreeIgnoreMissingUpdate / ivyConfiguration := Def.uncached {
// inTask will make sure the new definition will pick up `updateOptions in dependencyTreeIgnoreMissingUpdate` // inTask will make sure the new definition will pick up `updateOptions in dependencyTreeIgnoreMissingUpdate`
Project.inTask(dependencyTreeIgnoreMissingUpdate, Classpaths.mkIvyConfiguration).value Project.inTask(dependencyTreeIgnoreMissingUpdate, Classpaths.mkIvyConfiguration).value
}, },
dependencyTreeIgnoreMissingUpdate / ivyModule := { dependencyTreeIgnoreMissingUpdate / ivyModule := Def.uncached {
// concatenating & inlining ivySbt & ivyModule default task implementations, as `SbtAccess.inTask` does // concatenating & inlining ivySbt & ivyModule default task implementations, as `SbtAccess.inTask` does
// NOT correctly force the scope when applied to `TaskKey.toTask` instances (as opposed to raw // NOT correctly force the scope when applied to `TaskKey.toTask` instances (as opposed to raw
// implementations like `Classpaths.mkIvyConfiguration` or `Classpaths.updateTask`) // implementations like `Classpaths.mkIvyConfiguration` or `Classpaths.updateTask`)
@ -52,7 +52,7 @@ object DependencyTreeSettings {
// don't fail on missing dependencies // don't fail on missing dependencies
dependencyTreeIgnoreMissingUpdate / updateConfiguration := updateConfiguration.value dependencyTreeIgnoreMissingUpdate / updateConfiguration := updateConfiguration.value
.withMissingOk(true), .withMissingOk(true),
dependencyTreeIgnoreMissingUpdate := { dependencyTreeIgnoreMissingUpdate := Def.uncached {
// inTask will make sure the new definition will pick up `ivyModule/updateConfiguration in ignoreMissingUpdate` // inTask will make sure the new definition will pick up `ivyModule/updateConfiguration in ignoreMissingUpdate`
Project.inTask(dependencyTreeIgnoreMissingUpdate, Classpaths.updateTask).value Project.inTask(dependencyTreeIgnoreMissingUpdate, Classpaths.updateTask).value
}, },
@ -67,7 +67,7 @@ object DependencyTreeSettings {
dependencyTreeCrossProjectId := CrossVersion(scalaVersion.value, scalaBinaryVersion.value)( dependencyTreeCrossProjectId := CrossVersion(scalaVersion.value, scalaBinaryVersion.value)(
projectID.value projectID.value
), ),
dependencyTreeModuleGraph0 := { dependencyTreeModuleGraph0 := Def.uncached {
val sv = scalaVersion.value val sv = scalaVersion.value
val g = dependencyTreeIgnoreMissingUpdate.value val g = dependencyTreeIgnoreMissingUpdate.value
.configuration(configuration.value) .configuration(configuration.value)
@ -107,12 +107,14 @@ object DependencyTreeSettings {
val config = configuration.value val config = configuration.value
target.value / s"dependencies-${config.toString}.dot" target.value / s"dependencies-${config.toString}.dot"
}, },
dependencyDot / asString := rendering.DOT.dotGraph( dependencyDot / asString := Def.uncached(
rendering.DOT.dotGraph(
dependencyTreeModuleGraph0.value, dependencyTreeModuleGraph0.value,
dependencyDotHeader.value, dependencyDotHeader.value,
dependencyDotNodeLabel.value, dependencyDotNodeLabel.value,
rendering.DOT.HTMLLabelRendering.AngleBrackets, rendering.DOT.HTMLLabelRendering.AngleBrackets,
dependencyDotNodeColors.value dependencyDotNodeColors.value
)
), ),
dependencyDot := writeToFile(dependencyDot / asString, dependencyDotFile).value, dependencyDot := writeToFile(dependencyDot / asString, dependencyDotFile).value,
dependencyDotHeader := dependencyDotHeader :=

View File

@ -42,11 +42,13 @@ object JUnitXmlReportPlugin extends AutoPlugin {
lazy val testReportSettings: Seq[Setting[?]] = Seq( lazy val testReportSettings: Seq[Setting[?]] = Seq(
testReportsDirectory := target.value / (prefix(configuration.value.name) + "reports"), testReportsDirectory := target.value / (prefix(configuration.value.name) + "reports"),
testListeners += new JUnitXmlTestsListener( testListeners += Def.uncached {
JUnitXmlTestsListener(
testReportsDirectory.value, testReportsDirectory.value,
SysProp.legacyTestReport, SysProp.legacyTestReport,
streams.value.log streams.value.log
) )
}
) )
} }

View File

@ -15,6 +15,7 @@ import Keys.*
import sbt.internal.SysProp import sbt.internal.SysProp
import sbt.librarymanagement.syntax.* import sbt.librarymanagement.syntax.*
import sbt.librarymanagement.{ Configuration, CrossVersion } import sbt.librarymanagement.{ Configuration, CrossVersion }
import sbt.librarymanagement.LibraryManagementCodec.given
import ProjectExtra.inConfig import ProjectExtra.inConfig
import sbt.internal.inc.ScalaInstance import sbt.internal.inc.ScalaInstance
import sbt.ScopeFilter.Make.* import sbt.ScopeFilter.Make.*

View File

@ -6,4 +6,7 @@ val updateReports = Def.taskDyn { updateClassifiers.all(ScopeFilter(configuratio
val newTask = taskKey[Unit]("") val newTask = taskKey[Unit]("")
newTask := updateReports.value newTask := {
updateReports.value
()
}

View File

@ -1,9 +1,11 @@
Global / localCacheDirectory := baseDirectory.value / "diskcache"
ThisBuild / evictionErrorLevel := Level.Info ThisBuild / evictionErrorLevel := Level.Info
libraryDependencies += "org.scala-sbt" % "sbt" % sbtVersion.value libraryDependencies += "org.scala-sbt" % "sbt" % sbtVersion.value
lazy val expectErrorNotCrash = taskKey[Unit]("Ensures that sbt properly set types on Trees so that the compiler doesn't crash on a bad reference to .value, but gives a proper error instead.") lazy val expectErrorNotCrash = taskKey[Unit]("Ensures that sbt properly set types on Trees so that the compiler doesn't crash on a bad reference to .value, but gives a proper error instead.")
expectErrorNotCrash := { expectErrorNotCrash := Def.uncached {
val fail = (Compile / compileIncremental).failure.value val fail = (Compile / compileIncremental).failure.value
Incomplete.allExceptions(fail).headOption match Incomplete.allExceptions(fail).headOption match
case Some(x: xsbti.CompileFailed) => () case Some(x: xsbti.CompileFailed) => ()

View File

@ -1,8 +1,9 @@
import sbt._, Keys._ import sbt.*, Keys.*
import Def.Initialize import Def.Initialize
import complete.{DefaultParsers, Parser} import complete.{DefaultParsers, Parser}
import sbt.librarymanagement.LibraryManagementCodec.given
object A { object A:
val x1: Initialize[Task[Int]] = Def.task { 3 } val x1: Initialize[Task[Int]] = Def.task { 3 }
val y1 = Def.task { x1.value } val y1 = Def.task { x1.value }
@ -11,4 +12,3 @@ object A {
val x3: Initialize[Int] = Def.setting { 3 } val x3: Initialize[Int] = Def.setting { 3 }
val y3 = Def.setting { x3.value } val y3 = Def.setting { x3.value }
}

View File

@ -1,7 +1,7 @@
import sbt._ import sbt.*
import Def.Initialize import Def.Initialize
import sbt.librarymanagement.LibraryManagementCodec.given
object A { object A:
val x1: Initialize[Task[Int]] = Def.task { 3 } val x1: Initialize[Task[Int]] = Def.task { 3 }
val y1 = x1.value val y1 = x1.value
}

View File

@ -1,8 +1,8 @@
import sbt._, Keys._ import sbt.*, Keys.*
import Def.Initialize import Def.Initialize
import complete.{DefaultParsers, Parser} import complete.{DefaultParsers, Parser}
import sbt.librarymanagement.LibraryManagementCodec.given
object A { object A:
val x1: Initialize[Parser[Int]] = Def.setting { DefaultParsers.success(3) } val x1: Initialize[Parser[Int]] = Def.setting { DefaultParsers.success(3) }
val y1 = Def.task { x1.parsed } val y1 = Def.task { x1.parsed }
}

View File

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

View File

@ -1,4 +1,4 @@
import sbt._ import sbt.*
object FooPlugin extends AutoPlugin { object FooPlugin extends AutoPlugin {
override def trigger = noTrigger override def trigger = noTrigger
@ -9,6 +9,6 @@ object FooPlugin extends AutoPlugin {
import autoImport._ import autoImport._
override def buildSettings = super.buildSettings ++ Seq( override def buildSettings = super.buildSettings ++ Seq(
myTask := println("Called my task") myTask := Def.uncached(println("Called my task"))
) )
} }

View File

@ -35,10 +35,10 @@ lazy val root = (project in file("."))
zeroAction := { IO.write(output.value, s"zero\n", append = true) }, zeroAction := { IO.write(output.value, s"zero\n", append = true) },
posAction := { IO.write(output.value, s"pos\n", append = true) }, posAction := { IO.write(output.value, s"pos\n", append = true) },
TaskKey[Unit]("checkTrue") := checkLines("true"), TaskKey[Unit]("checkTrue") := checkLines("true").value,
TaskKey[Unit]("checkFalse") := checkLines("false"), TaskKey[Unit]("checkFalse") := checkLines("false").value,
TaskKey[Unit]("checkNeg") := checkLines("neg"), TaskKey[Unit]("checkNeg") := checkLines("neg").value,
TaskKey[Unit]("checkZero") := checkLines("zero"), TaskKey[Unit]("checkZero") := checkLines("zero").value,
// https://github.com/sbt/sbt/issues/5625 // https://github.com/sbt/sbt/issues/5625
javacOptions ++= ( javacOptions ++= (
@ -49,6 +49,6 @@ lazy val root = (project in file("."))
def checkLines(content: String) = Def.task { def checkLines(content: String) = Def.task {
val lines = IO.read(output.value).linesIterator.toList val lines = IO.read(output.value).linesIterator.toList
assert(lines == List("true"), s"$content was expected but found: $lines") assert(lines == List(content), s"$content was expected but found: $lines")
() ()
} }

View File

@ -16,11 +16,11 @@ lazy val foo = project
.settings( .settings(
crossScalaVersions := Seq(scala212, scala213), crossScalaVersions := Seq(scala212, scala213),
libraryDependencies += "org.scalatest" %% "scalatest" % "3.1.0", libraryDependencies += "org.scalatest" %% "scalatest" % "3.1.0",
check := { check := Def.uncached {
// This tests that +check will respect bar's crossScalaVersions and not switch // This tests that +check will respect bar's crossScalaVersions and not switch
val x = (LocalProject("bar") / scalaVersion).value val x = (LocalProject("bar") / scalaVersion).value
assert(x == scala212, s"$x == $scala212") assert(x == scala212, s"$x == $scala212")
(Compile / compile).value Def.unit((Compile / compile).value)
}, },
(Test / testOnly) := { (Test / testOnly) := {
// This tests that +testOnly will respect bar's crossScalaVersions and not switch // This tests that +testOnly will respect bar's crossScalaVersions and not switch
@ -28,35 +28,37 @@ lazy val foo = project
assert(x == scala212, s"$x == $scala212") assert(x == scala212, s"$x == $scala212")
val _ = (Test / testOnly).evaluated val _ = (Test / testOnly).evaluated
}, },
compile2 := { compile2 := Def.uncached {
// This tests that +build will ignore bar's crossScalaVersions and use root's like sbt 0.13 // This tests that +build will ignore bar's crossScalaVersions and use root's like sbt 0.13
val x = (LocalProject("bar") / scalaVersion).value val x = (LocalProject("bar") / scalaVersion).value
assert(x == scalaVersion.value, s"$x == ${scalaVersion.value}") assert(x == scalaVersion.value, s"$x == ${scalaVersion.value}")
(Compile / compile).value Def.unit((Compile / compile).value)
}, },
) )
lazy val bar = project lazy val bar = project
.settings( .settings(
crossScalaVersions := Seq(scala212), crossScalaVersions := Seq(scala212),
check := (Compile / compile).value, check := Def.uncached {
compile2 := (Compile / compile).value, Def.unit((Compile / compile).value)
},
compile2 := Def.uncached(Def.unit((Compile / compile).value)),
) )
lazy val baz = project lazy val baz = project
.settings( .settings(
crossScalaVersions := Seq(scala213), crossScalaVersions := Seq(scala213),
check := { check := Def.uncached {
// This tests that +baz/check will respect bar's crossScalaVersions and not switch // This tests that +baz/check will respect bar's crossScalaVersions and not switch
val x = (LocalProject("bar") / scalaVersion).value val x = (LocalProject("bar") / scalaVersion).value
assert(x == scala212, s"$x == $scala212") assert(x == scala212, s"$x == $scala212")
(Compile / compile).value Def.unit((Compile / compile).value)
}, },
) )
lazy val client = project lazy val client = project
.settings( .settings(
crossScalaVersions := Seq(scala212, scala213), crossScalaVersions := Seq(scala212, scala213),
check := (Compile / compile).value, check := Def.uncached(Def.unit((Compile / compile).value)),
compile2 := (Compile / compile).value, compile2 := Def.uncached(Def.unit((Compile / compile).value)),
) )

View File

@ -68,14 +68,14 @@ val c = project.settings(apiBaseSetting)
val d = project val d = project
.dependsOn(c) .dependsOn(c)
.settings( .settings(
externalResolvers := Seq(aResolver.value, bResolver.value), externalResolvers := Def.uncached(Seq(aResolver.value, bResolver.value)),
addDep("a"), addDep("a"),
addDep("b"), addDep("b"),
checkApiMappings := { checkApiMappings := Def.uncached {
val actual = (Compile / doc / apiMappings).value val actual = (Compile / doc / apiMappings).value
println("Actual API Mappings: " + actual.mkString("\n\t", "\n\t", "")) println("Actual API Mappings: " + actual.mkString("\n\t", "\n\t", ""))
val expected = expectedMappings.value val expected = expectedMappings.value
println("Expected API Mappings: " + expected.mkString("\n\t", "\n\t", "")) println("Expected API Mappings: " + expected.mkString("\n\t", "\n\t", ""))
assert(actual == expected) assert(actual.toString.replaceAll(">sha256-.*/256", "") == expected.toString)
} }
) )

View File

@ -1,7 +1,7 @@
import sjsonnew.BasicJsonProtocol._ import sjsonnew.BasicJsonProtocol._
val cacheTask = taskKey[Int]("task") val cacheTask = taskKey[Int]("task")
cacheTask := 1 cacheTask := Def.uncached(1)
val checkTask = inputKey[Unit]("validate that the correct value is set by cacheTask") val checkTask = inputKey[Unit]("validate that the correct value is set by cacheTask")
checkTask := { checkTask := {

View File

@ -1,3 +1,5 @@
Global / localCacheDirectory := baseDirectory.value / "diskcache"
import sjsonnew.BasicJsonProtocol._ import sjsonnew.BasicJsonProtocol._
lazy val a0 = 1 lazy val a0 = 1
@ -12,11 +14,11 @@ lazy val checkNext = inputKey[Unit]("check-next")
// Also, it is ok for b to refer to b.previous: // Also, it is ok for b to refer to b.previous:
// normally, b's definition could not refer to plain b.value because it would be undefined // normally, b's definition could not refer to plain b.value because it would be undefined
a := b.previous.getOrElse(a0) a := Def.uncached(b.previous.getOrElse(a0))
b := a.previous.getOrElse(a0) + b.previous.getOrElse(b0) b := Def.uncached(a.previous.getOrElse(a0) + b.previous.getOrElse(b0))
next := (a.value, b.value) next := Def.uncached((a.value, b.value))
def parser = { def parser = {
import complete.DefaultParsers._ import complete.DefaultParsers._

View File

@ -7,13 +7,13 @@ lazy val checkScopes = inputKey[Unit]("check scopes")
lazy val subA = project lazy val subA = project
lazy val subB = project lazy val subB = project
x := 3 x := Def.uncached(3)
Compile / y / x := 7 Compile / y / x := Def.uncached(7)
Runtime / y / x := 13 Runtime / y / x := Def.uncached(13)
subA / Compile / x := { subA / Compile / x := Def.uncached {
val xcy = (Compile / y / x).previous getOrElse 0 // 7 val xcy = (Compile / y / x).previous getOrElse 0 // 7
// verify that This is properly resolved to Global and not the defining key's scope // verify that This is properly resolved to Global and not the defining key's scope
val xg = x.previous getOrElse 0 // 3 val xg = x.previous getOrElse 0 // 3
@ -22,7 +22,7 @@ subA / Compile / x := {
} }
inConfig(Compile)(Seq( inConfig(Compile)(Seq(
subB / y := { subB / y := Def.uncached {
// verify that the referenced key gets delegated // verify that the referenced key gets delegated
val xty = (Test / y / x).previous getOrElse 0 // 13 val xty = (Test / y / x).previous getOrElse 0 // 13
// verify that inConfig gets applied // verify that inConfig gets applied
@ -37,7 +37,7 @@ def parser = {
(Space ~> IntBasic) ~ (Space ~> IntBasic) (Space ~> IntBasic) ~ (Space ~> IntBasic)
} }
checkScopes := { checkScopes := Def.uncached {
val (expectedX, expectedY) = parser.parsed val (expectedX, expectedY) = parser.parsed
val actualX = (subA/ Compile / x).value val actualX = (subA/ Compile / x).value
val actualY = (subB / Test / y).value val actualY = (subB / Test / y).value

View File

@ -8,8 +8,8 @@ lazy val root = (project in file("."))
.settings( .settings(
name := "promise", name := "promise",
output := baseDirectory.value / "output.txt", output := baseDirectory.value / "output.txt",
midpoint := Def.promise[Int], midpoint := Def.uncached(Def.promise[Int]),
longRunning := { longRunning := Def.uncached {
val p = midpoint.value val p = midpoint.value
val st = streams.value val st = streams.value
IO.write(output.value, "start\n", append = true) IO.write(output.value, "start\n", append = true)
@ -18,21 +18,21 @@ lazy val root = (project in file("."))
Thread.sleep(100) Thread.sleep(100)
IO.write(output.value, "end\n", append = true) IO.write(output.value, "end\n", append = true)
}, },
midTask := { midTask := Def.uncached {
val st = streams.value val st = streams.value
val x = midpoint.await.value val x = midpoint.await.value
IO.write(output.value, s"$x in the middle\n", append = true) IO.write(output.value, s"$x in the middle\n", append = true)
}, },
joinTwo := { joinTwo := Def.uncached {
val x = longRunning.value val x = longRunning.value
val y = midTask.value val y = midTask.value
}, },
TaskKey[Unit]("check") := { TaskKey[Unit]("check") := Def.uncached {
val lines = IO.read(output.value).linesIterator.toList val lines = IO.read(output.value).linesIterator.toList
assert(lines == List("start", "5 in the middle", "end")) assert(lines == List("start", "5 in the middle", "end"))
() ()
}, },
TaskKey[Unit]("check2") := { TaskKey[Unit]("check2") := Def.uncached {
val lines = IO.read(output.value).linesIterator.toList val lines = IO.read(output.value).linesIterator.toList
assert(lines == List("start", "end", "5 in the middle")) assert(lines == List("start", "end", "5 in the middle"))
() ()

View File

@ -15,9 +15,10 @@ lazy val baz = project
scalaVersion := "2.12.20", scalaVersion := "2.12.20",
) )
someTask := { someTask := Def.uncached {
val x = target.value / (name.value + ".txt") val x = target.value / (name.value + ".txt")
val s = streams.value val s = streams.value
s.log.info(s"writing $x") s.log.info(s"writing $x")
IO.touch(x) IO.touch(x)
()
} }

View File

@ -4,7 +4,7 @@ version := {
version.value version.value
} }
TaskKey[Unit]("evil-clear-logger") := { TaskKey[Unit]("evil-clear-logger") := Def.uncached {
val logger = sLog.value val logger = sLog.value
val cls = logger.getClass val cls = logger.getClass
val field = cls.getDeclaredField("ref") val field = cls.getDeclaredField("ref")

View File

@ -8,7 +8,7 @@ TaskKey[Unit]("checkBuildSbtDefined", "") := {
assert(notExistingThing.?.value == Some(5), "Failed to set a settingKey defined in build.sbt") assert(notExistingThing.?.value == Some(5), "Failed to set a settingKey defined in build.sbt")
} }
TaskKey[Unit]("evil-clear-logger") := { TaskKey[Unit]("evil-clear-logger") := Def.uncached {
val logger = sLog.value val logger = sLog.value
val cls = logger.getClass val cls = logger.getClass
val field = cls.getDeclaredField("ref") val field = cls.getDeclaredField("ref")
@ -16,6 +16,7 @@ TaskKey[Unit]("evil-clear-logger") := {
val ref = field.get(logger).asInstanceOf[java.lang.ref.WeakReference[_]] val ref = field.get(logger).asInstanceOf[java.lang.ref.WeakReference[_]]
// MUHAHAHHAHAHAHAHHAHA, I am de evil GC, I clear things. // MUHAHAHHAHAHAHAHHAHA, I am de evil GC, I clear things.
ref.clear() ref.clear()
()
} }
commands ++= Seq( commands ++= Seq(

View File

@ -6,23 +6,45 @@ val taskF = taskKey[File]("")
scalaVersion := "3.3.1" scalaVersion := "3.3.1"
name := "task-map" name := "task-map"
taskA := touch(target.value / "a") taskA := {
taskB := touch(target.value / "b") val c = fileConverter.value
touch(target.value / "a")
Def.declareOutput(c.toVirtualFile((target.value / "a").toPath()))
target.value / "a"
}
taskE := touch(target.value / "e") taskB := {
taskF := touch(target.value / "f") val c = fileConverter.value
touch(target.value / "b")
Def.declareOutput(c.toVirtualFile((target.value / "b").toPath()))
target.value / "b"
}
taskE := {
val c = fileConverter.value
touch(target.value / "e")
Def.declareOutput(c.toVirtualFile((target.value / "e").toPath()))
target.value / "e"
}
taskF := {
val c = fileConverter.value
touch(target.value / "f")
Def.declareOutput(c.toVirtualFile((target.value / "f").toPath()))
target.value / "f"
}
// a <<= a triggeredBy b // a <<= a triggeredBy b
// means "a" will be triggered by "b" // means "a" will be triggered by "b"
// said differently, invoking "b" will run "b" and then run "a" // said differently, invoking "b" will run "b" and then run "a"
taskA := taskA.triggeredBy(taskB).value taskA := Def.uncached(taskA.triggeredBy(taskB).value)
// e <<= e runBefore f // e <<= e runBefore f
// means "e" will be run before running "f" // means "e" will be run before running "f"
// said differently, invoking "f" will run "e" and then run "f" // said differently, invoking "f" will run "e" and then run "f"
taskE := taskE.runBefore(taskF).value taskE := Def.uncached(taskE.runBefore(taskF).value)
// test utils // test utils
def touch(f: File): File = { IO.touch(f); f } def touch(f: File): File = { IO.touch(f); f }

View File

@ -1,7 +1,7 @@
> taskB > taskB
$ exists target/**/task-map/**/b $ exists target/**/b
$ exists target/**/task-map/**/a $ exists target/**/a
> taskF > taskF
$ exists target/**/task-map/e $ exists target/**/e
$ exists target/**/task-map/f $ exists target/**/f

View File

@ -4,7 +4,7 @@ logLevel := Level.Debug
incOptions ~= { _.withApiDebug(true) } incOptions ~= { _.withApiDebug(true) }
TaskKey[Unit]("show-apis") := { TaskKey[Unit]("show-apis") := Def.uncached {
val a = (Compile / compile).value match { case a: Analysis => a } val a = (Compile / compile).value match { case a: Analysis => a }
val scalaSrc = (Compile / scalaSource).value val scalaSrc = (Compile / scalaSource).value
val javaSrc = (Compile / javaSource).value val javaSrc = (Compile / javaSource).value
@ -14,4 +14,5 @@ TaskKey[Unit]("show-apis") := {
import DefaultShowAPI._ import DefaultShowAPI._
DefaultShowAPI(aApi) DefaultShowAPI(aApi)
DefaultShowAPI(jApi) DefaultShowAPI(jApi)
()
} }

View File

@ -3,7 +3,7 @@ import complete.DefaultParsers._
// Reset compiler iterations, necessary because tests run in batch mode // Reset compiler iterations, necessary because tests run in batch mode
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.") val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
recordPreviousIterations := { recordPreviousIterations := Def.uncached {
val log = streams.value.log val log = streams.value.log
CompileState.previousIterations = { CompileState.previousIterations = {
val previousAnalysis = (Compile / previousCompile).value.analysis.asScala val previousAnalysis = (Compile / previousCompile).value.analysis.asScala
@ -14,6 +14,7 @@ recordPreviousIterations := {
case Some(a: Analysis) => a.compilations.allCompilations.size case Some(a: Analysis) => a.compilations.allCompilations.size
} }
} }
()
} }
val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.") val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.")

View File

@ -8,33 +8,34 @@ val checkMapN1 = taskKey[Unit]("")
Global / localCacheDirectory := baseDirectory.value / "diskcache" Global / localCacheDirectory := baseDirectory.value / "diskcache"
pure1 := (Def.cachedTask { pure1 := {
val output = StringVirtualFile1("target/out/a.txt", "foo") val output = StringVirtualFile1("target/out/a.txt", "foo")
Def.declareOutput(output) Def.declareOutput(output)
() ()
}).value }
map1 := (Def.cachedTask { map1 := {
pure1.value pure1.value
val output1 = StringVirtualFile1("target/out/b1.txt", "foo") val output1 = StringVirtualFile1("target/out/b1.txt", "foo")
val output2 = StringVirtualFile1("target/out/b2.txt", "foo") val output2 = StringVirtualFile1("target/out/b2.txt", "foo")
Def.declareOutput(output1) Def.declareOutput(output1)
Def.declareOutput(output2) Def.declareOutput(output2)
"something" "something"
}).value }
mapN1 := (Def.cachedTask { mapN1 := {
pure1.value pure1.value
map1.value map1.value
val output = StringVirtualFile1("target/out/c.txt", "foo") val output = StringVirtualFile1("target/out/c.txt", "foo")
Def.declareOutput(output) Def.declareOutput(output)
() ()
}).value }
checkMapN1 := { checkMapN1 := Def.uncached {
val s = streams.value
val config = Def.cacheConfiguration.value val config = Def.cacheConfiguration.value
val prev = config.cacheEventLog.previous match val prev = config.cacheEventLog.previous match
case s: CacheEventSummary.Data => s case s: CacheEventSummary.Data => s
case s => sys.error(s"empty event log") case s => sys.error(s"empty event log")
assert(prev.hitCount == 2, s"prev.hitCount = ${prev.hitCount}") assert(prev.hitCount == 2, s"prev.hitCount = ${prev.hitCount} (expected 2)")
} }

View File

@ -1,16 +1,18 @@
import sbt.internal.util.CacheEventSummary import sbt.internal.util.CacheEventSummary
import complete.DefaultParsers.*
lazy val checkMiss = taskKey[Unit]("") lazy val checkMiss = inputKey[Unit]("")
Global / localCacheDirectory := baseDirectory.value / "diskcache" Global / localCacheDirectory := baseDirectory.value / "diskcache"
scalaVersion := "3.7.1" scalaVersion := "3.7.1"
checkMiss := { checkMiss := {
val expected: Int = (Space ~> NatBasic).parsed
val s = streams.value val s = streams.value
val config = Def.cacheConfiguration.value val config = Def.cacheConfiguration.value
val prev = config.cacheEventLog.previous match val prev = config.cacheEventLog.previous match
case s: CacheEventSummary.Data => s case s: CacheEventSummary.Data => s
case _ => sys.error(s"empty event log") case _ => sys.error(s"empty event log")
s.log.info(prev.missCount.toString) s.log.info(prev.missCount.toString)
assert(prev.missCount == 2, s"prev.missCount = ${prev.missCount}") assert(prev.missCount > 0, s"prev.missCount = ${prev.missCount}")
} }

View File

@ -1,7 +1,7 @@
$ copy-file changes/A1.scala A.scala $ copy-file changes/A1.scala A.scala
> run 1 > run 1
> checkMiss > checkMiss 1
$ copy-file changes/A2.scala A.scala $ copy-file changes/A2.scala A.scala
> run 2 > run 2
> checkMiss > checkMiss 1

View File

@ -7,12 +7,14 @@ Global / localCacheDirectory := baseDirectory.value / "diskcache"
scalaVersion := "2.13.16" scalaVersion := "2.13.16"
addCompilerPlugin(("org.typelevel" % "kind-projector" % "0.13.3").cross(CrossVersion.full)) addCompilerPlugin(("org.typelevel" % "kind-projector" % "0.13.3").cross(CrossVersion.full))
check := { check := Def.uncached {
val s = streams.value
val config = Def.cacheConfiguration.value val config = Def.cacheConfiguration.value
val prev = config.cacheEventLog.previous match val prev = config.cacheEventLog.previous match
case s: CacheEventSummary.Data => s case s: CacheEventSummary.Data => s
case s => sys.error(s"empty event log") case s => sys.error(s"empty event log")
assert(prev.hitCount == 1, s"prev.hitCount = ${prev.hitCount}") s.log.info(s"prev.missCount = ${prev.missCount}")
assert(prev.missCount == 0, s"prev.missCount = ${prev.missCount}")
} }
lazy val foo = (project in file("foo")) lazy val foo = (project in file("foo"))

View File

@ -4,22 +4,22 @@ import CustomKeys.*
Global / localCacheDirectory := baseDirectory.value / "diskcache" Global / localCacheDirectory := baseDirectory.value / "diskcache"
aa := A() aa := Def.uncached(A())
// This tests that aa is opted out from caching // This tests that aa is opted out from caching
map1 := (Def.cachedTask { map1 := {
aa.value aa.value
val output1 = StringVirtualFile1("target/out/b1.txt", "foo") val output1 = StringVirtualFile1("target/out/b1.txt", "foo")
val output2 = StringVirtualFile1("target/out/b2.txt", "foo") val output2 = StringVirtualFile1("target/out/b2.txt", "foo")
Def.declareOutput(output1) Def.declareOutput(output1)
Def.declareOutput(output2) Def.declareOutput(output2)
"something" "something"
}).value }
mapN1 := (Def.cachedTask { mapN1 := {
aa.value aa.value
map1.value map1.value
val output = StringVirtualFile1("target/out/c.txt", "foo") val output = StringVirtualFile1("target/out/c.txt", "foo")
Def.declareOutput(output) Def.declareOutput(output)
() ()
}).value }

View File

@ -18,22 +18,25 @@ val root = (project in file(".")).settings(
sourceDirectory.value.toPath.resolve("main/native/include").toString), sourceDirectory.value.toPath.resolve("main/native/include").toString),
libraryDependencies += "com.lihaoyi" %% "utest" % "0.6.6" % "test", libraryDependencies += "com.lihaoyi" %% "utest" % "0.6.6" % "test",
testFrameworks := Seq(new TestFramework("utest.runner.Framework")), testFrameworks := Seq(new TestFramework("utest.runner.Framework")),
copyTestResources := { copyTestResources := Def.uncached {
val key = Def.spaceDelimited().parsed.head val key = Def.spaceDelimited().parsed.head
val base = baseDirectory.value.toPath val base = baseDirectory.value.toPath
val resources = (baseDirectory.value / "src" / "main" / "resources" / key).toPath val resources = (baseDirectory.value / "src" / "main" / "resources" / key).toPath
Files.walk(resources).iterator.asScala.foreach { p => Files.walk(resources).iterator.asScala.foreach { p =>
Files.copy(p, base.resolve(p.getFileName), StandardCopyOption.REPLACE_EXISTING) Files.copy(p, base.resolve(p.getFileName), StandardCopyOption.REPLACE_EXISTING)
} }
()
}, },
appendToLibraryPath := { appendToLibraryPath := Def.uncached {
val cp = System.getProperty("java.library.path", "").split(":") val cp = System.getProperty("java.library.path", "").split(":")
val newCp = if (cp.contains(".")) cp else cp :+ "." val newCp = if (cp.contains(".")) cp else cp :+ "."
System.setProperty("java.library.path", newCp.mkString(":")) System.setProperty("java.library.path", newCp.mkString(":"))
()
}, },
dropLibraryPath := { dropLibraryPath := Def.uncached {
val cp = System.getProperty("java.library.path", "").split(":").dropRight(1) val cp = System.getProperty("java.library.path", "").split(":").dropRight(1)
System.setProperty("java.library.path", cp.mkString(":")) System.setProperty("java.library.path", cp.mkString(":"))
()
}, },
wrappedRun := wrap(Runtime / run).value, wrappedRun := wrap(Runtime / run).value,
wrappedTest := wrap(Test / testOnly).value wrappedTest := wrap(Test / testOnly).value

View File

@ -2,5 +2,5 @@ ThisBuild / scalaVersion := "2.12.20"
lazy val root = (project in file(".")). lazy val root = (project in file(".")).
settings( settings(
incOptions := xsbti.compile.IncOptions.of() incOptions := Def.uncached(xsbti.compile.IncOptions.of())
) )

View File

@ -1,6 +1,6 @@
import sbt.internal.inc.Analysis import sbt.internal.inc.Analysis
TaskKey[Unit]("verify-binary-deps") := { TaskKey[Unit]("verify-binary-deps") := Def.uncached {
val a = (Compile / compile).value match { case a: Analysis => a } val a = (Compile / compile).value match { case a: Analysis => a }
val classDir = (Compile / classDirectory).value val classDir = (Compile / classDirectory).value
val base = baseDirectory.value val base = baseDirectory.value

View File

@ -5,7 +5,7 @@ logLevel := Level.Debug
// Reset compiler iterations, necessary because tests run in batch mode // Reset compiler iterations, necessary because tests run in batch mode
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.") val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
recordPreviousIterations := { recordPreviousIterations := Def.uncached {
val log = streams.value.log val log = streams.value.log
CompileState.previousIterations = { CompileState.previousIterations = {
val previousAnalysis = (Compile / previousCompile).value.analysis.asScala val previousAnalysis = (Compile / previousCompile).value.analysis.asScala

View File

@ -3,7 +3,7 @@ import complete.DefaultParsers._
// Reset compiler iterations, necessary because tests run in batch mode // Reset compiler iterations, necessary because tests run in batch mode
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.") val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
recordPreviousIterations := { recordPreviousIterations := Def.uncached {
val log = streams.value.log val log = streams.value.log
CompileState.previousIterations = { CompileState.previousIterations = {
val previousAnalysis = (Compile / previousCompile).value.analysis.asScala val previousAnalysis = (Compile / previousCompile).value.analysis.asScala

View File

@ -1,5 +1,5 @@
TaskKey[Unit]("check212") := checkCp(true) TaskKey[Unit]("check212") := checkCp(true).value
TaskKey[Unit]("check213") := checkCp(false) TaskKey[Unit]("check213") := checkCp(false).value
def checkCp(auto: Boolean) = Def.task { def checkCp(auto: Boolean) = Def.task {
val opts = compilers.value.scalac.classpathOptions val opts = compilers.value.scalac.classpathOptions

View File

@ -3,9 +3,10 @@ import xsbti.compile.TastyFiles
ThisBuild / scalaVersion := "3.3.1" ThisBuild / scalaVersion := "3.3.1"
TaskKey[Unit]("check") := { TaskKey[Unit]("check") := Def.uncached {
assert((Compile / auxiliaryClassFiles).value == Seq(TastyFiles.instance)) assert((Compile / auxiliaryClassFiles).value == Seq(TastyFiles.instance))
assert((Test / auxiliaryClassFiles).value == Seq(TastyFiles.instance)) assert((Test / auxiliaryClassFiles).value == Seq(TastyFiles.instance))
()
} }
TaskKey[Unit]("check2") := checkTastyFiles(true, true).value TaskKey[Unit]("check2") := checkTastyFiles(true, true).value

View File

@ -1,4 +1,4 @@
TaskKey[Unit]("checkJavaFailures") := { TaskKey[Unit]("checkJavaFailures") := Def.uncached {
val reporter = savedReporter.value val reporter = savedReporter.value
val ignore = (Compile / compile).failure.value val ignore = (Compile / compile).failure.value
val ps = reporter.problems.filter(_.severity() != xsbti.Severity.Info) val ps = reporter.problems.filter(_.severity() != xsbti.Severity.Info)
@ -9,9 +9,10 @@ TaskKey[Unit]("checkJavaFailures") := {
val expected = "${BASE}/src/main/java/bad.java" val expected = "${BASE}/src/main/java/bad.java"
val sourcePath = first.position.sourcePath.get val sourcePath = first.position.sourcePath.get
assert(sourcePath == expected, s"$sourcePath == $expected was false") assert(sourcePath == expected, s"$sourcePath == $expected was false")
()
} }
TaskKey[Unit]("checkScalaFailures") := { TaskKey[Unit]("checkScalaFailures") := Def.uncached {
val reporter = savedReporter.value val reporter = savedReporter.value
val ignore = (Compile / compile).failure.value val ignore = (Compile / compile).failure.value
val ps = reporter.problems val ps = reporter.problems
@ -22,4 +23,5 @@ TaskKey[Unit]("checkScalaFailures") := {
val expected = "${BASE}/src/main/scala/bad.scala" val expected = "${BASE}/src/main/scala/bad.scala"
val sourcePath = first.position.sourcePath.get val sourcePath = first.position.sourcePath.get
assert(sourcePath == expected, s"$sourcePath == $expected was false") assert(sourcePath == expected, s"$sourcePath == $expected was false")
()
} }

View File

@ -14,8 +14,8 @@ object TestPlugin extends AutoPlugin {
import autoImport._ import autoImport._
override def projectSettings = Seq( override def projectSettings = Seq(
savedReporter := new CollectingReporter, savedReporter := new CollectingReporter,
Compile / compile / compilerReporter := savedReporter.value, Compile / compile / compilerReporter := Def.uncached(savedReporter.value),
problems := savedReporter.value.problems problems := Def.uncached(savedReporter.value.problems),
) )
} }

View File

@ -6,10 +6,10 @@ lazy val root = (project in file("."))
.settings( .settings(
name := "foo", name := "foo",
crossScalaVersions := List(scala212, scala213), crossScalaVersions := List(scala212, scala213),
incOptions := incOptions.value.withClassfileManagerType( incOptions := Def.uncached(incOptions.value.withClassfileManagerType(
Option(xsbti.compile.TransactionalManagerType.of( Option(xsbti.compile.TransactionalManagerType.of(
crossTarget.value / "classes.bak", crossTarget.value / "classes.bak",
(Compile / compile / streams).value.log (Compile / compile / streams).value.log
): xsbti.compile.ClassFileManagerType).asJava ): xsbti.compile.ClassFileManagerType).asJava
) ))
) )

View File

@ -1,5 +1,5 @@
publishTo := baseDirectory(base => Some(Resolver.file("filesys-publish", base / "repo")) ).value publishTo := Def.uncached(baseDirectory(base => Some(Resolver.file("filesys-publish", base / "repo")) ).value)
resolvers += baseDirectory(base => "filesys" at (base / "repo").toURI.toString).value resolvers += baseDirectory(base => "filesys" at (base / "repo").toURI.toString).value

View File

@ -22,7 +22,7 @@ lazy val realCommonsIoClient = project.
libraryDependencies := Seq( libraryDependencies := Seq(
"commons-io" % "commons-io" % "1.3" "commons-io" % "commons-io" % "1.3"
), ),
fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project") fullResolvers := Def.uncached(fullResolvers.value.filterNot(_.name == "inter-project"))
) )
lazy val fakeCommonsIo = project. lazy val fakeCommonsIo = project.

View File

@ -2,9 +2,10 @@ lazy val check = taskKey[Unit]("")
lazy val root = (project in file(".")). lazy val root = (project in file(".")).
settings( settings(
check := { check := Def.uncached {
val fr = fullResolvers.value val fr = fullResolvers.value
assert(!(fr exists { _.name == "jcenter" })) assert(!(fr exists { _.name == "jcenter" }))
assert(fr exists { _.name == "public" }) assert(fr exists { _.name == "public" })
()
}, },
) )

View File

@ -6,7 +6,7 @@ ThisBuild / csrCacheDirectory := (ThisBuild / baseDirectory).value / "coursier-c
def commonSettings: Seq[Def.Setting[_]] = def commonSettings: Seq[Def.Setting[_]] =
Seq( Seq(
fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project"), fullResolvers := Def.uncached(fullResolvers.value.filterNot(_.name == "inter-project")),
publishTo := Some(MavenCache("local-maven", (LocalRootProject / target).value / "local-maven")), publishTo := Some(MavenCache("local-maven", (LocalRootProject / target).value / "local-maven")),
scalaCompilerBridgeResolvers += userLocalFileResolver(appConfiguration.value), scalaCompilerBridgeResolvers += userLocalFileResolver(appConfiguration.value),
resolvers += MavenCache("local-maven", (LocalRootProject / target).value / "local-maven"), resolvers += MavenCache("local-maven", (LocalRootProject / target).value / "local-maven"),

View File

@ -23,7 +23,7 @@ lazy val b = (project in file("b")).
lazy val root = (project in file(".")). lazy val root = (project in file(".")).
settings( settings(
check := { check := Def.uncached {
(a / update).value (a / update).value
(b / update).value (b / update).value
val acp = (a / Compile / externalDependencyClasspath).value.sortBy {_.data.name} val acp = (a / Compile / externalDependencyClasspath).value.sortBy {_.data.name}

View File

@ -1,7 +1,7 @@
import scala.xml._ import scala.xml._
lazy val root = (project in file(".")) settings ( lazy val root = (project in file(".")) settings (
readPom := { readPom := Def.uncached {
val vf = makePom.value val vf = makePom.value
val converter = fileConverter.value val converter = fileConverter.value
XML.loadFile(converter.toPath(vf).toFile) XML.loadFile(converter.toPath(vf).toFile)
@ -37,13 +37,12 @@ def withRepositories[T](pomXML: Elem)(f: NodeSeq => T) = {
else sys.error("'repositories' element not found in generated pom") else sys.error("'repositories' element not found in generated pom")
} }
lazy val checkExtra = readPom map { pomXML => lazy val checkExtra = readPom.map: pomXML =>
checkProject(pomXML) checkProject(pomXML)
val extra = pomXML \ extraTagName val extra = pomXML \ extraTagName
if (extra.isEmpty) sys.error("'" + extraTagName + "' not found in generated pom.xml.") else () if (extra.isEmpty) sys.error("'" + extraTagName + "' not found in generated pom.xml.") else ()
}
lazy val checkVersionPlusMapping = (readPom) map { (pomXml) => lazy val checkVersionPlusMapping = readPom.map: pomXml =>
var found = false var found = false
for { for {
dep <- pomXml \ "dependencies" \ "dependency" dep <- pomXml \ "dependencies" \ "dependency"
@ -52,19 +51,18 @@ lazy val checkVersionPlusMapping = (readPom) map { (pomXml) =>
if (dep \ "version").text != "[1.3,1.4)" if (dep \ "version").text != "[1.3,1.4)"
} sys.error(s"Found dependency with invalid maven version: $dep") } sys.error(s"Found dependency with invalid maven version: $dep")
() ()
}
lazy val checkAPIURL = (readPom) map { (pomXml) => lazy val checkAPIURL = readPom.map: pomXml =>
val notes = pomXml \ "properties" \ "info.apiURL" val notes = pomXml \ "properties" \ "info.apiURL"
if (notes.isEmpty) sys.error("'apiURL' not found in generated pom.xml.") else () if (notes.isEmpty) sys.error("'apiURL' not found in generated pom.xml.")
} else ()
lazy val checkReleaseNotesURL = (readPom) map { (pomXml) => lazy val checkReleaseNotesURL = readPom.map: pomXml =>
val notes = pomXml \ "properties" \ "info.releaseNotesUrl" val notes = pomXml \ "properties" \ "info.releaseNotesUrl"
if (notes.isEmpty) sys.error("'releaseNotesUrl' not found in generated pom.xml.") else () if (notes.isEmpty) sys.error("'releaseNotesUrl' not found in generated pom.xml.")
} else ()
lazy val checkPom = Def task { lazy val checkPom = Def.task {
val pomXML = readPom.value val pomXML = readPom.value
checkProject(pomXML) checkProject(pomXML)
val ivyRepositories = fullResolvers.value val ivyRepositories = fullResolvers.value

View File

@ -4,7 +4,7 @@ moduleName := "asdf"
crossPaths := false crossPaths := false
TaskKey[Unit]("checkName") := Def task { TaskKey[Unit]("checkName") := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val vf = (Compile / packageBin).value val vf = (Compile / packageBin).value
val path = converter.toPath(vf).toAbsolutePath.toString val path = converter.toPath(vf).toAbsolutePath.toString
@ -12,4 +12,5 @@ TaskKey[Unit]("checkName") := Def task {
val n = name.value val n = name.value
assert(path contains module, s"Path $path did not contain module name $module") assert(path contains module, s"Path $path did not contain module name $module")
assert(!path.contains(n), s"Path $path contained $n") assert(!path.contains(n), s"Path $path contained $n")
()
} }

View File

@ -9,7 +9,7 @@ lazy val common =
name := "config", name := "config",
organization := "com.typesafe", organization := "com.typesafe",
version := "0.4.9-SNAPSHOT", version := "0.4.9-SNAPSHOT",
publishTo := Some(localRemote), publishTo := Def.uncached(Some(localRemote)),
autoScalaLibrary := false, autoScalaLibrary := false,
crossPaths := false crossPaths := false
) )
@ -24,7 +24,7 @@ lazy val analyze =
resolvers += localRemote, resolvers += localRemote,
resolvers += Resolver.mavenLocal, resolvers += Resolver.mavenLocal,
resolvers += Resolver.sonatypeRepo("snapshots"), resolvers += Resolver.sonatypeRepo("snapshots"),
fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project") fullResolvers := Def.uncached(fullResolvers.value.filterNot(_.name == "inter-project"))
) )

View File

@ -2,7 +2,8 @@ ThisBuild / scalaVersion := "3.3.4"
lazy val check = taskKey[Unit]("") lazy val check = taskKey[Unit]("")
check := { check := Def.uncached {
val bridge = scalaCompilerBridgeBinaryJar.value val bridge = scalaCompilerBridgeBinaryJar.value
bridge.getOrElse(sys.error(s"bridge JAR is missing")) bridge.getOrElse(sys.error(s"bridge JAR is missing"))
()
} }

View File

@ -2,7 +2,7 @@ scalaVersion := "3.3.4"
val makeHome = taskKey[Unit]("Populates the 'home/lib' directory with Scala jars from the default ScalaInstance") val makeHome = taskKey[Unit]("Populates the 'home/lib' directory with Scala jars from the default ScalaInstance")
makeHome := { makeHome := Def.uncached {
val lib = baseDirectory.value / "home" / "lib" val lib = baseDirectory.value / "home" / "lib"
for(jar <- scalaInstance.value.allJars) for(jar <- scalaInstance.value.allJars)
IO.copyFile(jar, lib / jar.getName) IO.copyFile(jar, lib / jar.getName)

View File

@ -3,7 +3,7 @@ scalaHome := Some(baseDirectory.value / "home")
val checkUpdate = taskKey[Unit]("Ensures that resolved Scala artifacts are replaced with ones from the configured Scala home directory") val checkUpdate = taskKey[Unit]("Ensures that resolved Scala artifacts are replaced with ones from the configured Scala home directory")
checkUpdate := { checkUpdate := Def.uncached {
val report = update.value val report = update.value
val lib = (scalaHome.value.get / "lib").getCanonicalFile val lib = (scalaHome.value.get / "lib").getCanonicalFile
for(f <- report.allFiles) for(f <- report.allFiles)

View File

@ -33,6 +33,6 @@ lazy val dependent = project
.settings( .settings(
// Ignore the inter-project resolver, so we force to look remotely. // Ignore the inter-project resolver, so we force to look remotely.
resolvers += sharedResolver, resolvers += sharedResolver,
fullResolvers := fullResolvers.value.filterNot(_==projectResolver.value), fullResolvers := Def.uncached(fullResolvers.value.filterNot(_==projectResolver.value)),
libraryDependencies += "com.badexample" % "badexample" % "1.0-SNAPSHOT" libraryDependencies += "com.badexample" % "badexample" % "1.0-SNAPSHOT"
) )

View File

@ -1,8 +1,8 @@
ivyConfiguration := { ivyConfiguration := Def.uncached {
throw new RuntimeException("updateSbtClassifiers should use updateSbtClassifiers / ivyConfiguration") throw new RuntimeException("updateSbtClassifiers should use updateSbtClassifiers / ivyConfiguration")
} }
dependencyResolution := { dependencyResolution := Def.uncached {
throw new RuntimeException("updateSbtClassifiers should use updateSbtClassifiers / dependencyResolution") throw new RuntimeException("updateSbtClassifiers should use updateSbtClassifiers / dependencyResolution")
} }
@ -12,7 +12,7 @@ lazy val root = (project in file("."))
scalaOrganization := "doesnt.exist", scalaOrganization := "doesnt.exist",
name := "myProjectName", name := "myProjectName",
TaskKey[Unit]("checkModuleIdsInUpdateSbtClassifiers") := { TaskKey[Unit]("checkModuleIdsInUpdateSbtClassifiers") := Def.uncached {
val updateReport = updateSbtClassifiers.value val updateReport = updateSbtClassifiers.value
val moduleReports = updateReport.configurations.find(_.configuration.name == "default").get.modules val moduleReports = updateReport.configurations.find(_.configuration.name == "default").get.modules
@ -82,7 +82,7 @@ lazy val root = (project in file("."))
) )
def assertCollectionsEqual(message: String, expected: Seq[String], actual: Seq[String]): Unit = def assertCollectionsEqual(message: String, expected: Seq[String], actual: Seq[String]): Unit =
// using the new line for a more readable comparison failure output // using the new line for a more readable comparison failure output
org.junit.Assert.assertEquals(message: String, expected.mkString("\n"), actual.mkString("\n")) assert(expected.mkString("\n") == actual.mkString("\n"), message)
assertCollectionsEqual( assertCollectionsEqual(
"Unexpected module ids in updateSbtClassifiers", "Unexpected module ids in updateSbtClassifiers",

View File

@ -1,12 +1,14 @@
TaskKey[Unit]("checkIsDefaultCache") := { TaskKey[Unit]("checkIsDefaultCache") := Def.uncached {
val csrCacheDir = csrCacheDirectory.value val csrCacheDir = csrCacheDirectory.value
assert(csrCacheDir == sbt.coursierint.LMCoursier.defaultCacheLocation, csrCacheDir.toString) assert(csrCacheDir == sbt.coursierint.LMCoursier.defaultCacheLocation, csrCacheDir.toString)
val expectedPath = if Util.isWindows then "Coursier\\Cache\\v1" else ".cache/coursier/v1" val expectedPath = if Util.isWindows then "Coursier\\Cache\\v1" else ".cache/coursier/v1"
assert(csrCacheDir.toString.endsWith(expectedPath), csrCacheDir.toString) assert(csrCacheDir.toString.endsWith(expectedPath), s"$csrCacheDir does not end with $expectedPath")
()
} }
TaskKey[Unit]("checkIsCustomCache") := { TaskKey[Unit]("checkIsCustomCache") := Def.uncached {
val csrCacheDir = csrCacheDirectory.value val csrCacheDir = csrCacheDirectory.value
val ip = ivyPaths.value val ip = ivyPaths.value
assert(csrCacheDir == file(ip.ivyHome.get) / "coursier-cache", csrCacheDir.toString) assert(csrCacheDir == file(ip.ivyHome.get) / "coursier-cache", csrCacheDir.toString)
()
} }

View File

@ -6,7 +6,7 @@ libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.25"
csrCacheDirectory := baseDirectory.value / "cache" csrCacheDirectory := baseDirectory.value / "cache"
logFile := baseDirectory.value / "log" logFile := baseDirectory.value / "log"
csrLogger := { csrLogger := Def.uncached {
var logStream: java.io.PrintStream = null var logStream: java.io.PrintStream = null
def log(msg: String): Unit = { def log(msg: String): Unit = {
println(msg) println(msg)

View File

@ -9,8 +9,9 @@ Compile / packageBin / mappings ++= {
} }
lazy val unzipPackage = taskKey[Unit]("extract jar file") lazy val unzipPackage = taskKey[Unit]("extract jar file")
unzipPackage := { unzipPackage := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val p = converter.toPath((Compile / packageBin).value) val p = converter.toPath((Compile / packageBin).value)
IO.unzip(p.toFile(), target.value / "extracted") IO.unzip(p.toFile(), target.value / "extracted")
()
} }

View File

@ -15,8 +15,9 @@ Compile / packageBin / mappings ++= {
} }
lazy val unzipPackage = taskKey[Unit]("extract jar file") lazy val unzipPackage = taskKey[Unit]("extract jar file")
unzipPackage := { unzipPackage := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val p = converter.toPath((Compile / packageBin).value) val p = converter.toPath((Compile / packageBin).value)
IO.unzip(p.toFile(), target.value / "extracted") IO.unzip(p.toFile(), target.value / "extracted")
()
} }

View File

@ -1,4 +1,4 @@
(Runtime / externalDependencyClasspath) += { (Runtime / externalDependencyClasspath) += Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
converter.toVirtualFile(file("conf").toPath): HashedVirtualFileRef converter.toVirtualFile(file("conf").toPath): HashedVirtualFileRef
} }

View File

@ -1,7 +1,7 @@
lazy val runTest = taskKey[Unit]("Run the test applications.") lazy val runTest = taskKey[Unit]("Run the test applications.")
def runTestTask(pre: Def.Initialize[Task[Unit]]) = def runTestTask(pre: Def.Initialize[Task[Unit]]) =
runTest := { runTest := Def.uncached {
val _ = pre.value val _ = pre.value
val r = (Compile / run / runner).value val r = (Compile / run / runner).value
val cp = (Compile / fullClasspath).value val cp = (Compile / fullClasspath).value
@ -9,11 +9,12 @@ def runTestTask(pre: Def.Initialize[Task[Unit]]) =
val args = baseDirectory.value.getAbsolutePath :: Nil val args = baseDirectory.value.getAbsolutePath :: Nil
given FileConverter = fileConverter.value given FileConverter = fileConverter.value
r.run(main, cp.files, args, streams.value.log).get r.run(main, cp.files, args, streams.value.log).get
()
} }
lazy val b = project.settings( lazy val b = project.settings(
runTestTask( waitForCStart ), runTestTask( waitForCStart ),
runTest := { runTest := Def.uncached {
val _ = runTest.value val _ = runTest.value
val cFinished = (c / baseDirectory).value / "finished" val cFinished = (c / baseDirectory).value / "finished"
assert( !cFinished.exists, "C finished before B") assert( !cFinished.exists, "C finished before B")

View File

@ -3,7 +3,7 @@ import complete.DefaultParsers._
// Reset compiler iterations, necessary because tests run in batch mode // Reset compiler iterations, necessary because tests run in batch mode
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.") val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
recordPreviousIterations := { recordPreviousIterations := Def.uncached {
val log = streams.value.log val log = streams.value.log
CompileState.previousIterations = { CompileState.previousIterations = {
val previousAnalysis = (Compile / previousCompile).value.analysis.asScala val previousAnalysis = (Compile / previousCompile).value.analysis.asScala
@ -14,6 +14,7 @@ recordPreviousIterations := {
case Some(a: Analysis) => a.compilations.allCompilations.size case Some(a: Analysis) => a.compilations.allCompilations.size
} }
} }
()
} }
val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.") val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.")

View File

@ -3,7 +3,7 @@ import complete.DefaultParsers._
// Reset compiler iterations, necessary because tests run in batch mode // Reset compiler iterations, necessary because tests run in batch mode
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.") val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
recordPreviousIterations := { recordPreviousIterations := Def.uncached {
val log = streams.value.log val log = streams.value.log
CompileState.previousIterations = { CompileState.previousIterations = {
val previousAnalysis = (Compile / previousCompile).value.analysis.asScala val previousAnalysis = (Compile / previousCompile).value.analysis.asScala
@ -14,6 +14,7 @@ recordPreviousIterations := {
case Some(a: Analysis) => a.compilations.allCompilations.size case Some(a: Analysis) => a.compilations.allCompilations.size
} }
} }
()
} }
val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.") val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.")

View File

@ -1,4 +1,4 @@
TaskKey[Unit]("outputEmpty") := { TaskKey[Unit]("outputEmpty") := Def.uncached {
val c = fileConverter.value val c = fileConverter.value
val dir = c.toPath((Compile / backendOutput).value).toFile() val dir = c.toPath((Compile / backendOutput).value).toFile()
def classes = dir.**("*.class").get() def classes = dir.**("*.class").get()

View File

@ -5,7 +5,7 @@ import complete.DefaultParsers._
// Reset compiler iterations, necessary because tests run in batch mode // Reset compiler iterations, necessary because tests run in batch mode
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.") val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
recordPreviousIterations := { recordPreviousIterations := Def.uncached {
val log = streams.value.log val log = streams.value.log
CompileState.previousIterations = { CompileState.previousIterations = {
val previousAnalysis = (Compile / previousCompile).value.analysis.asScala val previousAnalysis = (Compile / previousCompile).value.analysis.asScala
@ -17,6 +17,7 @@ recordPreviousIterations := {
case Some(_) => -1 // should be unreachable but causes warnings case Some(_) => -1 // should be unreachable but causes warnings
} }
} }
()
} }
val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.") val checkIterations = inputKey[Unit]("Verifies the accumulated number of iterations of incremental compilation.")

View File

@ -3,7 +3,7 @@ import sbt.internal.inc.Analysis
import xsbti.compile.{PreviousResult, CompileAnalysis, MiniSetup} import xsbti.compile.{PreviousResult, CompileAnalysis, MiniSetup}
import xsbti.compile.analysis.{ Compilation => XCompilation } import xsbti.compile.analysis.{ Compilation => XCompilation }
(Compile / previousCompile) := { (Compile / previousCompile) := Def.uncached {
val previous = (Compile / previousCompile).value val previous = (Compile / previousCompile).value
if (!CompileState.isNew) { if (!CompileState.isNew) {
val res = PreviousResult.of(none[CompileAnalysis].asJava, none[MiniSetup].asJava) val res = PreviousResult.of(none[CompileAnalysis].asJava, none[MiniSetup].asJava)
@ -16,7 +16,7 @@ import xsbti.compile.analysis.{ Compilation => XCompilation }
* a) checks in which compilation given set of files was recompiled * a) checks in which compilation given set of files was recompiled
* b) checks overall number of compilations performed * b) checks overall number of compilations performed
*/ */
TaskKey[Unit]("checkCompilations") := { TaskKey[Unit]("checkCompilations") := Def.uncached {
val analysis = (Compile / compile).value match { case a: Analysis => a } val analysis = (Compile / compile).value match { case a: Analysis => a }
val srcDir = (Compile / scalaSource).value val srcDir = (Compile / scalaSource).value
def findFile(className: String): VirtualFileRef = { def findFile(className: String): VirtualFileRef = {

View File

@ -7,7 +7,7 @@ import xsbti.compile.analysis.{ Compilation => XCompilation }
logLevel := Level.Debug logLevel := Level.Debug
// Reset compile status because scripted tests are run in batch mode // Reset compile status because scripted tests are run in batch mode
(Compile / previousCompile) := { (Compile / previousCompile) := Def.uncached {
val previous = (Compile / previousCompile).value val previous = (Compile / previousCompile).value
if (!CompileState.isNew) { if (!CompileState.isNew) {
val res = PreviousResult.of(none[CompileAnalysis].asJava, none[MiniSetup].asJava) val res = PreviousResult.of(none[CompileAnalysis].asJava, none[MiniSetup].asJava)
@ -20,7 +20,7 @@ logLevel := Level.Debug
// some fraction (e.g. 50%) of files is scheduled to be recompiled // some fraction (e.g. 50%) of files is scheduled to be recompiled
// in this test we want precise information about recompiled files // in this test we want precise information about recompiled files
// which that heuristic would distort // which that heuristic would distort
incOptions := incOptions.value.withRecompileAllFraction(1.0) incOptions := Def.uncached(incOptions.value.withRecompileAllFraction(1.0))
Global / allowMachinePath := false Global / allowMachinePath := false
@ -28,7 +28,7 @@ Global / allowMachinePath := false
* a) checks in which compilation given set of files was recompiled * a) checks in which compilation given set of files was recompiled
* b) checks overall number of compilations performed * b) checks overall number of compilations performed
*/ */
TaskKey[Unit]("checkCompilations") := { TaskKey[Unit]("checkCompilations") := Def.uncached {
val log = streams.value.log val log = streams.value.log
val c = fileConverter.value val c = fileConverter.value
val vs = (Compile / sources).value.toVector map { x => val vs = (Compile / sources).value.toVector map { x =>
@ -66,4 +66,5 @@ TaskKey[Unit]("checkCompilations") := {
// Note that Y.scala is not recompiled because it depends just on X through member reference dependency // Note that Y.scala is not recompiled because it depends just on X through member reference dependency
recompiledFilesInIteration(2, Set("B.scala", "C.scala", "D.scala")) recompiledFilesInIteration(2, Set("B.scala", "C.scala", "D.scala"))
assert(allCompilations.size == 3) assert(allCompilations.size == 3)
()
} }

View File

@ -16,7 +16,7 @@ lazy val root = (project in file("."))
// testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-f", "result.txt", "-eNDXEHLO") // testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-f", "result.txt", "-eNDXEHLO")
Configurations.Test / testOptions ++= { Configurations.Test / testOptions ++= {
def args(path: String, args: String*): Seq[TestOption] = def args(path: String, args: String*): Seq[TestOption] =
if(file(path).exists) Tests.Argument(args : _*) :: Nil if file(path).exists then Tests.Argument(args*) :: Nil
else Nil else Nil
args("success1", "-n", "test2 test3") ++ args("success1", "-n", "test2 test3") ++
args("success2", "-n", "test2") ++ args("success2", "-n", "test2") ++

View File

@ -1,5 +1,7 @@
// https://github.com/sbt/sbt/issues/1673#issuecomment-537327439 // https://github.com/sbt/sbt/issues/1673#issuecomment-537327439
Global / localCacheDirectory := baseDirectory.value / "diskcache"
val Config_0 = config("config-0").extend(Compile) val Config_0 = config("config-0").extend(Compile)
val Config_1 = config("config-1").extend(Compile) val Config_1 = config("config-1").extend(Compile)
val Config_2 = config("config-2").extend(Compile) val Config_2 = config("config-2").extend(Compile)
@ -23,7 +25,7 @@ val t = taskKey[Unit]("")
val p1 = project val p1 = project
.configs(CustomConfigs: _*) .configs(CustomConfigs: _*)
.settings( .settings(
t := { t := Def.uncached {
(Config_0 / compile).value (Config_0 / compile).value
(Config_1 / compile).value (Config_1 / compile).value
(Config_2 / compile).value (Config_2 / compile).value
@ -40,6 +42,7 @@ val p1 = project
(Config_13 / compile).value (Config_13 / compile).value
(Config_14 / compile).value (Config_14 / compile).value
(Config_15 / compile).value (Config_15 / compile).value
()
} }
) )
.settings(CustomConfigs.flatMap(c => inConfig(c)(Defaults.testSettings))) .settings(CustomConfigs.flatMap(c => inConfig(c)(Defaults.testSettings)))

View File

@ -1,4 +1,4 @@
testGrouping := { testGrouping := Def.uncached {
val tests = (Test / definedTests).value val tests = (Test / definedTests).value
tests map { test => tests map { test =>
new Tests.Group( new Tests.Group(

View File

@ -8,7 +8,7 @@ Global / concurrentRestrictions := Seq(Tags.limit(TestATypeTag, 1), Tags.limit(T
libraryDependencies += specs % Test libraryDependencies += specs % Test
inConfig(Test)(Seq( inConfig(Test)(Seq(
testGrouping := { testGrouping := Def.uncached {
val home = javaHome.value val home = javaHome.value
val strategy = outputStrategy.value val strategy = outputStrategy.value
val baseDir = baseDirectory.value val baseDir = baseDirectory.value
@ -29,5 +29,8 @@ inConfig(Test)(Seq(
), Seq((if (test.name.contains("TestA")) TestATypeTag else TestBTypeTag) -> 1)) ), Seq((if (test.name.contains("TestA")) TestATypeTag else TestBTypeTag) -> 1))
} }
}, },
TaskKey[Unit]("test-failure") := testFull.failure.value TaskKey[Unit]("test-failure") := Def.uncached {
testFull.failure.value
()
}
)) ))

View File

@ -4,7 +4,7 @@ ThisBuild / scalaVersion := "2.12.20"
Global / concurrentRestrictions := Seq(Tags.limitAll(4)) Global / concurrentRestrictions := Seq(Tags.limitAll(4))
libraryDependencies += specs % Test libraryDependencies += specs % Test
inConfig(Test)(Seq( inConfig(Test)(Seq(
testGrouping := { testGrouping := Def.uncached {
val home = javaHome.value val home = javaHome.value
val strategy = outputStrategy.value val strategy = outputStrategy.value
val baseDir = baseDirectory.value val baseDir = baseDirectory.value
@ -23,5 +23,8 @@ inConfig(Test)(Seq(
) )
))} ))}
}, },
TaskKey[Unit]("test-failure") := testFull.failure.value TaskKey[Unit]("test-failure") := Def.uncached {
testFull.failure.value
()
}
)) ))

View File

@ -16,7 +16,7 @@ ThisBuild / organization := "org.example"
lazy val root = (project in file(".")) lazy val root = (project in file("."))
.settings( .settings(
Test / testGrouping := { Test / testGrouping := Def.uncached {
val tests = (Test / definedTests).value val tests = (Test / definedTests).value
assert(tests.size == 3) assert(tests.size == 3)
for (idx <- 0 until groups) yield for (idx <- 0 until groups) yield
@ -26,7 +26,7 @@ lazy val root = (project in file("."))
SubProcess(ForkOptions().withRunJVMOptions(Vector("-Dgroup.prefix=" + groupPrefix(idx)))) SubProcess(ForkOptions().withRunJVMOptions(Vector("-Dgroup.prefix=" + groupPrefix(idx))))
) )
}, },
check := { check := Def.uncached {
val files = val files =
for(i <- 0 until groups; j <- 1 to groupSize) yield for(i <- 0 until groups; j <- 1 to groupSize) yield
file(groupPrefix(i) + j) file(groupPrefix(i) + j)

View File

@ -48,7 +48,7 @@ a21 := 21
a22 := 22 a22 := 22
a23 := 23 a23 := 23
TaskKey[Unit]("check") := { TaskKey[Unit]("check") := Def.uncached {
val sum = ( val sum = (
a1.value ++ List( a1.value ++ List(
a2.value, a2.value,
@ -76,4 +76,5 @@ TaskKey[Unit]("check") := {
) )
).sum ).sum
assert(sum == 276, sum) assert(sum == 276, sum)
()
} }

View File

@ -11,11 +11,12 @@ lazy val root = (project in file("."))
libraryDependencies += { libraryDependencies += {
"org.scala-lang" % "scala-compiler" % scalaVersion.value % OtherScala.name "org.scala-lang" % "scala-compiler" % scalaVersion.value % OtherScala.name
}, },
OtherScala / managedClasspath := OtherScala / managedClasspath := Def.uncached {
Classpaths.managedJars(OtherScala, classpathTypes.value, update.value, fileConverter.value), Classpaths.managedJars(OtherScala, classpathTypes.value, update.value, fileConverter.value)
},
// Hack in the scala instance // Hack in the scala instance
scalaInstance := { scalaInstance := Def.uncached {
val converter = fileConverter.value val converter = fileConverter.value
val rawJars = (OtherScala / managedClasspath).value.map(c => converter.toPath(c.data).toFile) val rawJars = (OtherScala / managedClasspath).value.map(c => converter.toPath(c.data).toFile)
val scalaHome = (target.value / "scala-home") val scalaHome = (target.value / "scala-home")

View File

@ -5,4 +5,5 @@ TaskKey[Unit]("check") := {
val c = fileConverter.value val c = fileConverter.value
Using.jarFile(false)(c.toPath(p).toFile()): jar => Using.jarFile(false)(c.toPath(p).toFile()): jar =>
assert(jar.getJarEntry("ch/epfl/scala/Client.class") ne null) assert(jar.getJarEntry("ch/epfl/scala/Client.class") ne null)
()
} }

View File

@ -25,7 +25,7 @@ lazy val reportWarning = project.in(file("report-warning"))
// check that the buildTarget/compile request fails with the custom message defined below // check that the buildTarget/compile request fails with the custom message defined below
lazy val respondError = project.in(file("respond-error")) lazy val respondError = project.in(file("respond-error"))
.settings( .settings(
Compile / compile := { Compile / compile := Def.uncached {
val _ = (Compile / compile).value val _ = (Compile / compile).value
throw new MessageOnlyException("custom message") throw new MessageOnlyException("custom message")
} }
@ -51,14 +51,14 @@ def somethingBad = throw new MessageOnlyException("I am a bad build target")
// other build targets should not be affected by this bad build target // other build targets should not be affected by this bad build target
lazy val badBuildTarget = project.in(file("bad-build-target")) lazy val badBuildTarget = project.in(file("bad-build-target"))
.settings( .settings(
Compile / bspBuildTarget := somethingBad, Compile / bspBuildTarget := Def.uncached(somethingBad),
Compile / bspBuildTargetSourcesItem := somethingBad, Compile / bspBuildTargetSourcesItem := Def.uncached(somethingBad),
Compile / bspBuildTargetResourcesItem := somethingBad, Compile / bspBuildTargetResourcesItem := Def.uncached(somethingBad),
Compile / bspBuildTargetDependencySourcesItem := somethingBad, Compile / bspBuildTargetDependencySourcesItem := Def.uncached(somethingBad),
Compile / bspBuildTargetScalacOptionsItem := somethingBad, Compile / bspBuildTargetScalacOptionsItem := Def.uncached(somethingBad),
Compile / bspBuildTargetCompileItem := somethingBad, Compile / bspBuildTargetCompileItem := Def.uncached(somethingBad),
Compile / bspBuildTargetOutputPathsItem := somethingBad, Compile / bspBuildTargetOutputPathsItem := Def.uncached(somethingBad),
Compile / bspScalaMainClasses := somethingBad, Compile / bspScalaMainClasses := Def.uncached(somethingBad),
Test / bspBuildTarget := somethingBad, Test / bspBuildTarget := Def.uncached(somethingBad),
Test / bspScalaTestClasses := somethingBad, Test / bspScalaTestClasses := Def.uncached(somethingBad),
) )

Some files were not shown because too many files have changed in this diff Show More