Different scalac options for different scopes or tasks?

十年热恋 提交于 2020-01-02 23:13:10

问题


I am trying to use a compiler plugin with sbt (I'm on 0.13.5), passed along in my build.sbt as:

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

This works, the plugin runs, however I would really like to only run the plugin on some explicit compiles (perhaps with a scoped compile task or a custom task).

If I try something like:

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

The plugin does not run on "plugin-config:compile". In fact if I have

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

The plugin still runs on "test:compile" or compile on any other scope. I would guess I am probably not understanding something correctly with the configs/scopes.

I also tried:

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

commands += pluginCommand

But the plugin doesn't actually run on that command, so again I am probably not understanding something there.

Any and all help welcome.


回答1:


So I have come to hacky solution; I thought I would share it here in case anyone else stumbles upon this question.

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\")")

As a quick guide, this code:

  • Defines a custom task "safeCompile" that runs the "Compile:compile" task, but succeeds even on errors (this is needed so that the sequence of commands defined later on doesn't break on compilation failure).
  • Declares "scalacOptions" to be dependent on a function that checks if the plugin is turned on (leaving the options untouched if it is) and otherwise sets the options to the default I want for the project (Seq("-deprecation", "-unchecked")). This is a hack so that these settings are on by default and so that a bare "scalacOptions :=" definition doesn't override the settings done in the aliased command sequence. (Using Seq.append and Seq.distinct might be a nicer way to do this hacky part).
  • Defines an aliased command sequence that: turns the plugin on, safeCompiles, turns the plugin off.

Comments are welcome, and if you get something cleaner to work, please share!



来源:https://stackoverflow.com/questions/25416836/different-scalac-options-for-different-scopes-or-tasks

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!