mirror of https://github.com/sbt/sbt.git
Merge pull request #4056 from BennyHill/fix/3042
Introduce CompositeProject
This commit is contained in:
commit
4fc45e0155
|
|
@ -121,7 +121,45 @@ sealed trait ProjectDefinition[PR <: ProjectReference] {
|
||||||
if (ts.isEmpty) Nil else s"$label: $ts" :: Nil
|
if (ts.isEmpty) Nil else s"$label: $ts" :: Nil
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait Project extends ProjectDefinition[ProjectReference] {
|
trait CompositeProject {
|
||||||
|
def componentProjects: Seq[Project]
|
||||||
|
}
|
||||||
|
|
||||||
|
private[sbt] object CompositeProject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand user defined projects with the component projects of `compositeProjects`.
|
||||||
|
*
|
||||||
|
* If two projects with the same id appear in the user defined projects and
|
||||||
|
* in `compositeProjects.componentProjects`, the user defined project wins.
|
||||||
|
* This is necessary for backward compatibility with the idioms:
|
||||||
|
* {{{
|
||||||
|
* lazy val foo = crossProject
|
||||||
|
* lazy val fooJS = foo.js.settings(...)
|
||||||
|
* lazy val fooJVM = foo.jvm.settings(...)
|
||||||
|
* }}}
|
||||||
|
* and the rarer:
|
||||||
|
* {{{
|
||||||
|
* lazy val fooJS = foo.js.settings(...)
|
||||||
|
* lazy val foo = crossProject
|
||||||
|
* lazy val fooJVM = foo.jvm.settings(...)
|
||||||
|
* }}}
|
||||||
|
*/
|
||||||
|
def expand(compositeProjects: Seq[CompositeProject]): Seq[Project] = {
|
||||||
|
val userProjects = compositeProjects.collect { case p: Project => p }
|
||||||
|
for (p <- compositeProjects.flatMap(_.componentProjects)) yield {
|
||||||
|
userProjects.find(_.id == p.id) match {
|
||||||
|
case Some(userProject) => userProject
|
||||||
|
case None => p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.distinct
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed trait Project extends ProjectDefinition[ProjectReference] with CompositeProject {
|
||||||
|
def componentProjects: Seq[Project] = this :: Nil
|
||||||
|
|
||||||
private[sbt] def copy(
|
private[sbt] def copy(
|
||||||
id: String = id,
|
id: String = id,
|
||||||
base: File = base,
|
base: File = base,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@ import sbt.internal.inc.ReflectUtilities
|
||||||
|
|
||||||
trait BuildDef {
|
trait BuildDef {
|
||||||
def projectDefinitions(@deprecated("unused", "") baseDirectory: File): Seq[Project] = projects
|
def projectDefinitions(@deprecated("unused", "") baseDirectory: File): Seq[Project] = projects
|
||||||
def projects: Seq[Project] = ReflectUtilities.allVals[Project](this).values.toSeq
|
def projects: Seq[Project] =
|
||||||
|
CompositeProject.expand(ReflectUtilities.allVals[CompositeProject](this).values.toSeq)
|
||||||
// TODO: Should we grab the build core settings here or in a plugin?
|
// TODO: Should we grab the build core settings here or in a plugin?
|
||||||
def settings: Seq[Setting[_]] = Defaults.buildCore
|
def settings: Seq[Setting[_]] = Defaults.buildCore
|
||||||
def buildLoaders: Seq[BuildLoader.Components] = Nil
|
def buildLoaders: Seq[BuildLoader.Components] = Nil
|
||||||
|
|
|
||||||
|
|
@ -151,10 +151,12 @@ private[sbt] object EvaluateConfigurations {
|
||||||
val allGeneratedFiles = (definitions.generated ++ dslEntries.flatMap(_.generated))
|
val allGeneratedFiles = (definitions.generated ++ dslEntries.flatMap(_.generated))
|
||||||
loader =>
|
loader =>
|
||||||
{
|
{
|
||||||
val projects =
|
val projects = {
|
||||||
definitions.values(loader).collect {
|
val compositeProjects = definitions.values(loader).collect {
|
||||||
case p: Project => resolveBase(file.getParentFile, p)
|
case p: CompositeProject => p
|
||||||
}
|
}
|
||||||
|
CompositeProject.expand(compositeProjects).map(resolveBase(file.getParentFile, _))
|
||||||
|
}
|
||||||
val (settingsRaw, manipulationsRaw) =
|
val (settingsRaw, manipulationsRaw) =
|
||||||
dslEntries map (_.result apply loader) partition {
|
dslEntries map (_.result apply loader) partition {
|
||||||
case DslEntry.ProjectSettings(_) => true
|
case DslEntry.ProjectSettings(_) => true
|
||||||
|
|
@ -280,7 +282,10 @@ private[sbt] object EvaluateConfigurations {
|
||||||
}
|
}
|
||||||
|
|
||||||
private[this] def extractedValTypes: Seq[String] =
|
private[this] def extractedValTypes: Seq[String] =
|
||||||
Seq(classOf[Project], classOf[InputKey[_]], classOf[TaskKey[_]], classOf[SettingKey[_]])
|
Seq(classOf[CompositeProject],
|
||||||
|
classOf[InputKey[_]],
|
||||||
|
classOf[TaskKey[_]],
|
||||||
|
classOf[SettingKey[_]])
|
||||||
.map(_.getName)
|
.map(_.getName)
|
||||||
|
|
||||||
private[this] def evaluateDefinitions(eval: Eval,
|
private[this] def evaluateDefinitions(eval: Eval,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
[#3042]: https://github.com/sbt/sbt/issues/3042
|
||||||
|
[#4056]: https://github.com/sbt/sbt/pull/4056
|
||||||
|
|
||||||
|
### Introduce CompositeProject
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
- Support for: `lazy val foo = someCompositeProject` (e.g.`CrossProject`) [#3042][]/[#4056][]
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import sbt.internal.AddSettings
|
||||||
|
import sbt.CompositeProject
|
||||||
|
|
||||||
|
lazy val check = taskKey[Unit]("check")
|
||||||
|
|
||||||
|
// Based on sbt-file-projects test
|
||||||
|
lazy val foo = new CompositeProject
|
||||||
|
{
|
||||||
|
val jvm = Project.apply("jvm", new File("jvm")).settings(version := "0.1.0") // this one needs to win
|
||||||
|
val js = Project.apply("js", new File("js")).settings(version := "0.1.0") // this one needs to win
|
||||||
|
def componentProjects: Seq[Project] = Seq(jvm, js)
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy val fooJS = foo.js
|
||||||
|
lazy val fooJVM = foo.jvm
|
||||||
|
|
||||||
|
lazy val bar = project
|
||||||
|
.dependsOn(foo.jvm)
|
||||||
|
|
||||||
|
val g = taskKey[Unit]("A task in the root project")
|
||||||
|
g := println("Hello.")
|
||||||
|
|
||||||
|
|
||||||
|
check := {
|
||||||
|
val verJvm = (version in foo.jvm).?.value
|
||||||
|
assert (verJvm == Some("0.1.0"))
|
||||||
|
|
||||||
|
val verFooJvm = (version in fooJVM).?.value
|
||||||
|
assert (verFooJvm == Some("0.1.0"))
|
||||||
|
|
||||||
|
val verJs = (version in foo.js).?.value
|
||||||
|
assert (verJs == Some("0.1.0"))
|
||||||
|
|
||||||
|
val verFooJs = (version in fooJS).?.value
|
||||||
|
assert (verFooJs == Some("0.1.0"))
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
lazy val root = (project in file("."))
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import sbt.internal.AddSettings
|
||||||
|
import sbt.CompositeProject
|
||||||
|
|
||||||
|
lazy val check = taskKey[Unit]("check")
|
||||||
|
|
||||||
|
// Based on sbt-file-projects test
|
||||||
|
lazy val foo = new CompositeProject
|
||||||
|
{
|
||||||
|
val jvm = Project.apply("jvm", new File("jvm")).settings(version := "0.1.0")
|
||||||
|
val js = Project.apply("js", new File("js")).settings(version := "0.1.0") // this one needs to win
|
||||||
|
def componentProjects: Seq[Project] = Seq(jvm, js)
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy val fooJS = foo.js
|
||||||
|
lazy val fooJVM = foo.jvm.settings(version := "0.2.0") // this one needs to win
|
||||||
|
|
||||||
|
lazy val bar = project
|
||||||
|
.dependsOn(foo.jvm)
|
||||||
|
|
||||||
|
val g = taskKey[Unit]("A task in the root project")
|
||||||
|
g := println("Hello.")
|
||||||
|
|
||||||
|
|
||||||
|
check := {
|
||||||
|
val verJvm = (version in foo.jvm).?.value
|
||||||
|
assert (verJvm == Some("0.2.0"))
|
||||||
|
|
||||||
|
val verFooJvm = (version in fooJVM).?.value
|
||||||
|
assert (verFooJvm == Some("0.2.0"))
|
||||||
|
|
||||||
|
val verJs = (version in foo.js).?.value
|
||||||
|
assert (verJs == Some("0.1.0"))
|
||||||
|
|
||||||
|
val verFooJs = (version in fooJS).?.value
|
||||||
|
assert (verFooJs == Some("0.1.0"))
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import sbt.internal.AddSettings
|
||||||
|
import sbt.CompositeProject
|
||||||
|
|
||||||
|
lazy val check = taskKey[Unit]("check")
|
||||||
|
|
||||||
|
lazy val fooJS = foo.js.settings(version := "0.2.1") // this one needs to win
|
||||||
|
|
||||||
|
// Based on sbt-file-projects test
|
||||||
|
lazy val foo = new CompositeProject
|
||||||
|
{
|
||||||
|
val jvm = Project.apply("jvm", new File("jvm")).settings(version := "0.1.0")
|
||||||
|
val js = Project.apply("js", new File("js")).settings(version := "0.1.0")
|
||||||
|
def componentProjects: Seq[Project] = Seq(jvm, js)
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy val fooJVM = foo.jvm.settings(version := "0.2.0") // this one needs to win
|
||||||
|
|
||||||
|
lazy val bar = project
|
||||||
|
.dependsOn(foo.jvm)
|
||||||
|
|
||||||
|
val g = taskKey[Unit]("A task in the root project")
|
||||||
|
g := println("Hello.")
|
||||||
|
|
||||||
|
|
||||||
|
check := {
|
||||||
|
val verJvm = (version in foo.jvm).?.value
|
||||||
|
assert (verJvm == Some("0.2.0"))
|
||||||
|
|
||||||
|
val verFooJvm = (version in fooJVM).?.value
|
||||||
|
assert (verFooJvm == Some("0.2.0"))
|
||||||
|
|
||||||
|
val verJs = (version in foo.js).?.value
|
||||||
|
assert (verJs == Some("0.2.1"))
|
||||||
|
|
||||||
|
val verFooJs = (version in fooJS).?.value
|
||||||
|
assert (verFooJs == Some("0.2.1"))
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
val h = taskKey[Unit]("A task in project 'js'")
|
||||||
|
h := println("Hello.")
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
object A
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
val aa = taskKey[Unit]("A task in the 'jvm' project")
|
||||||
|
aa := println("Hello.")
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
val c = project
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
> g
|
||||||
|
-> root/compile
|
||||||
|
> jvm/compile
|
||||||
|
> jvm/aa
|
||||||
|
> js/compile
|
||||||
|
> js/h
|
||||||
|
> c/compile
|
||||||
|
> bar/compile
|
||||||
|
|
||||||
|
$ copy-file changes/basic.sbt basic.sbt
|
||||||
|
> reload
|
||||||
|
> g
|
||||||
|
> root/compile
|
||||||
|
> jvm/compile
|
||||||
|
> jvm/aa
|
||||||
|
> js/compile
|
||||||
|
> js/h
|
||||||
|
> c/compile
|
||||||
|
> bar/compile
|
||||||
|
> check
|
||||||
|
|
||||||
|
$ copy-file changes/shadow.sbt build.sbt
|
||||||
|
> reload
|
||||||
|
> jvm/compile
|
||||||
|
> jvm/aa
|
||||||
|
> js/compile
|
||||||
|
> js/h
|
||||||
|
> c/compile
|
||||||
|
> bar/compile
|
||||||
|
> check
|
||||||
|
|
||||||
|
$ copy-file changes/shadowLazy.sbt build.sbt
|
||||||
|
> reload
|
||||||
|
> jvm/compile
|
||||||
|
> jvm/aa
|
||||||
|
> js/compile
|
||||||
|
> js/h
|
||||||
|
> c/compile
|
||||||
|
> bar/compile
|
||||||
|
> check
|
||||||
Loading…
Reference in New Issue