我正在编写一个自定义 sbt 插件,其任务旨在针对另一个多项目中的特定项目。
请注意,“插件”和“多项目”客户端是两个独立的项目,因此插件会(本地)发布,然后通过多项目的
plugins.sbt
文件中的 addSbtPlugin 使用。
多项目客户的
build.sbt
是:
val scala3Version = "3.3.0-RC3"
organizationName := "Nigel Eke"
organization := "nigeleke"
lazy val root = project
.in(file("."))
.settings(
name := "sbt-example-client",
publish / skip := true
)
.aggregate(core, client)
lazy val core = project
.settings(
name := "core",
scalaVersion := scala3Version
)
lazy val client = project
.enablePlugins(MyPlugin)
.settings(name := "client")
我的自定义插件仅适用于
client
项目。
一个最小的插件示例是:
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 = allRequirements
override lazy val projectSettings = Seq(
myTask := {
println(s"project: ${thisProject.value.id} plugins: ${thisProject.value.plugins}")
}
)
}
当我回到多项目客户端并运行
sbt myTask
我得到以下输出:
project: client plugins: nigeleke.sbt.MyPlugin
project: root plugins: <none>
project: core plugins: <none>
这向我表明插件代码正在为所有项目调用,无论它是否已启用。我的期望是它只会被那些启用它的人调用。
对于为什么这种期望看起来不正确,我将不胜感激。
其次:自定义插件通过引用
thisProject.value.plugins
属性可以看到是启用的。我能看到“测试”的唯一方法是将thisProject.value.plugins
转换为字符串并查看它是否包含"nigeleke.sbt.MyPlugin"
。不过,我想以一种更类型安全的方式来做到这一点,但这似乎是不可能的。
我将触发器覆盖修改为
noTrigger
和 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}")
}
)
}