5

How do I override a sub-project setting/task in a multi-build SBT project? For example, here are two very simple SBT projects:

~/projects/backend/build.sbt

name := "backend"

// old version of scala
scalaVersion := "2.9.1"

~/mycode/docker_builder/build.sbt

lazy val backend = RootProject(file("~/projects/backend"))

lazy val root = (project in file(".")).
settings(
  // Doesn't work because sub-project already defines name
  name in backend := "sub-overriden",

  // Doesn't override {backend/}backend/*:scalaVersion since backend already defines scalaVersion in Global config
  scalaVersion in backend := "2.10.1",

  // Does define new setting in sub-project: {backend/}backend/test:scalaVersion (because backend did not define scalaVersion in test config)
  scalaVersion in (backend, Test) := "2.10.2"
).
aggregate(sub1)
// dependsOn(sub1)

In the sample above, I'm trying to override both name and scalaVersion, but as noted in the comments, the root project is not able to override any setting/task explicitly defined explicitly in the backend project. Now I'm assuming this is expected behavior, since RootProject and it's parent ProjectReference point to a completely different SBT build, but if this is the case, why are we allowed to introduce new settings into the build, e.g: scalaVersion in (backend, Test)?

Any workarounds or other solutions?

The sample backend project above is a gross oversimplification--our actual backend project in our team is based on the multi-project format with about a dozen or two sub-projects and sbt-plugins--however, fortunately I'm able to reproduce the issue with the listing above.

Related:
How to define build-scoped settings in multi-project .sbt builds?
Setting javac options for SBT dependencies
Use common settings in SBT `RootProject`

Community
  • 1
  • 1
Saad Malik
  • 1,598
  • 1
  • 18
  • 20

2 Answers2

1

There doesn't seem to be any way to override settings from the subproject directly from the main build. When you create the Project its settings doesn't even contain the definitions from the subproject's build.sbt yet.

What you can do though is call .addSbtFiles(file("overrides.sbt")) (paths are resolved relative to the subproject's base dir) and then put the overrides into this separate file which is loaded after the subproject's build.sbt.

szeiger
  • 1,406
  • 9
  • 11
1

Very old question, but I could not find any good solution and this question pointed me to a acceptable solution with the following features in sbt:

  • You can use ? on a key to return an option
  • The effect shown in this question about unset properties in sub-projects can be set in parent
  • assigning a key based on another key value

Define the property in both, the child and the parent:

lazy val testProperty = settingKey[String]("Test Prop")

In the child project you set the property value conditionally like:

testProperty := testProperty.?.value.getOrElse("~ child default! ~")

In the parent project you set the property value normally:

childProject / testProperty := "# parent override! "
Miquel
  • 4,741
  • 3
  • 20
  • 19