How to change value of setting for a custom config

2019-07-13 05:47发布

问题:

I have a play project, and I want to add an sbt task that runs the application with a given folder available as a resource. However, I don't want that folder to be on the classpath during "normal" runs.

I created a configuration, added the resources to that configuration, but when I run in that configuration, the files aren't being picked up

for example, I have:

val Mock = config(“mock”) extend Compile
val mock = inputKey[Unit]("run in mock mode")

val project = Project(“my project”, file(“src/”))
.configs(Mock)
.settings(
      unmanagedResourceDirectories in Mock ++= Seq(baseDirectory.value / “mock-resources”)
      mock <<= run in Mock
)

I want it so that when I type mock the mock-resources is on the classpath, and when i type run it isn't.

I'm using play 2.2.0 with sbt 0.13.1

回答1:

You need to set the appropriate settings and tasks that are under Compile configuration to the newly-defined Mock configuration. The reason for this is this:

lazy val Mock = config("mock") extend Compile

When there's no setting or task under Mock sbt keeps searching in Compile where run is indeed defined but uses Compile values.

Do the following and it's going to work - note Classpaths.configSettings and run in Seq:

lazy val Mock = config("mock") extend Compile

lazy val mock = inputKey[Unit]("run in mock mode")

lazy val mockSettings = inConfig(Mock) {
  Classpaths.configSettings ++
  Seq(
    unmanagedClasspath += baseDirectory.value / "mock-resources",
    mock <<= run in Mock,
    run <<= Defaults.runTask(fullClasspath in Mock, mainClass in Mock, runner in Mock)
  )
}

lazy val p = (project in file("src/")).configs(Mock).settings(
  mockSettings: _*
)

NOTE I'm unsure why I needed the following line:

run <<= Defaults.runTask(fullClasspath in Mock, mainClass in Mock, runner in Mock)

My guess is that because run uses fullClasspath that defaults to Compile scope it doesn't see the value in Mock. sbt keeps amazing me!

I've asked about it in Why does the default run task not pick settings in custom configuration?

Sample

I've been running the build with the following hello.scala under src directory:

object Hello extends App {
    val r = getClass.getResource("/a.properties")
    println(s"resource: $r")
}

Upon p/mock:mock it gave me:

> p/mock:mock
[info] Running Hello
resource: file:/Users/jacek/sandbox/mock-config/src/mock-resources/a.properties

Same for p/mock:run:

> p/mock:run
[info] Running Hello
resource: file:/Users/jacek/sandbox/mock-config/src/mock-resources/a.properties

And mock was no different:

> mock
[info] Running Hello
resource: file:/Users/jacek/sandbox/mock-config/src/mock-resources/a.properties