mirror of https://github.com/sbt/sbt.git
[2.x] fix: derivedProjects not invoked when no explicit root project is defined (#9012)
**Problem**
When build.sbt contains no explicit project definition (e.g. just bare settings with no lazy val root = project.in(file("."))), sbt creates a synthetic root project. In Load.loadTransitive, this synthetic root was processed with expand = false, which prevented AutoPlugin.derivedProjects from being called.
Any plugin relying on derivedProjects to inject projects would fail with "Reference to undefined setting" errors.
The workaround was to add an explicit root project in build.sbt (val root = project.in(file("."))), which caused the Some(root) branch to execute with expand = true.
**Solution**
Removed the expand variable from loadTransitive and pass true directly to processProject. Previously, the Some(root) branch set expand = true while the None branch set expand = false. Since derivedProjects should always be invoked for the root project regardless of whether it was explicitly defined or auto-generated, both branches should behave the same way. Eliminating the variable makes this intent clear.
This commit is contained in:
parent
4d71c15e87
commit
1f2d14aa3e
|
|
@ -1120,11 +1120,11 @@ private[sbt] object Load {
|
|||
buildBase
|
||||
)
|
||||
val discoveredIdsStr = discovered.map(_.id).mkString(",")
|
||||
val (root, expand, moreProjects, otherProjects) =
|
||||
val (root, moreProjects, otherProjects) =
|
||||
rootOpt match
|
||||
case Some(root) =>
|
||||
log.debug(s"[Loading] Found root project ${root.id} w/ remaining $discoveredIdsStr")
|
||||
(root, true, discovered, LoadedProjects(Nil, Nil))
|
||||
(root, discovered, LoadedProjects(Nil, Nil))
|
||||
case None =>
|
||||
log.debug(s"[Loading] Found non-root projects $discoveredIdsStr")
|
||||
// Here we do something interesting... We need to create an aggregate root project
|
||||
|
|
@ -1144,10 +1144,10 @@ private[sbt] object Load {
|
|||
)
|
||||
val existingIds = otherProjects.projects.map(_.id)
|
||||
val refs = existingIds.map(id => ProjectRef(buildUri, id))
|
||||
(root.aggregate(refs*), false, Nil, otherProjects)
|
||||
(root.aggregate(refs*), Nil, otherProjects)
|
||||
val (finalRoot, projectLevelExtra) =
|
||||
timed(s"Load.loadTransitive: processProject($root)", log) {
|
||||
processProject(root, files, extraFiles, expand)
|
||||
processProject(root, files, extraFiles, true)
|
||||
}
|
||||
val newProjects = moreProjects ++ projectLevelExtra
|
||||
val newAcc = finalRoot +: (acc ++ otherProjects.projects)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
@transient
|
||||
lazy val check = taskKey[Unit]("check")
|
||||
|
||||
check := {
|
||||
val v = (LocalProject("foo") / DerivedProjectPlugin.value1).value
|
||||
assert(v == 3, s"Expected 3 but got $v")
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import sbt._
|
||||
import sbt.Keys._
|
||||
|
||||
object DerivedProjectPlugin extends AutoPlugin {
|
||||
val value1 = settingKey[Int]("value1")
|
||||
|
||||
override def derivedProjects(proj: ProjectDefinition[?]) =
|
||||
proj.projectOrigin match {
|
||||
case ProjectOrigin.DerivedProject =>
|
||||
Nil
|
||||
case _ =>
|
||||
Seq(
|
||||
Project("foo", file("foo")).settings(
|
||||
value1 := 3,
|
||||
name := "foo",
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override def trigger = allRequirements
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# derivedProjects should work even without an explicit root project
|
||||
> check
|
||||
Loading…
Reference in New Issue