如何在build.sbt中一次更改范围内的许多设置?

时间:2014-07-20 18:42:01

标签: scala sbt

我想根据它们在build.sbt中应用的上下文对设置进行分组。而不是

foo in ThisBuild := bar

baz in ThisBuild := bar

bar in Compile := 5

quux in Compile := 7

我想要的东西大致看起来像(不关心特定的语法/ API,只是概念分组和缺乏重复)

in(ThisBuild) {
  foo := bar
  baz := bar
}

in(Compile) {
  bar  := 5
  quux := 7
}

这样的事可能/干净/惯用吗?

2 个答案:

答案 0 :(得分:3)

对于Compile配置,请使用inConfig,如下所示:

inConfig(Compile) {
  Seq(
    bar  := 5,
    quux := 7
  )
}

对于ThisBuild范围,请使用inScope,如下所示:

inScope(ThisScope.copy(project=Select(ThisBuild))) {
  Seq(
    foo := bar,
    baz := bar
  )
}

请注意,所有in*方法适用于Seq s。

另请注意,由于它们出现在build.sbt文件中,因此它们会自动作用于构建定义所属的项目。显然,in ThisBuild设置属于构建。

至于在in*文件中使用*.sbt方法的惯用性,我从未在文件中看到它们。由于他们很新(从0.13开始)人们可能还没有赶上他们的使用。

特征ProjectExtra提供inConfiginTaskinScope方法。 As @copumpkin pointed out in the comment没有inProject方法可以补充其他方法。我不知道为什么,但inScope需要 <{1}}和inConfig,因为它们几乎将范围映射到配置或其他轴未更改的任务。

供参考,这是inTask

的定义
Scope

答案 1 :(得分:2)

Defaults.scala

作为Jacek's answer的补充,我建议你看看sbt 0.13.5 JvmPlugin.scalaDefaults.scalaJvmPlugin是一个默认启用的自动插件,可添加compile:compiletest:test等基本JVM任务。

Defaults.defaultConfigs

例如,Defaults.defaultConfigs添加了compile:compiletest:test,如下所示:

lazy val defaultConfigs: Seq[Setting[_]] =
  inConfig(Compile)(compileSettings) ++
  inConfig(Test)(testSettings) ++
  inConfig(Runtime)(Classpaths.configSettings)

Defaults.testSettings

正如Jacek所说,传入设置中的预期类型都是Seq[Def.Setting[_]]。像

lazy val testSettings: Seq[Setting[_]] = configSettings ++ testTasks

Defaults.testTasks

这些序列可以通过追加以testTasks为不同方式的重用序列来构建:

lazy val testTasks: Seq[Setting[_]] =
  testTaskOptions(test) ++
  testTaskOptions(testOnly) ++
  testTaskOptions(testQuick) ++
  testDefaults ++ Seq(
    ....
    test := {
        val trl = (testResultLogger in (Test, test)).value
        val taskName = Project.showContextKey(state.value)(resolvedScoped.value)
        trl.run(streams.value.log, executeTests.value, taskName)
    },
    testOnly <<= inputTests(testOnly),
    testQuick <<= inputTests(testQuick)
)

项目范围和自动插件

如果您正在使用多项目build.sbt,则可以通过将设置传递给项目的设置方法来完成项目范围。

lazy val root = (project in file("."))

lazy val foo = project.
  settings(yourSettings: _*).
  settings(someOtherSettings: _*)

lazy val bar = project.
  settings(yourSettings: _*).
  settings(someOtherSettings: _*)

您可以在def yourSettings(或build.sbt)中定义project/foo.scala。当你开始明确地发现传递设置很乏味时,你可以定义一个类似于sbt的JvmPlugin的自动插件。这可以让你写:

lazy val root = (project in file("."))

lazy val foo = project.
  enablePlugins(FooPlugin, BarPlugin)

lazy val bar = project.
  enablePlugins(FooPlugin, BarPlugin)

修改

如果你凭空捏造FooPluginBarPlugin,你可以写下:

lazy val root = (project in file("."))

lazy val foo, bar = project

有关详细信息,请参阅Plugins

我想澄清一下,你可以选择自动插件的魔术/自动化程度。在上文中,FooPluginBarPlugin都是无中生触的,但您可以轻松地BarPlugin触发FooPlugin或根本不触发{{1}}。这意味着自动化诸如“为所有与Web相关的项目使用coffeescript插件”之类的东西。我希望我仍然可以回答您的问题“我想根据上下文对设置进行分组。”