Reputation: 531
I am writing a custom sbt plugin, whose tasks are intended to target specific projects from another multi-project.
Note that the 'plugin' and 'multi-project' client are two separate projects, so the plugin gets published (locally) and then used via an addSbtPlugin in the multi-project's plugins.sbt
file.
The build.sbt
for the multi-project client is:
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")
where my custom plugin is only intended for the client
project.
A minimal plugin example is:
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}")
}
)
}
When I go back to the multi-project client and run sbt myTask
I get the following output:
project: client plugins: nigeleke.sbt.MyPlugin
project: root plugins: <none>
project: core plugins: <none>
This indicates to me that the plugin code is being called for all projects, regardless whether it has been enabled or not. My expectation was that it would only be called for those in which it is enabled.
I would appreciate some help regarding why this expectation appears incorrect.
Secondly: the custom plugin can see that it is enabled by referencing the thisProject.value.plugins
attribute. The only way I can see to "test" this is to convert thisProject.value.plugins
to a string and see if it contains "nigeleke.sbt.MyPlugin"
. I'd like to do this in a more typesafe manner though, but that doesn't appear to be possible.
Upvotes: 2
Views: 137
Reputation: 531
I amended the trigger override to noTrigger
and myTask
worked as expected.
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}")
}
)
}
The trigger
method takes a parameter of type PluginTrigger
, which is a sealed trait that defines the possible values that can be used to trigger the plugin. Values are
allRequirements
:
This is the default value and indicates that the plugin should be triggered for all projects in the build. This means that the plugin will be automatically enabled for all projects, regardless of whether they explicitly enable it or not.
noTrigger
:
This value indicates that the plugin should not be triggered automatically for any projects. Instead, projects must explicitly enable the plugin using enablePlugins.
some
:
This value allows you to specify a list of other plugins that must be enabled for the plugin to be triggered. For example, if you set trigger to some(Seq(pluginA, pluginB)), then your plugin will only be triggered if both pluginA and pluginB are also enabled for the project.
[This response was elicited with the help of ChatGPT]
Upvotes: 3