SBT create sub-projects using a collection
reflection, sbt, scala, subproject
Solution
Sbt allows for making a build definition for the build itself:
http://www.scala-sbt.org/release/docs/Getting-Started/Full-Def.html
You can try creating a project/project/build.scala file that contains a source generator, something like this:
// project/project/build.scala
sourceGenerators in Compile <+= sourceManaged in Compile map { out =>
Generator.generate(out / "generated")
}
EDIT: You should implement the Generator object yourself.
This source generator will in turn scan the topmost apps folder and create a source for an object that contains all the subprojects.
// project/subprojects.scala
// This is autogenerated from the source generator
object Subprojects{
lazy val Sub1 = project.in(file("apps/Sub1"))
lazy val Sub2 = project.in(file("apps/Sub2"))
lazy val all = Seq(Sub1,Sub2)
}
Now in your main build.scala just write:
// project/build.scala
lazy val root = project.in(file("."))
.aggregate(Subprojects.all.map(sbt.Project.projectToRef) :_*)
.dependsOn(Subprojects.all.map(ClassPathDependency(_, None)) :_*)
I didn't run all this through a compiler so some errors are possible but the principle should work.
EDIT: I created a repo on Github where I implemented the solution. Go there and see how it is done.
https://github.com/darkocerdic/sbt-auto-subprojects
Problem
I've been searching if this is possible for a while with little success. Using SBT, can you create a sub-project programmatically, without explicitly assigning each project to it's own `val`? My current project structure looks something like this: ``` root/ common/ <--- This is another sub-project that others dependOn project/ build.scala src/main/scala apps/ <--- sub-projects live here Sub1/ Sub2/ ``` `Sub1` and `Sub2` are both their own SBT projects. My first attempt to link these projects together looked like this: ``` // root/project/build.scala import sbt._ import Keys._ object build extends Build { lazy val common = project /* Pseudo-code */ val names = List("Sub1", "Sub2") lazy val deps = names map { name => Project(id = name, base = file(s"apps/$name")).dependsOn(common) } lazy val finalDeps = common :: deps lazy val root = project.in(file(".")).aggregate(finalDeps.map(sbt.Project.projectToRef) :_*) .dependsOn(finalDeps.map(ClassPathDependency(_, None)) :_*) } ``` However, because SBT uses reflection to build it's projects and sub-projects, this doesn't work. It only works if each sub-project is stated explicitly: ``` lazy val Sub1 = project.in(file("apps/Sub1")) ``` So the question: Is there a way to programmatically build sub-project dependencies in SBT?