pawel.panasewicz
pawel.panasewicz

Reputation: 1833

How to override SettingKey for computing another SettingKey in sbt?

I want to override the value of a SettingKey b only when computing SettingKey a1.

import sbt._
import sbt.Keys._

object Build extends Build {
  val a1Key = SettingKey[String]("a1", "")
  val a2Key = SettingKey[String]("a2", "")
  val bKey  = SettingKey[String]("b", "")

  lazy val rootProject = Project("P", file(".")).settings(
   bKey := "XXX",
   a1Key <<= bKey((x) => ">>>"+x+"<<<"),
   a2Key <<= bKey((x) => ">>>"+x+"<<<")
  ) .settings(
   bKey in a1Key := "YYY"   //providing custom value in setting scope
  ) 
}

Current result is

> a1
[info] >>>XXX<<<
> a2
[info] >>>XXX<<<
> b
[info] XXX      

...but I'm aiming at seeing YYY as the value of a1:

> a1
[info] >>>YYY<<<
> a2
[info] >>>XXX<<<
> b
[info] XXX  

Better real world example than above is when you want to add some resources to your build only in runtime configuration, and some other resources when the application is packaged. For example building GWT app public resources served by server during development-mode and during production are different. It would be nice for example to customize setting resource-directories for run and package tasks.

Upvotes: 4

Views: 1258

Answers (1)

user500592
user500592

Reputation:

You need to set a1Key and a2Key to allow for bKey to be overridden in the first place:

lazy val rootProject = Project("P", file(".")).settings(
  bKey := "Fnord",
  a1Key <<= (bKey in a1Key)(x => ">>>" + x + "<<<"),
  a2Key <<= (bKey in a2Key)(x => ">>>" + x + "<<<")
).settings(
  bKey in a1Key := "Meep"
)

That way, computing a1Key will use the more specific value Meep and while computing a2Key, sbt would "look for" the definition of bKey in a2Key and then, because it doesn't "find" it, falls back to the more general bKey (in the default scope), which is defined and therefore used.

Edit: this unfortunately means, that unless whoever provides the definitions of the a1Key and a2Key settings also explicitly provides the required extension points (in the form of setting-scoped dependencies), you cannot override the dependencies. That is at least how I understand it.

Upvotes: 2

Related Questions