chriskilding
chriskilding

Reputation: 849

Multiple SBT Configurations should be exclusive, but they all activate at the same time - why?

I have defined a minimal build.sbt with two custom profiles ‘dev’ and ‘staging’ (what SBT seems to call Configurations). However, when I run SBT with the Configuration that was defined first in the file (dev), both Configuration blocks are executed - and if both modify the same setting, the last one wins (staging).

This seems to break any notion of conditional activation, so what am I doing wrong with SBT?

For reference, I want to emulate the conditionally activated Profiles concept of Maven e.g. mvn test -P staging.

SBT version: 1.2.1

build.sbt:

name := "example-project"
scalaVersion := "2.12.6"
...

fork := true

// Environment-independent JVM property (always works)
javaOptions += "-Da=b"

// Environment-specific JVM property (doesn’t work)
lazy val Dev = config("dev") extend Test
lazy val Staging = config("staging") extend Test
val root = (project in file("."))
  .configs(Dev, Staging)
  .settings(inConfig(Dev)(Seq(javaOptions in Test += "-Dfoo=bar")))
  .settings(inConfig(Staging)(Seq(javaOptions in Test += "-Dfoo=qux")))

Command:

# Bad
sbt test
  => foo=qux
     a=b

# Bad
sbt clean dev:test
  => foo=qux
     a=b

# Good
sbt clean staging:test
  => foo=qux
     a=b

Upvotes: 1

Views: 266

Answers (1)

laughedelic
laughedelic

Reputation: 6460

Notice that despite of the inConfig usage you're still setting javaOptions in Test, i.e. in the Test config. If you remove in Test, it works as expected:

...
  .settings(inConfig(Dev)(javaOptions += "-Dfoo=bar"))
  .settings(inConfig(Staging)(javaOptions += "-Dfoo=qux"))

(also Seq(...) wrapping is unnecessary)

Now in sbt:

> show Test/javaOptions
[info] *

> show Dev/javaOptions
[info] * -Dfoo=bar

> show Staging/javaOptions
[info] * -Dfoo=qux

You can achieve the same result by scoping each setting explicitly (without inConfig wrapping):

  .settings(
    Dev/javaOptions += "-Dfoo=bar",
    Staging/javaOptions += "-Dfoo=qux",
    ...
  )

(here Conf/javaOptions is the same as javaOptions in Conf)

Upvotes: 1

Related Questions