mirror of https://github.com/sbt/sbt.git
Use flatMapTask instead of taskDyn
This commit is contained in:
parent
e9490e203b
commit
100f1ac09c
|
|
@ -301,11 +301,17 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits:
|
|||
*/
|
||||
inline def taskValue: Task[A1] = InputWrapper.`wrapInit_\u2603\u2603`[Task[A1]](in)
|
||||
|
||||
// implicit def macroValueIInT[T](
|
||||
// @deprecated("unused", "") in: Initialize[InputTask[T]]
|
||||
// ): InputEvaluated[T] = ???
|
||||
// implicit def macroValueIInT[T](
|
||||
// @deprecated("unused", "") in: Initialize[InputTask[T]]
|
||||
// ): InputEvaluated[T] = ???
|
||||
|
||||
// implicit def macroPrevious[T](@deprecated("unused", "") in: TaskKey[T]): MacroPrevious[T] = ???
|
||||
inline def flatMapTask[A2](f: A1 => Initialize[Task[A2]]): Initialize[Task[A2]] =
|
||||
std.FullInstance.initializeTaskMonad.flatMap(in)(f)
|
||||
|
||||
extension [A1](in: TaskKey[A1])
|
||||
// implicit def macroPrevious[T](@deprecated("unused", "") in: TaskKey[T]): MacroPrevious[T] = ???
|
||||
inline def previous(using JsonFormat[A1]): Option[A1] =
|
||||
${ TaskMacro.previousImpl[A1]('in) }
|
||||
|
||||
// The following conversions enable the types Parser[T], Initialize[Parser[T]], and
|
||||
// Initialize[State => Parser[T]] to be used in the inputTask macro as an input with an ultimate
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ object Remove {
|
|||
}
|
||||
trait Sequence[A, -B, T] extends Value[A, T] with Values[A, B]
|
||||
|
||||
implicit def removeSeq[T, V <: T]: Sequence[Seq[T], Seq[V], V] =
|
||||
given removeSeq[T, V <: T]: Sequence[Seq[T], Seq[V], V] =
|
||||
new Sequence[Seq[T], Seq[V], V] {
|
||||
def removeValue(a: Seq[T], b: V): Seq[T] = a filterNot b.==
|
||||
def removeValues(a: Seq[T], b: Seq[V]): Seq[T] = a diff (b: Seq[T])
|
||||
}
|
||||
implicit def removeOption[T]: Sequence[Seq[T], Option[T], Option[T]] =
|
||||
given removeOption[T]: Sequence[Seq[T], Option[T], Option[T]] =
|
||||
new Sequence[Seq[T], Option[T], Option[T]] {
|
||||
def removeValue(a: Seq[T], b: Option[T]): Seq[T] = b.fold(a)(a filterNot _.==)
|
||||
def removeValues(a: Seq[T], b: Option[T]): Seq[T] = b.fold(a)(a filterNot _.==)
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ object TaskMacro:
|
|||
'{
|
||||
Def.ifS[A1](Def.task($cond))(Def.task[A1]($thenp))(Def.task[A1]($elsep))
|
||||
}
|
||||
case '{ (${ stats }: a); if ($cond) then $thenp else $elsep } =>
|
||||
case '{ ${ stats }: a; if ($cond) then $thenp else $elsep } =>
|
||||
'{
|
||||
Def.ifS[A1](Def.task { $stats; $cond })(Def.task[A1]($thenp))(Def.task[A1]($elsep))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,34 +69,42 @@ object RemoteCache {
|
|||
)
|
||||
|
||||
lazy val projectSettings: Seq[Def.Setting[_]] = (Seq(
|
||||
pushRemoteCache := (Def.taskDyn {
|
||||
val arts = (pushRemoteCacheConfiguration / remoteCacheArtifacts).value
|
||||
val configs = arts flatMap { art =>
|
||||
art.packaged.scopedKey.scope match {
|
||||
case Scope(_, Select(c), _, _) => Some(c)
|
||||
case _ => None
|
||||
pushRemoteCache := ((Def
|
||||
.task {
|
||||
val arts = (pushRemoteCacheConfiguration / remoteCacheArtifacts).value
|
||||
val configs = arts flatMap { art =>
|
||||
art.packaged.scopedKey.scope match {
|
||||
case Scope(_, Select(c), _, _) => Some(c)
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
val filter = ScopeFilter(configurations = inConfigurationsByKeys(configs: _*))
|
||||
Def.task {
|
||||
val _ = pushRemoteCache.all(filter).value
|
||||
()
|
||||
}
|
||||
}).value,
|
||||
pullRemoteCache := (Def.taskDyn {
|
||||
val arts = (pushRemoteCacheConfiguration / remoteCacheArtifacts).value
|
||||
val configs = arts flatMap { art =>
|
||||
art.packaged.scopedKey.scope match {
|
||||
case Scope(_, Select(c), _, _) => Some(c)
|
||||
case _ => None
|
||||
ScopeFilter(configurations = inConfigurationsByKeys(configs: _*))
|
||||
})
|
||||
.flatMapTask { case filter =>
|
||||
Def.task {
|
||||
val _ = pushRemoteCache.all(filter).value
|
||||
()
|
||||
}
|
||||
}
|
||||
val filter = ScopeFilter(configurations = inConfigurationsByKeys(configs: _*))
|
||||
Def.task {
|
||||
val _ = pullRemoteCache.all(filter).value
|
||||
()
|
||||
}
|
||||
}).value,
|
||||
})
|
||||
.value,
|
||||
pullRemoteCache := ((Def
|
||||
.task {
|
||||
val arts = (pushRemoteCacheConfiguration / remoteCacheArtifacts).value
|
||||
val configs = arts flatMap { art =>
|
||||
art.packaged.scopedKey.scope match {
|
||||
case Scope(_, Select(c), _, _) => Some(c)
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
ScopeFilter(configurations = inConfigurationsByKeys(configs: _*))
|
||||
})
|
||||
.flatMapTask { case filter =>
|
||||
Def.task {
|
||||
val _ = pullRemoteCache.all(filter).value
|
||||
()
|
||||
}
|
||||
})
|
||||
.value,
|
||||
pushRemoteCacheConfiguration / remoteCacheArtifacts := {
|
||||
enabledOnly(remoteCacheArtifact.toSettingKey, defaultArtifactTasks).apply(_.join).value
|
||||
},
|
||||
|
|
@ -239,13 +247,16 @@ object RemoteCache {
|
|||
isSnapshot.value
|
||||
)
|
||||
},
|
||||
pushRemoteCacheConfiguration / packagedArtifacts := Def.taskDyn {
|
||||
val artifacts = (pushRemoteCacheConfiguration / remoteCacheArtifacts).value
|
||||
artifacts
|
||||
.map(a => a.packaged.map(file => (a.artifact, file)))
|
||||
.join
|
||||
.apply(_.join.map(_.toMap))
|
||||
}.value,
|
||||
pushRemoteCacheConfiguration / packagedArtifacts :=
|
||||
(Def
|
||||
.task { (pushRemoteCacheConfiguration / remoteCacheArtifacts).value })
|
||||
.flatMapTask { case artifacts =>
|
||||
artifacts
|
||||
.map(a => a.packaged.map(file => (a.artifact, file)))
|
||||
.join
|
||||
.apply(_.join.map(_.toMap))
|
||||
}
|
||||
.value,
|
||||
pushRemoteCacheConfiguration / remoteCacheArtifacts := {
|
||||
List((packageCache / remoteCacheArtifact).value)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -263,12 +263,19 @@ private[sbt] object Settings {
|
|||
@nowarn
|
||||
private[sbt] def cleanImpl[T: JsonFormat: ToSeqPath](taskKey: TaskKey[T]): Def.Setting[_] = {
|
||||
val taskScope = taskKey.scope in taskKey.key
|
||||
addTaskDefinition(sbt.Keys.clean in taskScope := Def.taskDyn {
|
||||
// the clean file task needs to run first because the previous cache gets blown away
|
||||
// by the second task
|
||||
Def.unit(Clean.cleanFileOutputTask(taskKey).value)
|
||||
Clean.task(taskScope, full = false)
|
||||
}.value)
|
||||
addTaskDefinition(
|
||||
sbt.Keys.clean in taskScope :=
|
||||
// the clean file task needs to run first because the previous cache gets blown away
|
||||
// by the second task
|
||||
Def
|
||||
.task {
|
||||
Def.unit(Clean.cleanFileOutputTask(taskKey).value)
|
||||
}
|
||||
.flatMapTask { case _ =>
|
||||
Clean.task(taskScope, full = false)
|
||||
}
|
||||
.value
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -68,15 +68,19 @@ object SemanticdbPlugin extends AutoPlugin {
|
|||
}.value,
|
||||
semanticdbOptions ++=
|
||||
targetRootOptions(scalaVersion.value, semanticdbTargetRoot.value),
|
||||
scalacOptions --= Def.settingDyn {
|
||||
val config = configuration.value
|
||||
val enabled = semanticdbEnabled.value
|
||||
if (enabled)
|
||||
Def.setting {
|
||||
semanticdbOptions.?.all(ancestorConfigs(config)).value.flatten.flatten
|
||||
}
|
||||
else Def.setting { Nil }
|
||||
}.value,
|
||||
// todo:
|
||||
// scalacOptions --= {
|
||||
// Def
|
||||
// .task { (configuration.value, semanticdbEnabled.value) }
|
||||
// .flatMapTask { case (config, enabled) =>
|
||||
// if enabled then
|
||||
// Def.task {
|
||||
// (semanticdbOptions.?.all(ancestorConfigs(config)).value.flatten.flatten: Seq[String])
|
||||
// }
|
||||
// else Def.task { (Nil: Seq[String]) }
|
||||
// }
|
||||
// .value
|
||||
// },
|
||||
scalacOptions ++= {
|
||||
if (semanticdbEnabled.value)
|
||||
semanticdbOptions.value
|
||||
|
|
|
|||
|
|
@ -1039,7 +1039,8 @@ object Defaults extends BuildCommon {
|
|||
cleanFiles := cleanFilesTask.value,
|
||||
cleanKeepFiles := Vector.empty,
|
||||
cleanKeepGlobs ++= historyPath.value.map(_.toGlob).toVector,
|
||||
clean := Def.taskDyn(Clean.task(resolvedScoped.value.scope, full = true)).value,
|
||||
// clean := Def.taskDyn(Clean.task(resolvedScoped.value.scope, full = true)).value,
|
||||
clean := Clean.scopedTask.value,
|
||||
consoleProject := consoleProjectTask.value,
|
||||
transitiveDynamicInputs := WatchTransitiveDependencies.task.value,
|
||||
) ++ sbt.internal.DeprecatedContinuous.taskDefinitions
|
||||
|
|
@ -1097,17 +1098,13 @@ object Defaults extends BuildCommon {
|
|||
}
|
||||
}
|
||||
|
||||
def scalaInstanceTask: Initialize[Task[ScalaInstance]] = Def.taskDyn {
|
||||
// if this logic changes, ensure that `unmanagedScalaInstanceOnly` and `update` are changed
|
||||
// appropriately to avoid cycles
|
||||
scalaHome.value match {
|
||||
case Some(h) => scalaInstanceFromHome(h)
|
||||
case None =>
|
||||
val scalaProvider = appConfiguration.value.provider.scalaProvider
|
||||
val version = scalaVersion.value
|
||||
if (
|
||||
version == scalaProvider.version
|
||||
) // use the same class loader as the Scala classes used by sbt
|
||||
def scalaInstanceTask: Initialize[Task[ScalaInstance]] =
|
||||
(Def.task { (Keys.scalaHome.value, appConfiguration.value, scalaVersion.value) }).flatMapTask {
|
||||
case (Some(h), _, _) => scalaInstanceFromHome(h)
|
||||
case (_, app, version) =>
|
||||
val scalaProvider = app.provider.scalaProvider
|
||||
if version == scalaProvider.version then
|
||||
// use the same class loader as the Scala classes used by sbt
|
||||
Def.task {
|
||||
val allJars = scalaProvider.jars
|
||||
val libraryJars = allJars.filter(_.getName == "scala-library.jar")
|
||||
|
|
@ -1124,16 +1121,15 @@ object Defaults extends BuildCommon {
|
|||
case _ => ScalaInstance(version, scalaProvider)
|
||||
}
|
||||
}
|
||||
else
|
||||
scalaInstanceFromUpdate
|
||||
else scalaInstanceFromUpdate
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the ScalaInstance only if it was not constructed via `update`
|
||||
// This is necessary to prevent cycles between `update` and `scalaInstance`
|
||||
private[sbt] def unmanagedScalaInstanceOnly: Initialize[Task[Option[ScalaInstance]]] =
|
||||
Def.taskDyn {
|
||||
if (scalaHome.value.isDefined) Def.task(Some(scalaInstance.value)) else Def.task(None)
|
||||
(Def.task { scalaHome.value }).flatMapTask { case h =>
|
||||
if h.isDefined then Def.task(Some(scalaInstance.value))
|
||||
else Def.task(None)
|
||||
}
|
||||
|
||||
private[this] def noToolConfiguration(autoInstance: Boolean): String = {
|
||||
|
|
@ -2542,10 +2538,11 @@ object Defaults extends BuildCommon {
|
|||
PomExtraDependencyAttributes.ScalaVersionKey -> scalaV
|
||||
).withCrossVersion(Disabled())
|
||||
|
||||
def discoverSbtPluginNames: Initialize[Task[PluginDiscovery.DiscoveredNames]] = Def.taskDyn {
|
||||
if (sbtPlugin.value) Def.task(PluginDiscovery.discoverSourceAll(compile.value))
|
||||
else Def.task(PluginDiscovery.emptyDiscoveredNames)
|
||||
}
|
||||
def discoverSbtPluginNames: Initialize[Task[PluginDiscovery.DiscoveredNames]] =
|
||||
(Def.task { sbtPlugin.value }).flatMapTask { case p =>
|
||||
if p then Def.task(PluginDiscovery.discoverSourceAll(compile.value))
|
||||
else Def.task(PluginDiscovery.emptyDiscoveredNames)
|
||||
}
|
||||
|
||||
def copyResourcesTask =
|
||||
Def.task {
|
||||
|
|
@ -3963,12 +3960,10 @@ object Classpaths {
|
|||
}
|
||||
|
||||
private[sbt] def depMap: Initialize[Task[Map[ModuleRevisionId, ModuleDescriptor]]] =
|
||||
Def.taskDyn {
|
||||
depMap(
|
||||
buildDependencies.value classpathTransitiveRefs thisProjectRef.value,
|
||||
settingsData.value,
|
||||
streams.value.log
|
||||
)
|
||||
import sbt.TupleSyntax.*
|
||||
(buildDependencies.toTaskable, thisProjectRef.toTaskable, settingsData, streams).flatMapN {
|
||||
case (bd, thisProj, data, s) =>
|
||||
depMap(bd.classpathTransitiveRefs(thisProj), data, s.log)
|
||||
}
|
||||
|
||||
@nowarn
|
||||
|
|
@ -3976,11 +3971,12 @@ object Classpaths {
|
|||
projects: Seq[ProjectRef],
|
||||
data: Settings[Scope],
|
||||
log: Logger
|
||||
): Initialize[Task[Map[ModuleRevisionId, ModuleDescriptor]]] =
|
||||
Def.value {
|
||||
projects.flatMap(ivyModule in _ get data).join.map { mod =>
|
||||
mod map { _.dependencyMapping(log) } toMap;
|
||||
}
|
||||
): Task[Map[ModuleRevisionId, ModuleDescriptor]] =
|
||||
val ivyModules = projects.flatMap { proj =>
|
||||
(proj / ivyModule).get(data)
|
||||
}.join
|
||||
ivyModules.mapN { mod =>
|
||||
mod map { _.dependencyMapping(log) } toMap;
|
||||
}
|
||||
|
||||
def projectResolverTask: Initialize[Task[Resolver]] =
|
||||
|
|
@ -4138,12 +4134,11 @@ object Classpaths {
|
|||
def addUnmanagedLibrary: Seq[Setting[_]] =
|
||||
Seq((Compile / unmanagedJars) ++= unmanagedScalaLibrary.value)
|
||||
|
||||
def unmanagedScalaLibrary: Initialize[Task[Seq[File]]] = Def.taskDyn {
|
||||
if (autoScalaLibrary.value && scalaHome.value.isDefined)
|
||||
Def.task { scalaInstance.value.libraryJars }
|
||||
else
|
||||
Def.task { Nil }
|
||||
}
|
||||
def unmanagedScalaLibrary: Initialize[Task[Seq[File]]] =
|
||||
(Def.task { autoScalaLibrary.value && scalaHome.value.isDefined }).flatMapTask { case cond =>
|
||||
if cond then Def.task { (scalaInstance.value.libraryJars: Seq[File]) }
|
||||
else Def.task { (Nil: Seq[File]) }
|
||||
}
|
||||
|
||||
import DependencyFilter._
|
||||
def managedJars(config: Configuration, jarTypes: Set[String], up: UpdateReport): Classpath =
|
||||
|
|
@ -4187,20 +4182,19 @@ object Classpaths {
|
|||
}
|
||||
|
||||
private[this] lazy val internalCompilerPluginClasspath: Initialize[Task[Classpath]] =
|
||||
Def.taskDyn {
|
||||
val ref = thisProjectRef.value
|
||||
val data = settingsData.value
|
||||
val deps = buildDependencies.value
|
||||
ClasspathImpl.internalDependenciesImplTask(
|
||||
ref,
|
||||
CompilerPlugin,
|
||||
CompilerPlugin,
|
||||
data,
|
||||
deps,
|
||||
TrackLevel.TrackAlways,
|
||||
streams.value.log
|
||||
)
|
||||
}
|
||||
(Def
|
||||
.task { (thisProjectRef.value, settingsData.value, buildDependencies.value, streams.value) })
|
||||
.flatMapTask { case (ref, data, deps, s) =>
|
||||
ClasspathImpl.internalDependenciesImplTask(
|
||||
ref,
|
||||
CompilerPlugin,
|
||||
CompilerPlugin,
|
||||
data,
|
||||
deps,
|
||||
TrackLevel.TrackAlways,
|
||||
s.log
|
||||
)
|
||||
}
|
||||
|
||||
lazy val compilerPluginConfig = Seq(
|
||||
scalacOptions := {
|
||||
|
|
|
|||
|
|
@ -147,14 +147,18 @@ object CoursierInputsTasks {
|
|||
}
|
||||
|
||||
private[sbt] def coursierInterProjectDependenciesTask: Def.Initialize[sbt.Task[Seq[CProject]]] =
|
||||
Def.taskDyn {
|
||||
val state = sbt.Keys.state.value
|
||||
val projectRef = sbt.Keys.thisProjectRef.value
|
||||
val projectRefs = Project.transitiveInterDependencies(state, projectRef)
|
||||
Def.task {
|
||||
csrProject.all(ScopeFilter(inProjects(projectRefs :+ projectRef: _*))).value
|
||||
(Def
|
||||
.task {
|
||||
val state = sbt.Keys.state.value
|
||||
val projectRef = sbt.Keys.thisProjectRef.value
|
||||
val projectRefs = Project.transitiveInterDependencies(state, projectRef)
|
||||
ScopeFilter(inProjects(projectRefs :+ projectRef: _*))
|
||||
})
|
||||
.flatMapTask { case filter =>
|
||||
Def.task {
|
||||
csrProject.all(filter).value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private[sbt] def coursierExtraProjectsTask: Def.Initialize[sbt.Task[Seq[CProject]]] = {
|
||||
Def.task {
|
||||
|
|
@ -191,22 +195,25 @@ object CoursierInputsTasks {
|
|||
|
||||
private[sbt] def coursierFallbackDependenciesTask
|
||||
: Def.Initialize[sbt.Task[Seq[FallbackDependency]]] =
|
||||
Def.taskDyn {
|
||||
val s = state.value
|
||||
val projectRef = thisProjectRef.value
|
||||
val projects = Project.transitiveInterDependencies(s, projectRef)
|
||||
(Def
|
||||
.task {
|
||||
val s = state.value
|
||||
val projectRef = thisProjectRef.value
|
||||
val projects = Project.transitiveInterDependencies(s, projectRef)
|
||||
ScopeFilter(inProjects(projectRef +: projects: _*))
|
||||
})
|
||||
.flatMapTask { case filter =>
|
||||
Def.task {
|
||||
val allDeps =
|
||||
allDependencies.all(filter).value.flatten
|
||||
|
||||
Def.task {
|
||||
val allDeps =
|
||||
allDependencies.all(ScopeFilter(inProjects(projectRef +: projects: _*))).value.flatten
|
||||
|
||||
FromSbt.fallbackDependencies(
|
||||
allDeps,
|
||||
scalaVersion.value,
|
||||
scalaBinaryVersion.value
|
||||
)
|
||||
FromSbt.fallbackDependencies(
|
||||
allDeps,
|
||||
scalaVersion.value,
|
||||
scalaBinaryVersion.value
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val credentialsTask = Def.task {
|
||||
val log = streams.value.log
|
||||
|
|
|
|||
|
|
@ -123,14 +123,17 @@ object CoursierRepositoriesTasks {
|
|||
}
|
||||
|
||||
def coursierRecursiveResolversTask: Def.Initialize[sbt.Task[Seq[Resolver]]] =
|
||||
Def.taskDyn {
|
||||
val s = state.value
|
||||
val projectRef = thisProjectRef.value
|
||||
val dependencyRefs = Project.transitiveInterDependencies(s, projectRef)
|
||||
Def.task {
|
||||
val resolvers = csrResolvers.all(ScopeFilter(inProjects(projectRef))).value ++
|
||||
csrResolvers.all(ScopeFilter(inProjects(dependencyRefs: _*))).value
|
||||
resolvers.flatten
|
||||
(Def
|
||||
.task {
|
||||
val s = state.value
|
||||
val projectRef = thisProjectRef.value
|
||||
val dependencyRefs = Project.transitiveInterDependencies(s, projectRef)
|
||||
(ScopeFilter(inProjects(projectRef)), ScopeFilter(inProjects(dependencyRefs: _*)))
|
||||
})
|
||||
.flatMapTask { case (filter1, filter2) =>
|
||||
Def.task {
|
||||
val resolvers = csrResolvers.all(filter1).value ++ csrResolvers.all(filter2).value
|
||||
resolvers.flatten
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,18 +62,22 @@ private[sbt] object ClassLoaders {
|
|||
)
|
||||
}
|
||||
|
||||
private[sbt] def runner: Def.Initialize[Task[ScalaRun]] = Def.taskDyn {
|
||||
val resolvedScope = resolvedScoped.value.scope
|
||||
val instance = scalaInstance.value
|
||||
val s = streams.value
|
||||
val opts = forkOptions.value
|
||||
val options = javaOptions.value
|
||||
if (fork.value) {
|
||||
s.log.debug(s"javaOptions: $options")
|
||||
Def.task(new ForkRun(opts))
|
||||
} else {
|
||||
Def.task {
|
||||
if (options.nonEmpty) {
|
||||
private[sbt] def runner: Def.Initialize[Task[ScalaRun]] =
|
||||
Def.taskIf {
|
||||
if fork.value then
|
||||
val s = streams.value
|
||||
val options = javaOptions.value
|
||||
s.log.debug(s"javaOptions: $options")
|
||||
val opts = forkOptions.value
|
||||
new ForkRun(opts)
|
||||
else {
|
||||
val resolvedScope = resolvedScoped.value.scope
|
||||
val instance = scalaInstance.value
|
||||
val s = streams.value
|
||||
val opts = forkOptions.value
|
||||
val options = javaOptions.value
|
||||
|
||||
if options.nonEmpty then
|
||||
val mask = ScopeMask(project = false)
|
||||
val showJavaOptions = Scope.displayMasked(
|
||||
(resolvedScope / javaOptions).scopedKey.scope,
|
||||
|
|
@ -86,7 +90,7 @@ private[sbt] object ClassLoaders {
|
|||
mask
|
||||
)
|
||||
s.log.warn(s"$showJavaOptions will be ignored, $showFork is set to false")
|
||||
}
|
||||
|
||||
val exclude = dependencyJars(exportedProducts).value.toSet ++ instance.libraryJars
|
||||
val allDeps = dependencyJars(dependencyClasspath).value.filterNot(exclude)
|
||||
val logger = state.value.globalLogging.full
|
||||
|
|
@ -114,7 +118,6 @@ private[sbt] object ClassLoaders {
|
|||
new Run(newLoader, trapExit.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private[this] def extendedClassLoaderCache: Def.Initialize[Task[ClassLoaderCache]] = Def.task {
|
||||
val errorMessage = "Tried to extract classloader cache for uninitialized state."
|
||||
|
|
|
|||
|
|
@ -78,53 +78,58 @@ private[sbt] object ClasspathImpl {
|
|||
private[this] def trackedExportedProductsImplTask(
|
||||
track: TrackLevel
|
||||
): Initialize[Task[Seq[(File, CompileAnalysis)]]] =
|
||||
Def.taskDyn {
|
||||
val _ = (packageBin / dynamicDependency).value
|
||||
val useJars = exportJars.value
|
||||
if (useJars) trackedJarProductsImplTask(track)
|
||||
else trackedNonJarProductsImplTask(track)
|
||||
Def.taskIf {
|
||||
if {
|
||||
val _ = (packageBin / dynamicDependency).value
|
||||
exportJars.value
|
||||
} then trackedJarProductsImplTask(track).value
|
||||
else trackedNonJarProductsImplTask(track).value
|
||||
}
|
||||
|
||||
private[this] def trackedNonJarProductsImplTask(
|
||||
track: TrackLevel
|
||||
): Initialize[Task[Seq[(File, CompileAnalysis)]]] =
|
||||
Def.taskDyn {
|
||||
val dirs = productDirectories.value
|
||||
val view = fileTreeView.value
|
||||
def containsClassFile(): Boolean =
|
||||
view.list(dirs.map(Glob(_, RecursiveGlob / "*.class"))).nonEmpty
|
||||
TrackLevel.intersection(track, exportToInternal.value) match {
|
||||
case TrackLevel.TrackAlways =>
|
||||
(Def
|
||||
.task {
|
||||
val dirs = productDirectories.value
|
||||
val view = fileTreeView.value
|
||||
(TrackLevel.intersection(track, exportToInternal.value), dirs, view)
|
||||
})
|
||||
.flatMapTask {
|
||||
case (TrackLevel.TrackAlways, _, _) =>
|
||||
Def.task {
|
||||
products.value map { (_, compile.value) }
|
||||
}
|
||||
case TrackLevel.TrackIfMissing if !containsClassFile() =>
|
||||
case (TrackLevel.TrackIfMissing, dirs, view)
|
||||
if view.list(dirs.map(Glob(_, RecursiveGlob / "*.class"))).isEmpty =>
|
||||
Def.task {
|
||||
products.value map { (_, compile.value) }
|
||||
}
|
||||
case _ =>
|
||||
case (_, dirs, _) =>
|
||||
Def.task {
|
||||
val analysis = previousCompile.value.analysis.toOption.getOrElse(Analysis.empty)
|
||||
dirs.map(_ -> analysis)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private[this] def trackedJarProductsImplTask(
|
||||
track: TrackLevel
|
||||
): Initialize[Task[Seq[(File, CompileAnalysis)]]] =
|
||||
Def.taskDyn {
|
||||
val jar = (packageBin / artifactPath).value
|
||||
TrackLevel.intersection(track, exportToInternal.value) match {
|
||||
case TrackLevel.TrackAlways =>
|
||||
(Def
|
||||
.task {
|
||||
val jar = (packageBin / artifactPath).value
|
||||
(TrackLevel.intersection(track, exportToInternal.value), jar)
|
||||
})
|
||||
.flatMapTask {
|
||||
case (TrackLevel.TrackAlways, _) =>
|
||||
Def.task {
|
||||
Seq((packageBin.value, compile.value))
|
||||
}
|
||||
case TrackLevel.TrackIfMissing if !jar.exists =>
|
||||
case (TrackLevel.TrackIfMissing, jar) if !jar.exists =>
|
||||
Def.task {
|
||||
Seq((packageBin.value, compile.value))
|
||||
}
|
||||
case _ =>
|
||||
case (_, jar) =>
|
||||
Def.task {
|
||||
val analysisOpt = previousCompile.value.analysis.toOption
|
||||
Seq(jar) map { x =>
|
||||
|
|
@ -136,29 +141,33 @@ private[sbt] object ClasspathImpl {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def internalDependencyClasspathTask: Initialize[Task[Classpath]] = {
|
||||
Def.taskDyn {
|
||||
val _ = (
|
||||
(exportedProductsNoTracking / transitiveClasspathDependency).value,
|
||||
(exportedProductsIfMissing / transitiveClasspathDependency).value,
|
||||
(exportedProducts / transitiveClasspathDependency).value,
|
||||
(exportedProductJarsNoTracking / transitiveClasspathDependency).value,
|
||||
(exportedProductJarsIfMissing / transitiveClasspathDependency).value,
|
||||
(exportedProductJars / transitiveClasspathDependency).value
|
||||
)
|
||||
internalDependenciesImplTask(
|
||||
thisProjectRef.value,
|
||||
classpathConfiguration.value,
|
||||
configuration.value,
|
||||
settingsData.value,
|
||||
buildDependencies.value,
|
||||
trackInternalDependencies.value,
|
||||
streams.value.log,
|
||||
)
|
||||
}
|
||||
}
|
||||
def internalDependencyClasspathTask: Initialize[Task[Classpath]] =
|
||||
(Def
|
||||
.task {
|
||||
val _ = (
|
||||
(exportedProductsNoTracking / transitiveClasspathDependency).value,
|
||||
(exportedProductsIfMissing / transitiveClasspathDependency).value,
|
||||
(exportedProducts / transitiveClasspathDependency).value,
|
||||
(exportedProductJarsNoTracking / transitiveClasspathDependency).value,
|
||||
(exportedProductJarsIfMissing / transitiveClasspathDependency).value,
|
||||
(exportedProductJars / transitiveClasspathDependency).value
|
||||
)
|
||||
})
|
||||
.flatMapTask { case u =>
|
||||
Def.task {
|
||||
(
|
||||
thisProjectRef.value,
|
||||
classpathConfiguration.value,
|
||||
configuration.value,
|
||||
settingsData.value,
|
||||
buildDependencies.value,
|
||||
trackInternalDependencies.value,
|
||||
streams.value.log,
|
||||
)
|
||||
}
|
||||
}
|
||||
.flatMapTask { internalDependenciesImplTask }
|
||||
|
||||
def internalDependenciesImplTask(
|
||||
projectRef: ProjectRef,
|
||||
|
|
@ -194,31 +203,35 @@ private[sbt] object ClasspathImpl {
|
|||
exportedPickles
|
||||
)
|
||||
}
|
||||
Def.taskDyn {
|
||||
implTask(
|
||||
thisProjectRef.value,
|
||||
classpathConfiguration.value,
|
||||
configuration.value,
|
||||
settingsData.value,
|
||||
buildDependencies.value,
|
||||
TrackLevel.TrackAlways,
|
||||
streams.value.log,
|
||||
)
|
||||
}
|
||||
(Def
|
||||
.task {
|
||||
(
|
||||
thisProjectRef.value,
|
||||
classpathConfiguration.value,
|
||||
configuration.value,
|
||||
settingsData.value,
|
||||
buildDependencies.value,
|
||||
TrackLevel.TrackAlways,
|
||||
streams.value.log,
|
||||
)
|
||||
})
|
||||
.flatMapTask(implTask)
|
||||
}
|
||||
|
||||
def internalDependencyJarsTask: Initialize[Task[Classpath]] =
|
||||
Def.taskDyn {
|
||||
internalDependencyJarsImplTask(
|
||||
thisProjectRef.value,
|
||||
classpathConfiguration.value,
|
||||
configuration.value,
|
||||
settingsData.value,
|
||||
buildDependencies.value,
|
||||
trackInternalDependencies.value,
|
||||
streams.value.log,
|
||||
)
|
||||
}
|
||||
(Def
|
||||
.task {
|
||||
(
|
||||
thisProjectRef.value,
|
||||
classpathConfiguration.value,
|
||||
configuration.value,
|
||||
settingsData.value,
|
||||
buildDependencies.value,
|
||||
trackInternalDependencies.value,
|
||||
streams.value.log,
|
||||
)
|
||||
})
|
||||
.flatMapTask(internalDependencyJarsImplTask)
|
||||
|
||||
private def internalDependencyJarsImplTask(
|
||||
projectRef: ProjectRef,
|
||||
|
|
@ -238,15 +251,17 @@ private[sbt] object ClasspathImpl {
|
|||
}
|
||||
|
||||
def unmanagedDependenciesTask: Initialize[Task[Classpath]] =
|
||||
Def.taskDyn {
|
||||
unmanagedDependencies0(
|
||||
thisProjectRef.value,
|
||||
configuration.value,
|
||||
settingsData.value,
|
||||
buildDependencies.value,
|
||||
streams.value.log
|
||||
)
|
||||
}
|
||||
(Def
|
||||
.task {
|
||||
(
|
||||
thisProjectRef.value,
|
||||
configuration.value,
|
||||
settingsData.value,
|
||||
buildDependencies.value,
|
||||
streams.value.log
|
||||
)
|
||||
})
|
||||
.flatMapTask(unmanagedDependencies0)
|
||||
|
||||
def unmanagedDependencies0(
|
||||
projectRef: ProjectRef,
|
||||
|
|
|
|||
|
|
@ -71,6 +71,11 @@ private[sbt] object Clean {
|
|||
tryDelete(debug)
|
||||
}
|
||||
|
||||
private[sbt] def scopedTask: Def.Initialize[Task[Unit]] =
|
||||
Keys.resolvedScoped.toTaskable.toTask.flatMapTask { case (r: ScopedKey[_]) =>
|
||||
task(r.scope, full = true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the clean task in a given scope. It uses the outputs task value in the provided
|
||||
* scope to determine which files to delete.
|
||||
|
|
@ -82,53 +87,63 @@ private[sbt] object Clean {
|
|||
scope: Scope,
|
||||
full: Boolean
|
||||
): Def.Initialize[Task[Unit]] =
|
||||
Def.taskDyn {
|
||||
val state = Keys.state.value
|
||||
val extracted = Project.extract(state)
|
||||
val view = (scope / fileTreeView).value
|
||||
val manager = streamsManager.value
|
||||
Def.task {
|
||||
val excludeFilter = cleanFilter(scope).value
|
||||
val delete = cleanDelete(scope).value
|
||||
val targetDir = (scope / target).?.value.map(_.toPath)
|
||||
(Def
|
||||
.task {
|
||||
val state = Keys.state.value
|
||||
val extracted = Project.extract(state)
|
||||
val view = (scope / fileTreeView).value
|
||||
val manager = streamsManager.value
|
||||
(state, extracted, view, manager)
|
||||
})
|
||||
.flatMapTask { case (state, extracted, view, manager) =>
|
||||
Def.task {
|
||||
val excludeFilter = cleanFilter(scope).value
|
||||
val delete = cleanDelete(scope).value
|
||||
val targetDir = (scope / target).?.value.map(_.toPath)
|
||||
|
||||
targetDir.filter(_ => full).foreach(deleteContents(_, excludeFilter, view, delete))
|
||||
(scope / cleanFiles).?.value.getOrElse(Nil).foreach { x =>
|
||||
if (x.isDirectory) deleteContents(x.toPath, excludeFilter, view, delete)
|
||||
else delete(x.toPath)
|
||||
}
|
||||
|
||||
// This is the special portion of the task where we clear out the relevant streams
|
||||
// and file outputs of a task.
|
||||
val streamsKey = scope.task.toOption.map(k => ScopedKey(scope.copy(task = Zero), k))
|
||||
val stampsKey =
|
||||
extracted.structure.data.getDirect(scope, inputFileStamps.key) match {
|
||||
case Some(_) => ScopedKey(scope, inputFileStamps.key) :: Nil
|
||||
case _ => Nil
|
||||
targetDir.filter(_ => full).foreach(deleteContents(_, excludeFilter, view, delete))
|
||||
(scope / cleanFiles).?.value.getOrElse(Nil).foreach { x =>
|
||||
if (x.isDirectory) deleteContents(x.toPath, excludeFilter, view, delete)
|
||||
else delete(x.toPath)
|
||||
}
|
||||
val streamsGlobs =
|
||||
(streamsKey.toSeq ++ stampsKey).map(k => manager(k).cacheDirectory.toGlob / **)
|
||||
((scope / fileOutputs).value.filter(g =>
|
||||
targetDir.fold(true)(g.base.startsWith)
|
||||
) ++ streamsGlobs)
|
||||
.foreach { g =>
|
||||
val filter: Path => Boolean = { path =>
|
||||
!g.matches(path) || excludeFilter(path)
|
||||
|
||||
// This is the special portion of the task where we clear out the relevant streams
|
||||
// and file outputs of a task.
|
||||
val streamsKey = scope.task.toOption.map(k => ScopedKey(scope.copy(task = Zero), k))
|
||||
val stampsKey =
|
||||
extracted.structure.data.getDirect(scope, inputFileStamps.key) match {
|
||||
case Some(_) => ScopedKey(scope, inputFileStamps.key) :: Nil
|
||||
case _ => Nil
|
||||
}
|
||||
deleteContents(g.base, filter, FileTreeView.default, delete)
|
||||
delete(g.base)
|
||||
}
|
||||
val streamsGlobs =
|
||||
(streamsKey.toSeq ++ stampsKey)
|
||||
.map(k => manager(k).cacheDirectory.toPath.toGlob / **)
|
||||
((scope / fileOutputs).value.filter { g =>
|
||||
targetDir.fold(true)(g.base.startsWith)
|
||||
} ++ streamsGlobs)
|
||||
.foreach { g =>
|
||||
val filter: Path => Boolean = { path =>
|
||||
!g.matches(path) || excludeFilter(path)
|
||||
}
|
||||
deleteContents(g.base, filter, FileTreeView.default, delete)
|
||||
delete(g.base)
|
||||
}
|
||||
}
|
||||
}
|
||||
} tag Tags.Clean
|
||||
private[sbt] trait ToSeqPath[T] {
|
||||
def apply(t: T): Seq[Path]
|
||||
}
|
||||
private[sbt] object ToSeqPath {
|
||||
implicit val identitySeqPath: ToSeqPath[Seq[Path]] = identity _
|
||||
implicit val seqFile: ToSeqPath[Seq[File]] = _.map(_.toPath)
|
||||
implicit val path: ToSeqPath[Path] = _ :: Nil
|
||||
implicit val file: ToSeqPath[File] = _.toPath :: Nil
|
||||
}
|
||||
.tag(Tags.Clean)
|
||||
|
||||
// SAM
|
||||
private[sbt] trait ToSeqPath[A]:
|
||||
def apply(a: A): Seq[Path]
|
||||
end ToSeqPath
|
||||
|
||||
private[sbt] object ToSeqPath:
|
||||
given identitySeqPath: ToSeqPath[Seq[Path]] = identity[Seq[Path]](_)
|
||||
given seqFile: ToSeqPath[Seq[File]] = _.map(_.toPath)
|
||||
given path: ToSeqPath[Path] = _ :: Nil
|
||||
given file: ToSeqPath[File] = _.toPath :: Nil
|
||||
end ToSeqPath
|
||||
|
||||
private[this] implicit class ToSeqPathOps[T](val t: T) extends AnyVal {
|
||||
def toSeqPath(implicit toSeqPath: ToSeqPath[T]): Seq[Path] = toSeqPath(t)
|
||||
}
|
||||
|
|
@ -137,19 +152,24 @@ private[sbt] object Clean {
|
|||
private[sbt] def cleanFileOutputTask[T: JsonFormat: ToSeqPath](
|
||||
taskKey: TaskKey[T]
|
||||
): Def.Initialize[Task[Unit]] =
|
||||
Def.taskDyn {
|
||||
val scope = taskKey.scope in taskKey.key
|
||||
Def.task {
|
||||
val targetDir = (scope / target).value.toPath
|
||||
val filter = cleanFilter(scope).value
|
||||
// We do not want to inadvertently delete files that are not in the target directory.
|
||||
val excludeFilter: Path => Boolean = path => !path.startsWith(targetDir) || filter(path)
|
||||
val delete = cleanDelete(scope).value
|
||||
val st = (scope / streams).value
|
||||
taskKey.previous.foreach(_.toSeqPath.foreach(p => if (!excludeFilter(p)) delete(p)))
|
||||
delete(st.cacheDirectory.toPath / Previous.DependencyDirectory)
|
||||
(Def
|
||||
.task {
|
||||
taskKey.scope in taskKey.key
|
||||
})
|
||||
.flatMapTask { case scope =>
|
||||
Def.task {
|
||||
val targetDir = (scope / target).value.toPath
|
||||
val filter = cleanFilter(scope).value
|
||||
// We do not want to inadvertently delete files that are not in the target directory.
|
||||
val excludeFilter: Path => Boolean = path => !path.startsWith(targetDir) || filter(path)
|
||||
val delete = cleanDelete(scope).value
|
||||
val st = (scope / streams).value
|
||||
taskKey.previous.foreach(_.toSeqPath.foreach(p => if (!excludeFilter(p)) delete(p)))
|
||||
delete(st.cacheDirectory.toPath / Previous.DependencyDirectory)
|
||||
}
|
||||
}
|
||||
} tag Tags.Clean
|
||||
.tag(Tags.Clean)
|
||||
|
||||
private[this] def tryDelete(debug: String => Unit): Path => Unit = path => {
|
||||
try {
|
||||
debug(s"clean -- deleting file $path")
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ object GlobalPlugin {
|
|||
import structure.{ data, root, rootProject }
|
||||
val p: Scope = Scope.GlobalScope in ProjectRef(root, rootProject(root))
|
||||
|
||||
// If we reference it directly (if it's an executionRoot) then it forces an update, which is not what we want.
|
||||
val updateReport = (Def.task { () }).flatMapTask { case _ => Def.task { update.value } }
|
||||
val taskInit = Def.task {
|
||||
val intcp = (Runtime / internalDependencyClasspath).value
|
||||
val prods = (Runtime / exportedProducts).value
|
||||
|
|
|
|||
|
|
@ -770,8 +770,7 @@ trait TaskSequential {
|
|||
tasks.toList match {
|
||||
case Nil => Def.task { last.value }
|
||||
case x :: xs =>
|
||||
Def.taskDyn {
|
||||
Def.unit(x.value)
|
||||
Def.task { Def.unit(x.value) }.flatMapTask { case _ =>
|
||||
sequential(xs, last)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,10 +36,10 @@ private[sbt] object WatchTransitiveDependencies {
|
|||
withParams((e, cm) => Def.task(transitiveDynamicInputs(argumentsImpl(key, e, cm).value)))
|
||||
private def withParams[R](
|
||||
f: (Extracted, CompiledMap) => Def.Initialize[Task[R]]
|
||||
): Def.Initialize[Task[R]] = Def.taskDyn {
|
||||
val extracted = Project.extract(state.value)
|
||||
f(extracted, compile(extracted.structure))
|
||||
}
|
||||
): Def.Initialize[Task[R]] =
|
||||
Def.task { Project.extract(state.value) }.flatMapTask { extracted =>
|
||||
f(extracted, compile(extracted.structure))
|
||||
}
|
||||
|
||||
private[sbt] def compile(structure: BuildStructure): CompiledMap = structure.compiledMap
|
||||
private[sbt] final class Arguments(
|
||||
|
|
@ -76,20 +76,24 @@ private[sbt] object WatchTransitiveDependencies {
|
|||
)
|
||||
}
|
||||
private val ShowTransitive = "(?:show)?(?:[ ]*)(.*)/(?:[ ]*)transitive(?:Inputs|Globs|Triggers)".r
|
||||
private def arguments: Def.Initialize[Task[Arguments]] = Def.taskDyn {
|
||||
Def.task {
|
||||
val extracted = Project.extract(state.value)
|
||||
val compiledMap = compile(extracted.structure)
|
||||
state.value.currentCommand.map(_.commandLine) match {
|
||||
case Some(ShowTransitive(key)) =>
|
||||
Parser.parse(key.trim, Act.scopedKeyParser(state.value)) match {
|
||||
case Right(scopedKey) => argumentsImpl(scopedKey, extracted, compiledMap)
|
||||
case _ => argumentsImpl(Keys.resolvedScoped.value, extracted, compiledMap)
|
||||
}
|
||||
case Some(_) => argumentsImpl(Keys.resolvedScoped.value, extracted, compiledMap)
|
||||
private def arguments: Def.Initialize[Task[Arguments]] =
|
||||
Def
|
||||
.task {
|
||||
val extracted = Project.extract(state.value)
|
||||
val compiledMap = compile(extracted.structure)
|
||||
val st = state.value
|
||||
val rs = Keys.resolvedScoped.value
|
||||
(extracted, compiledMap, st, rs)
|
||||
}
|
||||
}.value
|
||||
}
|
||||
.flatMapTask { case (extracted, compiledMap, st, rs) =>
|
||||
st.currentCommand.map(_.commandLine) match
|
||||
case Some(ShowTransitive(key)) =>
|
||||
Parser.parse(key.trim, Act.scopedKeyParser(st)) match
|
||||
case Right(scopedKey) => argumentsImpl(scopedKey, extracted, compiledMap)
|
||||
case _ => argumentsImpl(rs, extracted, compiledMap)
|
||||
case Some(_) => argumentsImpl(rs, extracted, compiledMap)
|
||||
}
|
||||
|
||||
private[sbt] def transitiveDynamicInputs(args: Arguments): Seq[DynamicInput] = {
|
||||
import args._
|
||||
val taskScope = Project.fillTaskAxis(scopedKey).scope
|
||||
|
|
|
|||
|
|
@ -198,24 +198,20 @@ object IvyXml {
|
|||
shadedConfigOpt: Option[Configuration]
|
||||
): Setting[Task[T]] =
|
||||
task := task.dependsOn {
|
||||
Def.taskDyn {
|
||||
val doGen = useCoursier.value
|
||||
if (doGen)
|
||||
Def.task {
|
||||
val currentProject = {
|
||||
val proj = csrProject.value
|
||||
val publications = csrPublications.value
|
||||
proj.withPublications(publications)
|
||||
}
|
||||
IvyXml.writeFiles(
|
||||
currentProject,
|
||||
shadedConfigOpt,
|
||||
sbt.Keys.ivySbt.value,
|
||||
sbt.Keys.streams.value.log
|
||||
)
|
||||
Def.taskIf {
|
||||
if useCoursier.value then
|
||||
val currentProject = {
|
||||
val proj = csrProject.value
|
||||
val publications = csrPublications.value
|
||||
proj.withPublications(publications)
|
||||
}
|
||||
else
|
||||
Def.task(())
|
||||
IvyXml.writeFiles(
|
||||
currentProject,
|
||||
shadedConfigOpt,
|
||||
sbt.Keys.ivySbt.value,
|
||||
sbt.Keys.streams.value.log
|
||||
)
|
||||
else ()
|
||||
}
|
||||
}.value
|
||||
|
||||
|
|
|
|||
|
|
@ -93,21 +93,26 @@ object BuildServerProtocol {
|
|||
bspSbtEnabled := true,
|
||||
bspFullWorkspace := bspFullWorkspaceSetting.value,
|
||||
bspWorkspace := bspFullWorkspace.value.scopes,
|
||||
bspWorkspaceBuildTargets := Def.taskDyn {
|
||||
val workspace = Keys.bspFullWorkspace.value
|
||||
val state = Keys.state.value
|
||||
val allTargets = ScopeFilter.in(workspace.scopes.values.toSeq)
|
||||
val sbtTargets = workspace.builds.map { case (buildTargetIdentifier, loadedBuildUnit) =>
|
||||
val buildFor = workspace.buildToScope.getOrElse(buildTargetIdentifier, Nil)
|
||||
sbtBuildTarget(loadedBuildUnit, buildTargetIdentifier, buildFor).result
|
||||
}.toList
|
||||
Def.task {
|
||||
val buildTargets = Keys.bspBuildTarget.result.all(allTargets).value
|
||||
val successfulBuildTargets = anyOrThrow(buildTargets ++ sbtTargets.join.value)
|
||||
state.respondEvent(WorkspaceBuildTargetsResult(successfulBuildTargets.toVector))
|
||||
successfulBuildTargets
|
||||
bspWorkspaceBuildTargets := (Def
|
||||
.task {
|
||||
val workspace = Keys.bspFullWorkspace.value
|
||||
val state = Keys.state.value
|
||||
val allTargets = ScopeFilter.in(workspace.scopes.values.toSeq)
|
||||
val sbtTargets = workspace.builds.map { case (buildTargetIdentifier, loadedBuildUnit) =>
|
||||
val buildFor = workspace.buildToScope.getOrElse(buildTargetIdentifier, Nil)
|
||||
sbtBuildTarget(loadedBuildUnit, buildTargetIdentifier, buildFor).result
|
||||
}.toList
|
||||
(workspace, state, allTargets, sbtTargets)
|
||||
}
|
||||
}.value,
|
||||
.flatMapTask { case (workspace, state, allTargets, sbtTargets) =>
|
||||
Def.task {
|
||||
val buildTargets = Keys.bspBuildTarget.result.all(allTargets).value
|
||||
val successfulBuildTargets = anyOrThrow(buildTargets ++ sbtTargets.join.value)
|
||||
state.respondEvent(WorkspaceBuildTargetsResult(successfulBuildTargets.toVector))
|
||||
successfulBuildTargets
|
||||
}
|
||||
})
|
||||
.value,
|
||||
// https://github.com/build-server-protocol/build-server-protocol/blob/master/docs/specification.md#build-target-sources-request
|
||||
bspBuildTargetSources := bspInputTask { (state, _, workspace, filter) =>
|
||||
// run the worker task concurrently
|
||||
|
|
@ -588,44 +593,66 @@ object BuildServerProtocol {
|
|||
}
|
||||
}
|
||||
|
||||
private def buildTargetTask: Def.Initialize[Task[BuildTarget]] = Def.taskDyn {
|
||||
val buildTargetIdentifier = Keys.bspTargetIdentifier.value
|
||||
val thisProject = Keys.thisProject.value
|
||||
val thisProjectRef = Keys.thisProjectRef.value
|
||||
val thisConfig = Keys.configuration.value
|
||||
val scalaJars = Keys.scalaInstance.value.allJars.map(_.toURI.toString)
|
||||
val compileData = ScalaBuildTarget(
|
||||
scalaOrganization = scalaOrganization.value,
|
||||
scalaVersion = scalaVersion.value,
|
||||
scalaBinaryVersion = scalaBinaryVersion.value,
|
||||
platform = ScalaPlatform.JVM,
|
||||
jars = scalaJars.toVector
|
||||
)
|
||||
val configuration = Keys.configuration.value
|
||||
val displayName = BuildTargetName.fromScope(thisProject.id, configuration.name)
|
||||
val baseDirectory = Keys.baseDirectory.value.toURI
|
||||
val projectDependencies = for {
|
||||
(dep, configs) <- Keys.bspInternalDependencyConfigurations.value
|
||||
config <- configs
|
||||
if dep != thisProjectRef || config.name != thisConfig.name
|
||||
} yield (dep / config / Keys.bspTargetIdentifier)
|
||||
val capabilities =
|
||||
BuildTargetCapabilities(canCompile = true, canTest = true, canRun = true, canDebug = false)
|
||||
val tags = BuildTargetTag.fromConfig(configuration.name)
|
||||
Def.task {
|
||||
BuildTarget(
|
||||
buildTargetIdentifier,
|
||||
Some(displayName),
|
||||
Some(baseDirectory),
|
||||
tags,
|
||||
capabilities,
|
||||
BuildServerConnection.languages,
|
||||
projectDependencies.join.value.distinct.toVector,
|
||||
dataKind = Some("scala"),
|
||||
data = Some(Converter.toJsonUnsafe(compileData)),
|
||||
)
|
||||
}
|
||||
}
|
||||
private def buildTargetTask: Def.Initialize[Task[BuildTarget]] =
|
||||
Def
|
||||
.task {
|
||||
val buildTargetIdentifier = Keys.bspTargetIdentifier.value
|
||||
val thisProject = Keys.thisProject.value
|
||||
val thisProjectRef = Keys.thisProjectRef.value
|
||||
val thisConfig = Keys.configuration.value
|
||||
val scalaJars = Keys.scalaInstance.value.allJars.map(_.toURI.toString)
|
||||
val compileData = ScalaBuildTarget(
|
||||
scalaOrganization = scalaOrganization.value,
|
||||
scalaVersion = scalaVersion.value,
|
||||
scalaBinaryVersion = scalaBinaryVersion.value,
|
||||
platform = ScalaPlatform.JVM,
|
||||
jars = scalaJars.toVector
|
||||
)
|
||||
val configuration = Keys.configuration.value
|
||||
val displayName = BuildTargetName.fromScope(thisProject.id, configuration.name)
|
||||
val baseDirectory = Keys.baseDirectory.value.toURI
|
||||
val projectDependencies = for {
|
||||
(dep, configs) <- Keys.bspInternalDependencyConfigurations.value
|
||||
config <- configs
|
||||
if dep != thisProjectRef || config.name != thisConfig.name
|
||||
} yield (dep / config / Keys.bspTargetIdentifier)
|
||||
val capabilities =
|
||||
BuildTargetCapabilities(canCompile = true, canTest = true, canRun = true, canDebug = false)
|
||||
val tags = BuildTargetTag.fromConfig(configuration.name)
|
||||
(
|
||||
buildTargetIdentifier,
|
||||
displayName,
|
||||
baseDirectory,
|
||||
tags,
|
||||
capabilities,
|
||||
projectDependencies,
|
||||
compileData
|
||||
)
|
||||
}
|
||||
.flatMapTask {
|
||||
case (
|
||||
buildTargetIdentifier,
|
||||
displayName,
|
||||
baseDirectory,
|
||||
tags,
|
||||
capabilities,
|
||||
projectDependencies,
|
||||
compileData
|
||||
) =>
|
||||
Def.task {
|
||||
BuildTarget(
|
||||
buildTargetIdentifier,
|
||||
Some(displayName),
|
||||
Some(baseDirectory),
|
||||
tags,
|
||||
capabilities,
|
||||
BuildServerConnection.languages,
|
||||
projectDependencies.join.value.distinct.toVector,
|
||||
dataKind = Some("scala"),
|
||||
data = Some(Converter.toJsonUnsafe(compileData)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private def sbtBuildTarget(
|
||||
loadedUnit: LoadedBuildUnit,
|
||||
|
|
@ -701,28 +728,44 @@ object BuildServerProtocol {
|
|||
)
|
||||
}
|
||||
|
||||
private def scalacOptionsTask: Def.Initialize[Task[ScalacOptionsItem]] = Def.taskDyn {
|
||||
val target = Keys.bspTargetIdentifier.value
|
||||
val scalacOptions = Keys.scalacOptions.value
|
||||
val classDirectory = Keys.classDirectory.value
|
||||
val externalDependencyClasspath = Keys.externalDependencyClasspath.value
|
||||
|
||||
val internalDependencyClasspath = for {
|
||||
(ref, configs) <- bspInternalDependencyConfigurations.value
|
||||
config <- configs
|
||||
} yield ref / config / Keys.classDirectory
|
||||
|
||||
Def.task {
|
||||
val classpath = internalDependencyClasspath.join.value.distinct ++
|
||||
externalDependencyClasspath.map(_.data)
|
||||
ScalacOptionsItem(
|
||||
target,
|
||||
scalacOptions.toVector,
|
||||
classpath.map(_.toURI).toVector,
|
||||
classDirectory.toURI
|
||||
)
|
||||
}
|
||||
}
|
||||
private def scalacOptionsTask: Def.Initialize[Task[ScalacOptionsItem]] =
|
||||
Def
|
||||
.task {
|
||||
val target = Keys.bspTargetIdentifier.value
|
||||
val scalacOptions = Keys.scalacOptions.value
|
||||
val classDirectory = Keys.classDirectory.value
|
||||
val externalDependencyClasspath = Keys.externalDependencyClasspath.value
|
||||
val internalDependencyClasspath = for {
|
||||
(ref, configs) <- bspInternalDependencyConfigurations.value
|
||||
config <- configs
|
||||
} yield ref / config / Keys.classDirectory
|
||||
(
|
||||
target,
|
||||
scalacOptions,
|
||||
classDirectory,
|
||||
externalDependencyClasspath,
|
||||
internalDependencyClasspath
|
||||
)
|
||||
}
|
||||
.flatMapTask {
|
||||
case (
|
||||
target,
|
||||
scalacOptions,
|
||||
classDirectory,
|
||||
externalDependencyClasspath,
|
||||
internalDependencyClasspath
|
||||
) =>
|
||||
Def.task {
|
||||
val classpath = internalDependencyClasspath.join.value.distinct ++
|
||||
externalDependencyClasspath.map(_.data)
|
||||
ScalacOptionsItem(
|
||||
target,
|
||||
scalacOptions.toVector,
|
||||
classpath.map(_.toURI).toVector,
|
||||
classDirectory.toURI
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private def dependencySourcesItemTask: Def.Initialize[Task[DependencySourcesItem]] = Def.task {
|
||||
val targetId = Keys.bspTargetIdentifier.value
|
||||
|
|
|
|||
Loading…
Reference in New Issue