如何以 DRY 方式 filter/disable SBT 中所有子项目的 scalac 选项

How to filter/disable a scalac option for all subprojects in SBT in a DRY way

我的项目有多个子项目,我在这个项目中使用sbt-tpolecat1。 我在代码中使用 Java 框架。该框架大量使用流畅的界面,因此我需要在我的代码中抑制许多 "discarded non-Unit value" 警告。

这个 sbt-tpolecat 提供了许多开箱即用的有用的 scalac 选项,我只想排除我的用例的 -Wvalue-discard scalac 选项。

问题是我在这个项目中有 4-5 个子项目2。现在我需要将以下内容添加到每个子项目的 settings:

sub_project_name.settings(
  scalacOptions ~= (_.filterNot(Set("-Wvalue-discard")))
)
// or
sub_project_name.settings(valueDiscardSetting)

lazy val valueDiscardSetting =
  Seq(scalacOptions ~= (_.filterNot(Set("-Wvalue-discard"))))

有没有办法以DRY方式在所有子项目中排除这个选项? 我当前的子项目层次结构与此类似:

App -> Frontend -> Common
    -> Backend  -> Common

常用设置值

在多项目构建中有factoring out common settings的常见做法

define a sequence of common settings in a val and add them to each project. Less concepts to learn that way.

例如

lazy val commonSettings = Seq(
  scalacOptions ~= (_.filterNot(Set("-Wvalue-discard"))),
  ...
)

lazy val util = (project in file("util")).settings(commonSettings)
lazy val core = (project in file("core")).settings(commonSettings)

常用设置自动插件

可以为每个项目设置设置。在project/CommonSettingsPlugin.scala

下创建如下小插件
object CommonSettingsPlugin extends AutoPlugin {
  override def requires = plugins.JvmPlugin
  override def trigger = allRequirements
  override lazy val projectSettings = Seq(
    scalacOptions ~= (_.filterNot(Set("-Wvalue-discard")))
  )
}

覆盖

override def requires = plugins.JvmPlugin

应该有效地启用插件,而不必在 build.sbt 中显式调用 enablePlugin

使用

覆盖设置

onLoad 发生在所有项目构建和加载之后。

lazy val settingsAlreadyOverridden = SettingKey[Boolean]("settingsAlreadyOverridden","Has overrideSettings command already run?")
settingsAlreadyOverridden := false
commands += Command.command("removeScalacOptions") { state =>
  if (settingsAlreadyOverridden.value) {
    state
  } else {
    Project.extract(state).appendWithSession(
      Seq(
        settingsAlreadyOverridden := true,
        scalacOptions ~= (_.filterNot(Set("-Wvalue-discard")))
      ),
      state
    )
  }
}

onLoad in Global := (onLoad in Global).value andThen ("removeScalacOptions" :: _)

还要考虑他们如何通过 removeScalacOptions 解决社区建设中的问题。