问题
Let's say that I wan to override (replace) the default setting for the packageBin
task. So I naively wrote an AutoPlugin like this:
object TestPlugin extends AutoPlugin {
override def trigger = allRequirements
override val projectSettings: Seq[Def.Setting[_]] = Seq(
packageBin in Compile <<= (packageBin in Compile).map { a =>
println("project/compile::packageBin")
a
}
)
}
But this does not work (at least not with SBT 0.13.5 and 0.13.6-M1), my version of packageBin
gets never called. If I put the the following line in my project's build.sbt
file, then it works.
packageBin in Compile <<= (packageBin in Compile).map { a => println("project/compile::packageBin"); a }
Is it possible at all to achieve this from an AutoPlugin or a classical plugin, and if so how?
回答1:
I found the solution to the problem here.
In order to make sure that the settings of the AutoPlugin are not overwritten by the default settings, the settings from the AutoPlugin must be applied after the default settings. The default settings are set by the AutoPlugins in package sbt.plugins (CorePlugin, IvyPlugin, JvmPlugin).
So all I had to do, is to make my AutoPlugin dependent on the JvmPlugin by adding the following override to my AutoPlugin:
override def requires: Plugins = JvmPlugin
The complete autoplugin with the overriden packageBin
is as follows:
import sbt._
import Keys._
import plugins.JvmPlugin
object TestPlugin extends AutoPlugin {
override def requires = JvmPlugin
override def trigger = allRequirements
override val projectSettings: Seq[Def.Setting[_]] = Seq(
packageBin in Compile <<= (packageBin in Compile).map { a =>
println("project/compile::packageBin")
a
}
)
}
回答2:
Just to complete the answer from @user1752169, here's a shorter (not necessarily simpler to comprehend) solution with the to-be-forgotten operator ~=
:
import sbt._
import Keys._
import plugins.JvmPlugin
object TestPlugin extends AutoPlugin {
override def requires = JvmPlugin
override def trigger = allRequirements
override val projectSettings: Seq[Def.Setting[_]] = Seq(
packageBin in Compile ~= { a =>
println("project/compile::packageBin")
a
}
)
}
Or to have a side-effecting post-processing with andFinally
:
import sbt._
import Keys._
import plugins.JvmPlugin
object TestPlugin extends AutoPlugin {
override def requires = JvmPlugin
override def trigger = allRequirements
override val projectSettings: Seq[Def.Setting[_]] = Seq(
packageBin in Compile <<= (packageBin in Compile) andFinally {
println("project/compile::packageBin")
}
)
}
As a nice addition, one may save the autoplugin code to project/src/main/scala
in any project and gets the plugin activated without much work (and constantly updated when changed).
来源:https://stackoverflow.com/questions/25247662/how-can-a-default-task-be-overridden-from-an-autoplugin