You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义sbt插件中如何让clean命令调用自定义任务myTask?

问题描述

我编写了如下最简自定义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>

我未能找到正确的实现语法,恳请指点。

解决方案

你的问题出在clean任务的定义方式上——clean.dependsOn(myTask).value这种写法并没有正确修改原clean任务的依赖关系,它只是直接计算了原clean任务的执行结果,而非重新绑定任务的执行逻辑。

正确的做法是使用sbt提供的Def.sequential来确保myTask先执行,再运行原clean任务,修改后的代码如下:

package nigeleke.sbt

import sbt.*
import Keys.*

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 := Def.sequential(myTask, clean).value
  )

}

也可以通过两次赋值的方式修改任务依赖,效果相同:

clean := clean.value
clean := clean.dependsOn(myTask).value

修改完成后,执行clean命令时会先运行myTask输出预期内容,再执行标准的clean清理操作。

内容的提问来源于stack exchange,提问作者user1460067

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 09:23:35