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 qctx.reflect.*
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
.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]] =
import conv.qctx
import qctx.reflect.*
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
.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]] =
import conv.qctx
@ -112,7 +120,7 @@ trait Cont:
given qctx.type = qctx
Expr
.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.
@ -334,7 +342,11 @@ trait Cont:
cacheConfigExpr: Expr[BuildWideCacheConfiguration],
tags: List[CacheLevelTag],
)(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 aJsonFormat = summonJsonFormat[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 _ => 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:
case File
case Directory
@ -178,5 +200,15 @@ end ContextUtil
object ContextUtil:
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
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,
BuildWideCacheConfiguration,
cacheLevel,
DiskActionCacheStore
DiskActionCacheStore,
Uncached,
}
import Util.*
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]] =
${ 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]] =
${ 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 =
t.get(isDummyTask).getOrElse(false)
/**
* Marker function to make the task uncached.
*/
inline def uncached[A1](inline a: A1): A1 = Uncached(a)
end Def
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] =
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]] =
append1[A2](taskMacro(v))
@ -165,6 +168,9 @@ sealed abstract class TaskKey[A1]
): Setting[Task[A1]] =
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]] =
appendN(taskMacro[A2](vs))
@ -427,8 +433,8 @@ object Scoped:
sealed trait DefinableTask[A1] { self: TaskKey[A1] =>
/** Internal function for the task macro. */
inline def taskMacro[A](inline a: A): Initialize[Task[A]] =
${ TaskMacro.taskMacroImpl[A]('a, cached = false) }
inline def taskMacro[A2](inline a: A2): Initialize[Task[A2]] =
${ TaskMacro.taskMacroImpl[A2]('a, 'this) }
private[sbt] inline def :==(app: A1): Setting[Task[A1]] =
set(Def.valueStrict(std.TaskExtra.constant(app)))

View File

@ -15,10 +15,9 @@ import sbt.internal.util.appmacro.{
Cont,
// Instance,
// LinterDSL,
// MixedBuilder,
// MonadInstance
ContextUtil,
ContextUtil0,
}
// import Instance.Transform
import sbt.internal.util.{ LinePosition, NoPosition, SourcePosition }
import language.experimental.macros
@ -49,6 +48,42 @@ object TaskMacro:
// 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
qctx: Quotes
): Expr[Initialize[Task[A1]]] =

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -180,8 +180,12 @@ object Keys {
// Output paths
@cacheLevel(include = Array.empty)
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 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 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)
@ -209,6 +213,7 @@ object Keys {
val compileInputs = taskKey[Inputs]("Collects all inputs needed for compilation.").withRank(DTask)
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)
@cacheLevel(include = Array.empty)
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 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 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)
@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)
@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)
// Run Keys
@ -356,6 +365,8 @@ object Keys {
val testOptions = taskKey[Seq[TestOption]]("Options for running tests.").withRank(BPlusTask)
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)
@cacheLevel(include = Array.empty)
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 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 csrFallbackDependencies = taskKey[Seq[FallbackDependency]]("")
val csrLogger = taskKey[Option[CacheLogger]]("")
@cacheLevel(include = Array.empty)
val csrExtraCredentials = taskKey[Seq[lmcoursier.credentials.Credentials]]("")
val csrPublications = taskKey[Seq[(lmcoursier.definitions.Configuration, lmcoursier.definitions.Publication)]]("")
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 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)
@cacheLevel(include = Array.empty)
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 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 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)
@cacheLevel(include = Array.empty)
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)
@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)
@cacheLevel(include = Array.empty)
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 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 ivyValidate = settingKey[Boolean]("Enables/disables Ivy validation of module metadata.").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 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)
@ -641,6 +665,8 @@ object Keys {
val streams = taskKey[TaskStreams]("Provides streams for logging and persisting data.").withRank(DTask)
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.")
@cacheLevel(include = Array.empty)
val state = Def.stateKey
val streamsManager = Def.streamsManagerKey
// wrapper to work around SI-2915

View File

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

View File

@ -62,16 +62,18 @@ object ScriptedPlugin extends AutoPlugin {
override lazy val projectSettings: Seq[Setting[?]] = Seq(
ivyConfigurations ++= Seq(ScriptedConf, ScriptedLaunchConf),
scriptedSbt := (pluginCrossBuild / sbtVersion).value,
sbtLauncher := getJars(ScriptedLaunchConf)
sbtLauncher := Def.uncached(
getJars(ScriptedLaunchConf)
.map(_.get().head)
.value,
.value
),
sbtTestDirectory := sourceDirectory.value / "sbt-test",
libraryDependencies ++= Seq(
"org.scala-sbt" %% "scripted-sbt" % scriptedSbt.value % ScriptedConf,
"org.scala-sbt" % "sbt-launch" % scriptedSbt.value % ScriptedLaunchConf
),
scriptedClasspath := getJars(ScriptedConf).value,
scriptedTests := scriptedTestsTask.value,
scriptedClasspath := Def.uncached(getJars(ScriptedConf).value),
scriptedTests := Def.uncached(scriptedTestsTask.value),
scriptedParallelInstances := 1,
scriptedBatchExecution := {
val binVersion = CrossVersionUtil.binarySbtVersion(scriptedSbt.value)
@ -82,8 +84,8 @@ object ScriptedPlugin extends AutoPlugin {
case _ => false
}
},
scriptedRun := scriptedRunTask.value,
scriptedDependencies := {
scriptedRun := Def.uncached(scriptedRunTask.value),
scriptedDependencies := Def.uncached {
def use[A](@deprecated("unused", "") x: A*): Unit = () // avoid unused warnings
val analysis = (Test / Keys.compile).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[?] = {
csrPublications := CoursierArtifactsTasks.coursierPublicationsTask(packageConfigs*).value
csrPublications := Def.uncached(
CoursierArtifactsTasks.coursierPublicationsTask(packageConfigs*).value
)
}
// 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.internal.util.{ Attributed, StringAttributeMap }
import sbt.internal.inc.{ FileAnalysisStore, ReflectUtilities }
import sbt.util.CacheImplicits.given
import xsbti.{ FileConverter, VirtualFileRef }
import xsbti.compile.CompileAnalysis

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -20,6 +20,7 @@ import sbt.internal.util.AttributeKey
import sbt.internal.util.complete.Parser
import sbt.nio.file.{ FileAttributes, FileTreeView, Glob, PathFilter }
import sbt.*
import sbt.util.cacheLevel
import scala.concurrent.duration.FiniteDuration
@ -39,6 +40,8 @@ object Keys {
settingKey[PathFilter]("A filter to apply to the input sources of a task.")
val fileInputExcludeFilter =
settingKey[PathFilter]("An exclusion filter to apply to the input sources of a task.")
@cacheLevel(include = Array.empty)
val inputFileStamper = settingKey[FileStamper](
"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 =
taskKey[Seq[(Path, FileAttributes)]]("Get all of the file inputs for a task")
.withRank(Invisible)
@cacheLevel(include = Array.empty)
private[sbt] val unmanagedFileStampCache = taskKey[FileStamp.Cache](
"Map of managed file stamps that may be cleared between task evaluation runs."
).withRank(Invisible)
@cacheLevel(include = Array.empty)
private[sbt] val managedFileStampCache = taskKey[FileStamp.Cache](
"Map of managed file stamps that may be cleared between task evaluation runs."
).withRank(Invisible)

View File

@ -127,7 +127,7 @@ private[sbt] object Settings {
scopedKey.scope.task.toOption.toSeq.map { key =>
val updatedKey = Def.ScopedKey(scopedKey.scope.copy(task = Zero), key)
scopedKey.scope / transitiveDynamicInputs :=
WatchTransitiveDependencies.task(updatedKey).value
Def.uncached(WatchTransitiveDependencies.task(updatedKey).value)
}
case dynamicDependency.key => (scopedKey.scope / dynamicDependency := { () }) :: Nil
case transitiveClasspathDependency.key =>
@ -158,7 +158,7 @@ private[sbt] object Settings {
private[sbt] def inputPathSettings(setting: Def.Setting[?]): Seq[Def.Setting[?]] = {
val scopedKey = setting.key
val scope = scopedKey.scope
(scope / Keys.allInputPathsAndAttributes := {
(scope / Keys.allInputPathsAndAttributes := Def.uncached {
val view = (scope / fileTreeView).value
val inputs = (scope / fileInputs).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.
*/
private def allFilesImpl(scope: Scope): Def.Setting[?] = {
addTaskDefinition(scope / Keys.allInputFiles := {
addTaskDefinition(scope / Keys.allInputFiles := Def.uncached {
val filter =
(scope / fileInputIncludeFilter).value && !(scope / fileInputExcludeFilter).value
(scope / Keys.allInputPathsAndAttributes).value.collect {
@ -218,7 +218,7 @@ private[sbt] object Settings {
changeKey: TaskKey[Seq[(Path, FileStamp)] => FileChanges],
stampKey: TaskKey[Seq[(Path, FileStamp)]]
): Def.Setting[?] =
addTaskDefinition(scope / changeKey := {
addTaskDefinition(scope / changeKey := Def.uncached {
val current = (scope / stampKey).value
changedFiles(_, current)
})
@ -262,7 +262,7 @@ private[sbt] object Settings {
* @return a task specific clean implementation
*/
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[?] = {
val taskScope = taskKey.scope.rescope(taskKey.key)
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
// by the second task
Def
@ -287,6 +287,7 @@ private[sbt] object Settings {
}
.value
)
)
}
/**
@ -300,7 +301,7 @@ private[sbt] object Settings {
private[sbt] def fileStamps(scopedKey: Def.ScopedKey[?]): Def.Setting[?] = {
import scala.collection.parallel.CollectionConverters.*
val scope = scopedKey.scope
addTaskDefinition(scope / Keys.inputFileStamps := {
addTaskDefinition(scope / Keys.inputFileStamps := Def.uncached {
val cache = (scope / unmanagedFileStampCache).value
val stamper = (scope / Keys.inputFileStamper).value
val stampFile: Path => Option[(Path, FileStamp)] =
@ -335,7 +336,7 @@ private[sbt] object Settings {
}
private def allOutputPathsImpl(scope: Scope): Def.Setting[?] =
addTaskDefinition(scope / allOutputFiles := {
addTaskDefinition(scope / allOutputFiles := Def.uncached {
val filter =
(scope / fileOutputIncludeFilter).value && !(scope / fileOutputExcludeFilter).value
val view = (scope / fileTreeView).value
@ -361,7 +362,7 @@ private[sbt] object Settings {
})
private def outputFileStampsImpl(scope: Scope): Def.Setting[?] =
addTaskDefinition(scope / outputFileStamps := {
addTaskDefinition(scope / outputFileStamps := Def.uncached {
val stamper: Path => Option[FileStamp] = (scope / outputFileStamper).value match {
case LastModified => FileStamp.lastModified
case Hash => FileStamp.hash

View File

@ -38,11 +38,11 @@ object DependencyTreeSettings {
// dependency tree
dependencyTreeIgnoreMissingUpdate / updateOptions := updateOptions.value
.withCachedResolution(false),
dependencyTreeIgnoreMissingUpdate / ivyConfiguration := {
dependencyTreeIgnoreMissingUpdate / ivyConfiguration := Def.uncached {
// inTask will make sure the new definition will pick up `updateOptions in dependencyTreeIgnoreMissingUpdate`
Project.inTask(dependencyTreeIgnoreMissingUpdate, Classpaths.mkIvyConfiguration).value
},
dependencyTreeIgnoreMissingUpdate / ivyModule := {
dependencyTreeIgnoreMissingUpdate / ivyModule := Def.uncached {
// 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
// implementations like `Classpaths.mkIvyConfiguration` or `Classpaths.updateTask`)
@ -52,7 +52,7 @@ object DependencyTreeSettings {
// don't fail on missing dependencies
dependencyTreeIgnoreMissingUpdate / updateConfiguration := updateConfiguration.value
.withMissingOk(true),
dependencyTreeIgnoreMissingUpdate := {
dependencyTreeIgnoreMissingUpdate := Def.uncached {
// inTask will make sure the new definition will pick up `ivyModule/updateConfiguration in ignoreMissingUpdate`
Project.inTask(dependencyTreeIgnoreMissingUpdate, Classpaths.updateTask).value
},
@ -67,7 +67,7 @@ object DependencyTreeSettings {
dependencyTreeCrossProjectId := CrossVersion(scalaVersion.value, scalaBinaryVersion.value)(
projectID.value
),
dependencyTreeModuleGraph0 := {
dependencyTreeModuleGraph0 := Def.uncached {
val sv = scalaVersion.value
val g = dependencyTreeIgnoreMissingUpdate.value
.configuration(configuration.value)
@ -107,12 +107,14 @@ object DependencyTreeSettings {
val config = configuration.value
target.value / s"dependencies-${config.toString}.dot"
},
dependencyDot / asString := rendering.DOT.dotGraph(
dependencyDot / asString := Def.uncached(
rendering.DOT.dotGraph(
dependencyTreeModuleGraph0.value,
dependencyDotHeader.value,
dependencyDotNodeLabel.value,
rendering.DOT.HTMLLabelRendering.AngleBrackets,
dependencyDotNodeColors.value
)
),
dependencyDot := writeToFile(dependencyDot / asString, dependencyDotFile).value,
dependencyDotHeader :=

View File

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

View File

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

View File

@ -6,4 +6,7 @@ val updateReports = Def.taskDyn { updateClassifiers.all(ScopeFilter(configuratio
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
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.")
expectErrorNotCrash := {
expectErrorNotCrash := Def.uncached {
val fail = (Compile / compileIncremental).failure.value
Incomplete.allExceptions(fail).headOption match
case Some(x: xsbti.CompileFailed) => ()

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
import sbt._
import sbt.*
object FooPlugin extends AutoPlugin {
override def trigger = noTrigger
@ -9,6 +9,6 @@ object FooPlugin extends AutoPlugin {
import autoImport._
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) },
posAction := { IO.write(output.value, s"pos\n", append = true) },
TaskKey[Unit]("checkTrue") := checkLines("true"),
TaskKey[Unit]("checkFalse") := checkLines("false"),
TaskKey[Unit]("checkNeg") := checkLines("neg"),
TaskKey[Unit]("checkZero") := checkLines("zero"),
TaskKey[Unit]("checkTrue") := checkLines("true").value,
TaskKey[Unit]("checkFalse") := checkLines("false").value,
TaskKey[Unit]("checkNeg") := checkLines("neg").value,
TaskKey[Unit]("checkZero") := checkLines("zero").value,
// https://github.com/sbt/sbt/issues/5625
javacOptions ++= (
@ -49,6 +49,6 @@ lazy val root = (project in file("."))
def checkLines(content: String) = Def.task {
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(
crossScalaVersions := Seq(scala212, scala213),
libraryDependencies += "org.scalatest" %% "scalatest" % "3.1.0",
check := {
check := Def.uncached {
// This tests that +check will respect bar's crossScalaVersions and not switch
val x = (LocalProject("bar") / scalaVersion).value
assert(x == scala212, s"$x == $scala212")
(Compile / compile).value
Def.unit((Compile / compile).value)
},
(Test / testOnly) := {
// 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")
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
val x = (LocalProject("bar") / scalaVersion).value
assert(x == scalaVersion.value, s"$x == ${scalaVersion.value}")
(Compile / compile).value
Def.unit((Compile / compile).value)
},
)
lazy val bar = project
.settings(
crossScalaVersions := Seq(scala212),
check := (Compile / compile).value,
compile2 := (Compile / compile).value,
check := Def.uncached {
Def.unit((Compile / compile).value)
},
compile2 := Def.uncached(Def.unit((Compile / compile).value)),
)
lazy val baz = project
.settings(
crossScalaVersions := Seq(scala213),
check := {
check := Def.uncached {
// This tests that +baz/check will respect bar's crossScalaVersions and not switch
val x = (LocalProject("bar") / scalaVersion).value
assert(x == scala212, s"$x == $scala212")
(Compile / compile).value
Def.unit((Compile / compile).value)
},
)
lazy val client = project
.settings(
crossScalaVersions := Seq(scala212, scala213),
check := (Compile / compile).value,
compile2 := (Compile / compile).value,
check := Def.uncached(Def.unit((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
.dependsOn(c)
.settings(
externalResolvers := Seq(aResolver.value, bResolver.value),
externalResolvers := Def.uncached(Seq(aResolver.value, bResolver.value)),
addDep("a"),
addDep("b"),
checkApiMappings := {
checkApiMappings := Def.uncached {
val actual = (Compile / doc / apiMappings).value
println("Actual API Mappings: " + actual.mkString("\n\t", "\n\t", ""))
val expected = expectedMappings.value
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._
val cacheTask = taskKey[Int]("task")
cacheTask := 1
cacheTask := Def.uncached(1)
val checkTask = inputKey[Unit]("validate that the correct value is set by cacheTask")
checkTask := {

View File

@ -1,3 +1,5 @@
Global / localCacheDirectory := baseDirectory.value / "diskcache"
import sjsonnew.BasicJsonProtocol._
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:
// 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 = {
import complete.DefaultParsers._

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@ version := {
version.value
}
TaskKey[Unit]("evil-clear-logger") := {
TaskKey[Unit]("evil-clear-logger") := Def.uncached {
val logger = sLog.value
val cls = logger.getClass
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")
}
TaskKey[Unit]("evil-clear-logger") := {
TaskKey[Unit]("evil-clear-logger") := Def.uncached {
val logger = sLog.value
val cls = logger.getClass
val field = cls.getDeclaredField("ref")
@ -16,6 +16,7 @@ TaskKey[Unit]("evil-clear-logger") := {
val ref = field.get(logger).asInstanceOf[java.lang.ref.WeakReference[_]]
// MUHAHAHHAHAHAHAHHAHA, I am de evil GC, I clear things.
ref.clear()
()
}
commands ++= Seq(

View File

@ -6,23 +6,45 @@ val taskF = taskKey[File]("")
scalaVersion := "3.3.1"
name := "task-map"
taskA := touch(target.value / "a")
taskB := touch(target.value / "b")
taskA := {
val c = fileConverter.value
touch(target.value / "a")
Def.declareOutput(c.toVirtualFile((target.value / "a").toPath()))
target.value / "a"
}
taskE := touch(target.value / "e")
taskF := touch(target.value / "f")
taskB := {
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
// means "a" will be triggered by "b"
// 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
// means "e" will be run before running "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
def touch(f: File): File = { IO.touch(f); f }

View File

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

View File

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

View File

@ -3,7 +3,7 @@ import complete.DefaultParsers._
// Reset compiler iterations, necessary because tests run in batch mode
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
recordPreviousIterations := {
recordPreviousIterations := Def.uncached {
val log = streams.value.log
CompileState.previousIterations = {
val previousAnalysis = (Compile / previousCompile).value.analysis.asScala
@ -14,6 +14,7 @@ recordPreviousIterations := {
case Some(a: Analysis) => a.compilations.allCompilations.size
}
}
()
}
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"
pure1 := (Def.cachedTask {
pure1 := {
val output = StringVirtualFile1("target/out/a.txt", "foo")
Def.declareOutput(output)
()
}).value
}
map1 := (Def.cachedTask {
map1 := {
pure1.value
val output1 = StringVirtualFile1("target/out/b1.txt", "foo")
val output2 = StringVirtualFile1("target/out/b2.txt", "foo")
Def.declareOutput(output1)
Def.declareOutput(output2)
"something"
}).value
}
mapN1 := (Def.cachedTask {
mapN1 := {
pure1.value
map1.value
val output = StringVirtualFile1("target/out/c.txt", "foo")
Def.declareOutput(output)
()
}).value
}
checkMapN1 := {
checkMapN1 := Def.uncached {
val s = streams.value
val config = Def.cacheConfiguration.value
val prev = config.cacheEventLog.previous match
case s: CacheEventSummary.Data => s
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 complete.DefaultParsers.*
lazy val checkMiss = taskKey[Unit]("")
lazy val checkMiss = inputKey[Unit]("")
Global / localCacheDirectory := baseDirectory.value / "diskcache"
scalaVersion := "3.7.1"
checkMiss := {
val expected: Int = (Space ~> NatBasic).parsed
val s = streams.value
val config = Def.cacheConfiguration.value
val prev = config.cacheEventLog.previous match
case s: CacheEventSummary.Data => s
case _ => sys.error(s"empty event log")
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
> run 1
> checkMiss
> checkMiss 1
$ copy-file changes/A2.scala A.scala
> run 2
> checkMiss
> checkMiss 1

View File

@ -7,12 +7,14 @@ Global / localCacheDirectory := baseDirectory.value / "diskcache"
scalaVersion := "2.13.16"
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 prev = config.cacheEventLog.previous match
case s: CacheEventSummary.Data => s
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"))

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
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 classDir = (Compile / classDirectory).value
val base = baseDirectory.value

View File

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

View File

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

View File

@ -3,9 +3,10 @@ import xsbti.compile.TastyFiles
ThisBuild / scalaVersion := "3.3.1"
TaskKey[Unit]("check") := {
TaskKey[Unit]("check") := Def.uncached {
assert((Compile / auxiliaryClassFiles).value == Seq(TastyFiles.instance))
assert((Test / auxiliaryClassFiles).value == Seq(TastyFiles.instance))
()
}
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 ignore = (Compile / compile).failure.value
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 sourcePath = first.position.sourcePath.get
assert(sourcePath == expected, s"$sourcePath == $expected was false")
()
}
TaskKey[Unit]("checkScalaFailures") := {
TaskKey[Unit]("checkScalaFailures") := Def.uncached {
val reporter = savedReporter.value
val ignore = (Compile / compile).failure.value
val ps = reporter.problems
@ -22,4 +23,5 @@ TaskKey[Unit]("checkScalaFailures") := {
val expected = "${BASE}/src/main/scala/bad.scala"
val sourcePath = first.position.sourcePath.get
assert(sourcePath == expected, s"$sourcePath == $expected was false")
()
}

View File

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

View File

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

View File

@ -22,7 +22,7 @@ lazy val realCommonsIoClient = project.
libraryDependencies := Seq(
"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.

View File

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

View File

@ -6,7 +6,7 @@ ThisBuild / csrCacheDirectory := (ThisBuild / baseDirectory).value / "coursier-c
def commonSettings: Seq[Def.Setting[_]] =
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")),
scalaCompilerBridgeResolvers += userLocalFileResolver(appConfiguration.value),
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(".")).
settings(
check := {
check := Def.uncached {
(a / update).value
(b / update).value
val acp = (a / Compile / externalDependencyClasspath).value.sortBy {_.data.name}

View File

@ -1,7 +1,7 @@
import scala.xml._
lazy val root = (project in file(".")) settings (
readPom := {
readPom := Def.uncached {
val vf = makePom.value
val converter = fileConverter.value
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")
}
lazy val checkExtra = readPom map { pomXML =>
lazy val checkExtra = readPom.map: pomXML =>
checkProject(pomXML)
val extra = pomXML \ extraTagName
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
for {
dep <- pomXml \ "dependencies" \ "dependency"
@ -52,19 +51,18 @@ lazy val checkVersionPlusMapping = (readPom) map { (pomXml) =>
if (dep \ "version").text != "[1.3,1.4)"
} 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"
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"
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
checkProject(pomXML)
val ivyRepositories = fullResolvers.value

View File

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

View File

@ -9,7 +9,7 @@ lazy val common =
name := "config",
organization := "com.typesafe",
version := "0.4.9-SNAPSHOT",
publishTo := Some(localRemote),
publishTo := Def.uncached(Some(localRemote)),
autoScalaLibrary := false,
crossPaths := false
)
@ -24,7 +24,7 @@ lazy val analyze =
resolvers += localRemote,
resolvers += Resolver.mavenLocal,
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]("")
check := {
check := Def.uncached {
val bridge = scalaCompilerBridgeBinaryJar.value
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")
makeHome := {
makeHome := Def.uncached {
val lib = baseDirectory.value / "home" / "lib"
for(jar <- scalaInstance.value.allJars)
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")
checkUpdate := {
checkUpdate := Def.uncached {
val report = update.value
val lib = (scalaHome.value.get / "lib").getCanonicalFile
for(f <- report.allFiles)

View File

@ -33,6 +33,6 @@ lazy val dependent = project
.settings(
// Ignore the inter-project resolver, so we force to look remotely.
resolvers += sharedResolver,
fullResolvers := fullResolvers.value.filterNot(_==projectResolver.value),
fullResolvers := Def.uncached(fullResolvers.value.filterNot(_==projectResolver.value)),
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")
}
dependencyResolution := {
dependencyResolution := Def.uncached {
throw new RuntimeException("updateSbtClassifiers should use updateSbtClassifiers / dependencyResolution")
}
@ -12,7 +12,7 @@ lazy val root = (project in file("."))
scalaOrganization := "doesnt.exist",
name := "myProjectName",
TaskKey[Unit]("checkModuleIdsInUpdateSbtClassifiers") := {
TaskKey[Unit]("checkModuleIdsInUpdateSbtClassifiers") := Def.uncached {
val updateReport = updateSbtClassifiers.value
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 =
// 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(
"Unexpected module ids in updateSbtClassifiers",

View File

@ -1,12 +1,14 @@
TaskKey[Unit]("checkIsDefaultCache") := {
TaskKey[Unit]("checkIsDefaultCache") := Def.uncached {
val csrCacheDir = csrCacheDirectory.value
assert(csrCacheDir == sbt.coursierint.LMCoursier.defaultCacheLocation, csrCacheDir.toString)
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 ip = ivyPaths.value
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"
logFile := baseDirectory.value / "log"
csrLogger := {
csrLogger := Def.uncached {
var logStream: java.io.PrintStream = null
def log(msg: String): Unit = {
println(msg)

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
lazy val runTest = taskKey[Unit]("Run the test applications.")
def runTestTask(pre: Def.Initialize[Task[Unit]]) =
runTest := {
runTest := Def.uncached {
val _ = pre.value
val r = (Compile / run / runner).value
val cp = (Compile / fullClasspath).value
@ -9,11 +9,12 @@ def runTestTask(pre: Def.Initialize[Task[Unit]]) =
val args = baseDirectory.value.getAbsolutePath :: Nil
given FileConverter = fileConverter.value
r.run(main, cp.files, args, streams.value.log).get
()
}
lazy val b = project.settings(
runTestTask( waitForCStart ),
runTest := {
runTest := Def.uncached {
val _ = runTest.value
val cFinished = (c / baseDirectory).value / "finished"
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
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
recordPreviousIterations := {
recordPreviousIterations := Def.uncached {
val log = streams.value.log
CompileState.previousIterations = {
val previousAnalysis = (Compile / previousCompile).value.analysis.asScala
@ -14,6 +14,7 @@ recordPreviousIterations := {
case Some(a: Analysis) => a.compilations.allCompilations.size
}
}
()
}
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
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
recordPreviousIterations := {
recordPreviousIterations := Def.uncached {
val log = streams.value.log
CompileState.previousIterations = {
val previousAnalysis = (Compile / previousCompile).value.analysis.asScala
@ -14,6 +14,7 @@ recordPreviousIterations := {
case Some(a: Analysis) => a.compilations.allCompilations.size
}
}
()
}
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 dir = c.toPath((Compile / backendOutput).value).toFile()
def classes = dir.**("*.class").get()

View File

@ -5,7 +5,7 @@ import complete.DefaultParsers._
// Reset compiler iterations, necessary because tests run in batch mode
val recordPreviousIterations = taskKey[Unit]("Record previous iterations.")
recordPreviousIterations := {
recordPreviousIterations := Def.uncached {
val log = streams.value.log
CompileState.previousIterations = {
val previousAnalysis = (Compile / previousCompile).value.analysis.asScala
@ -17,6 +17,7 @@ recordPreviousIterations := {
case Some(_) => -1 // should be unreachable but causes warnings
}
}
()
}
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.analysis.{ Compilation => XCompilation }
(Compile / previousCompile) := {
(Compile / previousCompile) := Def.uncached {
val previous = (Compile / previousCompile).value
if (!CompileState.isNew) {
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
* 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 srcDir = (Compile / scalaSource).value
def findFile(className: String): VirtualFileRef = {

View File

@ -7,7 +7,7 @@ import xsbti.compile.analysis.{ Compilation => XCompilation }
logLevel := Level.Debug
// Reset compile status because scripted tests are run in batch mode
(Compile / previousCompile) := {
(Compile / previousCompile) := Def.uncached {
val previous = (Compile / previousCompile).value
if (!CompileState.isNew) {
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
// in this test we want precise information about recompiled files
// which that heuristic would distort
incOptions := incOptions.value.withRecompileAllFraction(1.0)
incOptions := Def.uncached(incOptions.value.withRecompileAllFraction(1.0))
Global / allowMachinePath := false
@ -28,7 +28,7 @@ Global / allowMachinePath := false
* a) checks in which compilation given set of files was recompiled
* b) checks overall number of compilations performed
*/
TaskKey[Unit]("checkCompilations") := {
TaskKey[Unit]("checkCompilations") := Def.uncached {
val log = streams.value.log
val c = fileConverter.value
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
recompiledFilesInIteration(2, Set("B.scala", "C.scala", "D.scala"))
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")
Configurations.Test / testOptions ++= {
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
args("success1", "-n", "test2 test3") ++
args("success2", "-n", "test2") ++

View File

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

View File

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

View File

@ -8,7 +8,7 @@ Global / concurrentRestrictions := Seq(Tags.limit(TestATypeTag, 1), Tags.limit(T
libraryDependencies += specs % Test
inConfig(Test)(Seq(
testGrouping := {
testGrouping := Def.uncached {
val home = javaHome.value
val strategy = outputStrategy.value
val baseDir = baseDirectory.value
@ -29,5 +29,8 @@ inConfig(Test)(Seq(
), 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))
libraryDependencies += specs % Test
inConfig(Test)(Seq(
testGrouping := {
testGrouping := Def.uncached {
val home = javaHome.value
val strategy = outputStrategy.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("."))
.settings(
Test / testGrouping := {
Test / testGrouping := Def.uncached {
val tests = (Test / definedTests).value
assert(tests.size == 3)
for (idx <- 0 until groups) yield
@ -26,7 +26,7 @@ lazy val root = (project in file("."))
SubProcess(ForkOptions().withRunJVMOptions(Vector("-Dgroup.prefix=" + groupPrefix(idx))))
)
},
check := {
check := Def.uncached {
val files =
for(i <- 0 until groups; j <- 1 to groupSize) yield
file(groupPrefix(i) + j)

View File

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

View File

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

View File

@ -5,4 +5,5 @@ TaskKey[Unit]("check") := {
val c = fileConverter.value
Using.jarFile(false)(c.toPath(p).toFile()): jar =>
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
lazy val respondError = project.in(file("respond-error"))
.settings(
Compile / compile := {
Compile / compile := Def.uncached {
val _ = (Compile / compile).value
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
lazy val badBuildTarget = project.in(file("bad-build-target"))
.settings(
Compile / bspBuildTarget := somethingBad,
Compile / bspBuildTargetSourcesItem := somethingBad,
Compile / bspBuildTargetResourcesItem := somethingBad,
Compile / bspBuildTargetDependencySourcesItem := somethingBad,
Compile / bspBuildTargetScalacOptionsItem := somethingBad,
Compile / bspBuildTargetCompileItem := somethingBad,
Compile / bspBuildTargetOutputPathsItem := somethingBad,
Compile / bspScalaMainClasses := somethingBad,
Test / bspBuildTarget := somethingBad,
Test / bspScalaTestClasses := somethingBad,
Compile / bspBuildTarget := Def.uncached(somethingBad),
Compile / bspBuildTargetSourcesItem := Def.uncached(somethingBad),
Compile / bspBuildTargetResourcesItem := Def.uncached(somethingBad),
Compile / bspBuildTargetDependencySourcesItem := Def.uncached(somethingBad),
Compile / bspBuildTargetScalacOptionsItem := Def.uncached(somethingBad),
Compile / bspBuildTargetCompileItem := Def.uncached(somethingBad),
Compile / bspBuildTargetOutputPathsItem := Def.uncached(somethingBad),
Compile / bspScalaMainClasses := Def.uncached(somethingBad),
Test / bspBuildTarget := Def.uncached(somethingBad),
Test / bspScalaTestClasses := Def.uncached(somethingBad),
)

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