自定义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
相关产品推荐
相关产品推荐

