mirror of https://github.com/sbt/sbt.git
When an AutoPlugin adds a project at the build root via extraProjects, avoid creating a second root from the build definition so both do not share the same target directory. Treat extraProjects root as 'root already defined' and exclude the build-defined root from initialProjects when both would be at the same base.
This commit is contained in:
parent
12deebba2b
commit
52bc35e3a9
|
|
@ -812,10 +812,17 @@ private[sbt] object Load {
|
||||||
mkReporter,
|
mkReporter,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val projectsFromBuildDef = defsScala.flatMap(b => projectsFromBuild(b, normBase))
|
||||||
|
val rootFromExtra =
|
||||||
|
buildLevelExtraProjects.filter(p => isRootPath(p.base, normBase))
|
||||||
val initialProjects =
|
val initialProjects =
|
||||||
defsScala.flatMap(b => projectsFromBuild(b, normBase)) ++ buildLevelExtraProjects
|
if rootFromExtra.nonEmpty then
|
||||||
|
projectsFromBuildDef.filterNot(p =>
|
||||||
val hasRootAlreadyDefined = defsScala.exists(_.rootProject.isDefined)
|
isRootPath(p.base, normBase)
|
||||||
|
) ++ buildLevelExtraProjects
|
||||||
|
else projectsFromBuildDef ++ buildLevelExtraProjects
|
||||||
|
val hasRootAlreadyDefined =
|
||||||
|
defsScala.exists(_.rootProject.isDefined) || rootFromExtra.nonEmpty
|
||||||
|
|
||||||
val memoSettings = new mutable.HashMap[VirtualFile, LoadedSbtFile]
|
val memoSettings = new mutable.HashMap[VirtualFile, LoadedSbtFile]
|
||||||
def loadProjects(ps: Seq[Project], createRoot: Boolean) =
|
def loadProjects(ps: Seq[Project], createRoot: Boolean) =
|
||||||
|
|
@ -1086,11 +1093,9 @@ private[sbt] object Load {
|
||||||
val DiscoveredProjects(rootOpt, discovered, files, extraFiles, generated) = discover(
|
val DiscoveredProjects(rootOpt, discovered, files, extraFiles, generated) = discover(
|
||||||
p.base
|
p.base
|
||||||
)
|
)
|
||||||
|
val root =
|
||||||
// TODO: We assume here the project defined in a build.sbt WINS because the original was a
|
if p.projectOrigin == ProjectOrigin.ExtraProject && isRootPath(p.base, buildBase) then p
|
||||||
// phony. However, we may want to 'merge' the two, or only do this if the original was a
|
else rootOpt.getOrElse(p)
|
||||||
// default generated project.
|
|
||||||
val root = rootOpt.getOrElse(p)
|
|
||||||
val (finalRoot, projectLevelExtra) = processProject(root, files, extraFiles, true)
|
val (finalRoot, projectLevelExtra) = processProject(root, files, extraFiles, true)
|
||||||
val newProjects = rest ++ discovered ++ projectLevelExtra
|
val newProjects = rest ++ discovered ++ projectLevelExtra
|
||||||
val newAcc = acc :+ finalRoot
|
val newAcc = acc :+ finalRoot
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
// Minimal build so the build definition contributes a root; the plugin's extraProjects
|
||||||
|
// root (foo at file(".")) should win and be the only root (#4976).
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* sbt
|
||||||
|
* Copyright 2023, Scala center
|
||||||
|
* Copyright 2011 - 2022, Lightbend, Inc.
|
||||||
|
* Copyright 2008 - 2010, Mark Harrah
|
||||||
|
* Licensed under Apache License 2.0 (see LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import sbt._, Keys._
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reproduces #4976 / Dale's use case: plugin defines the root project via extraProjects.
|
||||||
|
* Without the fix, loading fails with "Overlapping output directories" (build root + foo).
|
||||||
|
*/
|
||||||
|
object RootFromExtraPlugin extends AutoPlugin {
|
||||||
|
override def trigger = allRequirements
|
||||||
|
override def extraProjects: Seq[Project] =
|
||||||
|
Seq(Project("foo", file(".")).settings(name := "foo"))
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Root project is defined by plugin via extraProjects (#4976). Without the fix,
|
||||||
|
# loading fails with "Overlapping output directories" (build root + foo).
|
||||||
|
|
||||||
|
> compile
|
||||||
|
|
||||||
|
> show name
|
||||||
Loading…
Reference in New Issue