用于添加设置的惯用方法

时间:2016-01-28 16:46:06

标签: scala sbt

我在开源sbt项目中看到了很多:

lazy val project = Project(
  id = "root",
  base = file("."),
  settings = Project.defaultSettings ++ Seq(
    ...
  )
)

我们也为我们的内部项目采用了这个惯例。然而今天我尝试使用这样的项目sbt-ensime并运行“gen-ensime”给了我一个错误:

[error] (*:update) java.lang.IllegalArgumentException: Cannot add dependency 'org.scala-lang#scala-compiler;2.11.7' to configuration 'ensime-internal' of module ... because this configuration doesn't exist!

建议的修复方法如下:https://github.com/ensime/ensime-sbt/issues/145

它建议我将我的项目更改为:

lazy val project = Project(
  id = "root",
  base = file(".")
).settings(Seq(
  ...
)

我的问题是:这是建议的方式来定义项目惯用语和首选sbt吗?使用此功能是否会丢失任何内容(特别是,仍然将defaultSettings添加到我的项目中)?

2 个答案:

答案 0 :(得分:3)

这两者之间似乎有区别

.settings(Seq(...))

将您的序列附加到'设置'在项目中,但

Project(settings = ...)

只需在不保存旧值的情况下编写设置。

因此看起来.settings()是更安全的方法。

一般来说.settings()现在更加惯用,因为有些sbt插件可能 尝试修改项目构建中的设置。

来自某些来源的几个片段:

/**
 * The explicitly defined sequence of settings that configure this project.
 * These do not include the automatically appended settings as configured by `auto`.
 */
def settings: Seq[Setting[_]]

/** Appends settings to the current settings sequence for this project. */
def settings(ss: Def.SettingsDefinition*): Project = copy(settings = (settings: Seq[Def.Setting[_]]) ++ Def.settings(ss: _*))

// TODO: Modify default settings to be the core settings, and automatically add the IvyModule + JvmPlugins.
def apply(id: String, base: File, aggregate: => Seq[ProjectReference] = Nil, dependencies: => Seq[ClasspathDep[ProjectReference]] = Nil,
    delegates: => Seq[ProjectReference] = Nil, settings: => Seq[Def.Setting[_]] = Nil, configurations: Seq[Configuration] = Nil,
    auto: AddSettings = AddSettings.allDefaults): Project =
    unresolved(id, base, aggregate, dependencies, delegates, settings, configurations, auto, Plugins.empty, Nil) // Note: JvmModule/IvyModule auto included...

def copy(id: String = id, base: File = base, aggregate: => Seq[ProjectReference] = aggregate, dependencies: => Seq[ClasspathDep[ProjectReference]] = dependencies,
    delegates: => Seq[ProjectReference] = delegates, settings: => Seq[Setting[_]] = settings, configurations: Seq[Configuration] = configurations,
    auto: AddSettings = auto): Project =
    unresolved(id, base, aggregate = aggregate, dependencies = dependencies, delegates = delegates, settings, configurations, auto, plugins, autoPlugins)

答案 1 :(得分:2)

这两种方法都有权存在。在构造函数Project(settings = ...)中传递设置来自过去,当SBT配置是静态的时。随着 autoplugin 的出现,配置概念转变为可变范式,Project().settings(...)与之兼容。

我更喜欢第一种方法,因为它更明确。

[error] (*:update) java.lang.IllegalArgumentException:
        Cannot add dependency 'org.scala-lang#scala-compiler;2.11.7' to configuration 'ensime-internal' of module ...
        because this configuration doesn't exist!

错误可以通过两种方式解决:

项目级方式

您可以在项目定义中明确添加ensime设置

import org.ensime.EnsimePlugin

lazy val project = Project(
  id = "root",
  base = file("."),
  settings = Project.defaultSettings ++ EnsimePlugin.projectSettings ++ Seq(
    ...
  )
)

全球级方式

或者您可以将ensime设置添加到~/.sbt/SBT_VERSION/global.sbt

中的全局级别的默认项目设置中
import org.ensime.EnsimePlugin

EnsimePlugin.projectSettings