Reputation: 108
I'm looking for a way to create a custom command in sbt for multi-project structure in a such way:
I have this in my build.sbt
lazy val root = (project in file("."))
.settings(
name := "Custom command",
commands += Command.command("customCommand") { state =>
state
}
)
.aggregate(a, b)
lazy val a = project
.settings(
commands += Command.command("customCommand") { state =>
println("Hello")
state
}
)
lazy val b = project
.settings(
commands += Command.command("customCommand") { state =>
println("Hey there")
state
}
)
Unfortunately, I get nothing in the sbt shell:
sbt:Custom command> customCommand
sbt:Custom command>
The expected output is:
sbt:Custom command> customCommand
Hello
Hey there
sbt:Custom command>
The order doesn't matter.
So it looks like my command is executed for the root
project only. Is there any way to tell sbt to execute customCommand
for subproject first?
Upvotes: 1
Views: 430
Reputation: 6460
Most of the time you don't really need a command and can do everything you want with a task. You can define a task key, override it in your subprojects and the aggregating project will do what you expect (aggregate):
lazy val customTask = taskKey[Unit]("My custom task")
lazy val root = (project in file("."))
.aggregate(a, b)
lazy val a = project
.settings(
customTask := { println("Hello") }
)
lazy val b = project
.settings(
customTask := { println("Hey there") }
)
Here's how it works:
> a/customTask
Hello
[success] Total time: 0 s, completed Apr 5, 2018 9:31:43 PM
> b/customTask
Hey there
[success] Total time: 0 s, completed Apr 5, 2018 9:31:47 PM
> customTask
Hey there
Hello
[success] Total time: 0 s, completed Apr 5, 2018 9:31:50 PM
Check sbt documentation on Commands, you need it only if you need to manipulate the build state explicitly (which is hard to do carefully), call other existing commands or modify settings (which you normally shouldn't):
Typically, you would resort to a command when you need to do something that’s impossible in a regular task.
If you still need a command, I think you cannot override it in subprojects and aggregate like a task, but you can probably define it once and inside it dispatch on the project it is called from. I really doubt you want it.
Upvotes: 1