如何从AutoPlugin覆盖默认任务?

时间:2014-08-11 16:07:55

标签: sbt sbt-plugin

让我们说要覆盖(替换)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或经典插件中实现这一点,如果是这样的话?

2 个答案:

答案 0 :(得分:6)

我找到了问题的解决方案here

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

所以我必须做的就是通过向我的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
    }
  )
}

答案 1 :(得分:0)

只需从the answer完成@user1752169,这里有一个较短的(不一定比较容易理解)解决方案与待忘记的操作符~=

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,并在没有太多工作的情况下激活插件(并在更改时不断更新)。