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?

Original source