【问题标题】:How can I create a separate sbt Configuration or Task to compile with WartRemover?如何创建单独的 sbt 配置或任务以使用 WartRemover 进行编译?
【发布时间】:2015-02-18 22:13:42
【问题描述】:

WartRemover 是一个 scalac 插件。通常它是通过sbt plugin 配置的。

我希望能够在我的 sbt 项目上将 WartRemover 作为单独的配置或任务运行,而不会影响 compile 的正常运行。

将 Wartremover 添加到我的plugins.sbt 后,我尝试了以下几种变体。

lazy val Lint = config("lint").extend(Compile)

project("foo").
  configs(Lint)
  settings(inConfig(Lint)(Defaults.compileSettings): _*).
  settings(inConfig(Linting)(wartremover.wartremoverSettings):_*).
  settings(inConfig(Linting)(wartremover.wartremoverErrors := wartremover.Warts.all))

之后scalacOptions 大致包含了我在新的lint 配置和compile 配置中的预期。但是,当我在调试模式下使用 sbt 运行 lint:compilecompile 时,我可以看到 scalac 的命令行参数,两个或两个命令都不会导致传递 -P:wartremover:... 开关。这很令人惊讶,因为只有lint:scalacOptions 显示了-P:wartremover:... 开关。

如何创建单独的 sbt 配置或任务以使用 WartRemover 进行编译而不影响compile:compile

【问题讨论】:

  • 您的意思是自定义命令吗? scala-sbt.org/0.12.2/docs/Extending/…
  • @gangstead,我不反对自定义命令。我只是不太了解如何使用必要的配置使其执行“编译”。

标签: scala sbt scalac


【解决方案1】:

我认为你非常接近。以下是一些细节:

  1. sbt 下载库依赖和编译器插件都使用Compile 配置的update 任务,它使用libraryDependencies 设置。 addCompilerPlugin 是带有CompilerPlugin 配置的libraryDependencies 的简写。
  2. 编译器插件在您感兴趣的配置上需要scalaOptions
  3. 您需要从Compile 中获取sources 才能在Lint 中使用它们。

如果您看到wartremoverSettings 的实现,它会同时执行addCompilerPluginscalacOptions。您有两个选项可以在 Compile 上禁用 wartremover:

  1. 使用自动插件(需要 sbt 0.13.5+)注入 wartremoverSettings,然后从 Compile 手动删除 wartremover 编译器插件。
  2. 禁用自动插件,然后手动将疣去除剂添加到libraryDependencies

这是第一个选项。

project/build.properties

sbt.version=0.13.7

项目/wart.sbt

addSbtPlugin("org.brianmckenna" % "sbt-wartremover" % "0.11")

build.sbt

lazy val Lint = config("lint") extend Compile

lazy val foo = project.
  configs(Lint).
  settings(inConfig(Lint) {
    Defaults.compileSettings ++ wartremover.wartremoverSettings ++
    Seq(
      sources in Lint := {
        val old = (sources in Lint).value
        old ++ (sources in Compile).value 
      },
      wartremover.wartremoverErrors := wartremover.Warts.all
    ) }: _*).
  settings(
    scalacOptions in Compile := (scalacOptions in Compile).value filterNot { _ contains "wartremover" }
  )

foo/src/main/scala/Foo.scala

package foo

object Foo extends App {
  // Won't compile: Inferred type containing Any
  val any = List(1, true, "three")
  println("hi")
}

样本输出

foo> clean
[success] Total time: 0 s, completed Dec 23, 2014 9:43:30 PM
foo> compile
[info] Updating {file:/quick-test/wart/}foo...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /quick-test/wart/foo/target/scala-2.10/classes...
[success] Total time: 1 s, completed Dec 23, 2014 9:43:33 PM
foo> run
[info] Running foo.Foo 
hi
[success] Total time: 0 s, completed Dec 23, 2014 9:43:37 PM
foo> lint:compile
[info] Compiling 1 Scala source to /quick-test/wart/foo/target/scala-2.10/lint-classes...
[error] /quick-test/wart/foo/src/main/scala/Foo.scala:5: Inferred type containing Any
[error]   val any = List(1, true, "three")
[error]       ^
[error] /quick-test/wart/foo/src/main/scala/Foo.scala:5: Inferred type containing Any
[error]   val any = List(1, true, "three")
[error]             ^

【讨论】:

  • 感谢您的帮助!你的建议完全符合我的期望。我似乎不需要从 Compile 中删除 AutoPlugin 添加的配置,我猜这是因为我的构建是在 .scala 文件中指定的。
  • 我错了:正如 Eugene 所说,我需要 scalac 选项上的过滤器来删除 wartremover 开关,以免在编译配置中传递给它。它没有注意到传递的开关有任何影响,因为默认情况下,WartRemover 插件会禁用所有疣。但是,在compile:compile 期间,编译器仍在加载 WartRemover 插件,这不是我想要的。
  • 添加Defaults.compileSettings 有什么作用?它会在我们的构建中引起一些问题;把它拿出来修复它们,似乎没有副作用。 (我们的设置都是在传递到项目的settings 块中的惰性值中定义的,除了nameversionorganization 之外,“顶层”没有任何内容。
猜你喜欢
  • 2015-09-30
  • 2011-12-03
  • 2011-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多