问题
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