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`
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:
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! "