【问题标题】:Different scalac options for different scopes or tasks?不同范围或任务的不同scalac选项?
【发布时间】:2014-08-26 07:20:13
【问题描述】:

我正在尝试使用带有 sbt 的编译器插件(我在 0.13.5),在我的 build.sbt 中传递为:

autoCompilerPlugins := true
scalacOptions += "-Xplugin:myCompilerPluginJar.jar"

这可行,插件运行,但是我真的想只在一些显式编译时运行插件(可能使用范围编译任务或自定义任务)。

如果我尝试类似:

val PluginConfig = config("plugin-config") extend(Compile)
autoCompilerPlugins := true
scalacOptions in PluginConfig += "-Xplugin:myCompilerPluginJar.jar"

插件不在“plugin-config:compile”上运行。事实上,如果我有

scalacOptions in Compile += "-Xplugin:myCompilerPluginJar.jar"

插件仍然在“test:compile”上运行或在任何其他范围内编译。我想我可能对配置/范围没有正确理解。

我也试过了:

lazy val pluginCommand = Command.command("plugincompile") { state =>
  runTask(compile in Compile,
    append(Seq(scalacOptions in Compile += "Xplugin:myCompilerPluginJar.jar"), state)
  )
  state
}

commands += pluginCommand

但是插件实际上并没有在那个命令上运行,所以我可能还是不明白那里的东西。

欢迎任何和所有帮助。

【问题讨论】:

    标签: sbt


    【解决方案1】:

    所以我来到了 hacky 解决方案;我想我会在这里分享它,以防其他人偶然发现这个问题。

    val safeCompile = TaskKey[Unit]("safeCompile", "Compiles, catching errors.")
    
    safeCompile := (compile in Compile).result.value.toEither.fold(
      l => {
        println("Compilation failed.")
      }, r => {
        println("Compilation success. " + r)})
    
    //Hack to allow "-deprecation" and "-unchecked" in scalacOptions by default
    scalacOptions <<= scalacOptions map { current: Seq[String] =>
      val default = "-deprecation" :: "-unchecked" :: Nil
      if (current.contains("-Xplugin:myCompilerPluginJar.jar")) current else default
    }
    
    addCommandAlias("depcheck", "; set scalacOptions := Seq(\"-deprecation\", \"-unchecked\", \"-Xplugin:myCompilerPluginJar.jar\"); safeCompile; set scalacOptions := Seq(\"-deprecation\", \"-unchecked\")")
    

    作为快速指南,此代码:

    • 定义了一个自定义任务“safeCompile”,该任务运行“Compile:compile”任务,但即使出现错误也会成功(这是必需的,以便稍后定义的命令序列不会在编译失败时中断)。
    • 声明“scalacOptions”依赖于检查插件是否打开的函数(如果打开则保持选项不变),否则将选项设置为我想要的项目默认值(Seq("-deprecation" , “-未选中”))。这是一个 hack,因此这些设置在默认情况下处于启用状态,并且裸露的“scalacOptions :=" 定义不会覆盖在别名命令序列中完成的设置。 (使用 Seq.append 和 Seq.distinct 可能是完成这个 hacky 部分的更好方法)。
    • 定义一个别名命令序列:打开插件,safeCompiles,关闭插件。

    欢迎评论,如果你有更清洁的工作,请分享!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-28
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      • 2018-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多