How can a default task be overridden from an AutoPlugin?

浪尽此生 提交于 2019-12-10 17:56:44

问题


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

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