Sbt multi-module build - maintain module dep graph as libraryDependencies in modules

Viewed 577

I'm trying to come up with a structure for a large, multi-module sbt project that satisfies the following requirements:

  1. When the root project is built, dependencies are first resolved from the modules available under the root ( i.e. if module A depends on module B version 2, which is the version of B available under the root, satisfy the dependency with whatever the build for B produces )

  2. When modules are built individually, dependencies are resolved from repositories ( local, cache, remote )

I am aware of two vehicles to define dependencies to an sbt project: dependsOn() and the libraryDependencies setting key.

So far, in my naive structure, where all build information for the modules (A, B) was tracked at the root, I simply passed .dependsOn the project references, and the inter-module dependencies were correctly resolved in the build of R

current build

What I would like to do, is to move/track this relationship in the build.sbt file of the modules themselves, which are then hosted in separate repositories (and pulled back occasionally to an "aggregate" tag of the parent project's repo via git submodule)

desired build

I've never had any problem doing this with maven (I assume because of being able to refer to a parent explicitly in the module's pom and there being only one way to establish a dependency) but I can't yet wrap my head around how to get it going in sbt

So my question is, will I have to write a custom resolver for this? Is there anything obvious I'm missing here?

Thanks.

1 Answers

I'm also having a similar setup, with an aggregate project with 100+ sub-projects. Sub-project also live in their own repository and can be built/published stand-alone or as part of the aggregate project. I don't need any special resolver for this to work.

I'm just combining both approaches you described:

project A:

groupId := "groupId"
version := "1.0.0-SNAPSHOT"
libraryDependencies += "groupId" %% "B" % version

project B:

groupId := "groupId"
version := "1.0.0-SNAPSHOT"

project R:

lazy val a = (project in file(a)).dependsOn(b)
lazy val b = (project in file(b))

I noticed that sbt is clever enough not to include the dependency on b twice.

Related