4

假设我要覆盖(替换)packageBin任务的默认设置。所以我天真地写了一个这样的 AutoPlugin:

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
    }  
  )

}

但这不起作用(至少不适用于 SBT 0.13.5 和 0.13.6-M1),我的版本packageBin永远不会被调用。如果我将以下行放在我的项目build.sbt文件中,那么它可以工作。

packageBin in Compile <<= (packageBin in Compile).map { a => println("project/compile::packageBin"); a }

是否有可能通过 AutoPlugin 或经典插件实现这一点,如果可以,如何实现?

4

2 回答 2

6

我在这里找到了问题的解决方案。

为了确保 AutoPlugin 的设置不会被默认设置覆盖,必须在默认设置之后应用 AutoPlugin 的设置。默认设置由包sbt.plugins(CorePlugin、IvyPlugin、JvmPlugin)中的 AutoPlugins 设置。

所以我所要做的就是通过向我的 AutoPlugin 添加以下覆盖来使我的 AutoPlugin 依赖于 JvmPlugin:

override def requires: Plugins = JvmPlugin

具有覆盖的完整自动插件packageBin如下:

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
    }
  )
}
于 2014-08-11T19:48:30.373 回答
0

只是为了完成来自@user1752169的答案,这里有一个更短(不一定更容易理解)的解决方案,带有 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
    }
  )
}

或者进行副作用后处理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")
    }
  )
}

作为一个很好的补充,可以将自动插件代码保存到project/src/main/scala任何项目中,并且无需太多工作即可激活插件(并在更改时不断更新)。

于 2014-08-11T22:04:13.793 回答