【问题标题】:sbt idiomatic way to add settings添加设置的 sbt 惯用方式
【发布时间】:2016-07-19 10:05:40
【问题描述】:

我在开源 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 是否仍添加到我的项目中)?

【问题讨论】:

    标签: scala sbt


    【解决方案1】:

    这两者之间似乎有区别

    .settings(Seq(...))
    

    将您的序列附加到项目中的“设置”中,但是

    Project(settings = ...)
    

    只写设置而不保存旧值。

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

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

    来自 sbt 来源的几个 sn-ps:

    /**
     * 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)
    

    【讨论】:

    【解决方案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(
        ...
      )
    )
    

    全局级方式

    或者您可以在 ~/.sbt/SBT_VERSION/global.sbt 中将 ensime 设置添加到全局级别的默认项目设置中

    import org.ensime.EnsimePlugin
    
    EnsimePlugin.projectSettings
    

    【讨论】:

    • 尝试“全局级别的方式”我得到一个“对象 ensime 不是包 org 的成员”错误。我还需要在我的全局配置中添加其他内容以使其正常工作吗?
    • 您需要启用 ensime 插件。将addSbtPlugin("org.ensime" % "sbt-ensime" % "1.0.0") 添加到~/.sbt/SBT_VERSION/plugins/build.sbt
    猜你喜欢
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 2019-08-09
    相关资源
    最近更新 更多