如何在我的自定义 sbt 插件中使用 clean 和 compile 等 sbt 命令

问题描述 投票:0回答:1

我有以下最小的自定义sbt插件,我想在其中实现(覆盖)标准

clean
命令以执行与
myTask
相同的操作。

package nigeleke.sbt

import sbt.*
import Keys.*

import scala.sys.process.*

object MyPlugin extends AutoPlugin {

  object autoImport {
    val myTask = taskKey[Unit]("Do something.")
  }

  import autoImport._

  override def requires = empty

  override def trigger = noTrigger

  override lazy val projectSettings = Seq(
    myTask := {
      println(s"project: ${thisProject.value.id}  plugins: ${thisProject.value.plugins}")
    },
    clean  := clean.dependsOn(myTask).value
  )

}

当我在客户端项目中启用此插件时,

myTask
命令按预期工作。我也想
clean
调用相同的任务,但没有输出即将到来:

> sbt
[info] welcome to sbt 1.8.2 (Eclipse Adoptium Java 17.0.6)
[info] loading global plugins from ... \.sbt\1.0\plugins
[info] loading settings for project sbt-example-client-build from plugins.sbt ...
[info] loading project definition from ... \sbt-example-client\project
[info] loading settings for project root from build.sbt,version.sbt ...
[info] set current project to sbt-example-client (in build file:/ ... /sbt-example-client/)
[info] sbt server started at local:sbt-server-c377c6b81cca5b432adb
[info] started sbt server
sbt:sbt-example-client> myTask
project: client  plugins: nigeleke.sbt.MyPlugin
[success] Total time: 0 s, completed 13 Apr 2023, 5:05:18 pm
sbt:sbt-example-client> clean
[success] Total time: 0 s, completed 13 Apr 2023, 5:05:21 pm
sbt:sbt-example-client>

我找不到调用它的正确语法,因此不胜感激。

scala sbt sbt-plugin
1个回答
0
投票

问题是

clean
是在默认的内置 sbt 插件中定义的
JvmPlugin

https://github.com/sbt/sbt/blob/v1.8.2/main/src/main/scala/sbt/plugins/JvmPlugin.scala#L44-L46

object JvmPlugin extends AutoPlugin {
  ...
  override lazy val projectSettings: Seq[Setting[_]] =
      ... ++
      Defaults.baseTasks ++    // (1)
      Defaults.compileBase ++  // (2)
      Defaults.defaultConfigs  // (3)
}

https://github.com/sbt/sbt/blob/v1.8.2/main/src/main/scala/sbt/Defaults.scala

object Defaults extends BuildCommon { 

  lazy val baseTasks: Seq[Setting[_]] = projectTasks ++ ...

  lazy val projectTasks: Seq[Setting[_]] = Seq(
    ...
    clean :=                                 // (1)
      Def.taskDyn(Clean.task(resolvedScoped.value.scope, full = true)).value,
    ...
  )

  def compileBase = ... ++ Seq(
    ...
    clean := clean.dependsOn(cleanIvy).value, // (2)
    ...
  )

  lazy val defaultConfigs: Seq[Setting[_]] =
    inConfig(Compile)(compileSettings) ++ 
    inConfig(Test)(testSettings) ++ ...

  lazy val compileSettings: Seq[Setting[_]] = configSettings + ...

  lazy val testSettings: Seq[Setting[_]] = configSettings ++ ...

  lazy val configSettings: Seq[Setting[_]] = ... ++ configTasks ++ ...

  lazy val configTasks: Seq[Setting[_]] = ... ++ Seq(
    ...
    clean := (compileOutputs / clean).value,  // (3)
    ...
  )
}

你不能禁用

JvmPlugin
因为在这种情况下 sbt 无法构建项目。

所以为了覆盖

clean
你应该让你的插件依赖于
JvmPlugin
(否则
JvmPlugin
定义
clean
覆盖你的)

object MyPlugin extends AutoPlugin {
  ...

  override def requires = JvmPlugin

然后以下任何选项都有效:

clean := clean.dependsOn(myTask).value
clean := {
  myTask.value
  clean.value
}
clean := Def.sequential(myTask, clean).value

如何从自动插件覆盖默认任务?

https://www.scala-sbt.org/1.x/docs/Custom-Settings.html#Implementing+a+task

SBT 任务取决于

SBT 取决于使用情况——从 0.12 迁移到 0.13

SBT 中的每个项目任务

多个项目的Sbt运行命令

SBT 中的排序和覆盖任务

如何在自定义清理任务中排除文件?

如何从任务中执行依赖项目中的清理任务?

© www.soinside.com 2019 - 2024. All rights reserved.