Reputation: 2315
Why does sbt not able to find a command in a multiproject build?
My plugin resembles
object MyPlugin extends Plugin {
lazy val plug = Seq( commands ++= Seq(versionWriteSnapshotRelease) )
def versionWriteSnapshotRelease = Command.command(
"versionWriteSnapshotRelease",
"Writes the release format of the snapshot version. This is used to preserve the actual snapshot version in a release commit.",
""
) { state => .... }
}
I have my project/Build.scala
file as follows:
lazy val app = Project(id = "app-subproject", base = file("app"))
.settings(MyPlug.plug :_*)
.settings(...)
lazy val common = Project(id = "library-subproject", base = file("common"))
.settings(MyPlug.plug :_*)
.settings(...)
With files laid out like
root
|_ common
|_ src
|_ app
|_ src
This configurations fails with the error:
[error] Not a valid command: versionWriteSnapshotRelease
[error] Not a valid project ID: versionWriteSnapshotRelease
[error] Expected ':' (if selecting a configuration)
[error] Not a valid key: versionWriteSnapshotRelease (similar: version, ...)
[error] versionWriteSnapshotRelease
However if I restructure to something like
lazy val app = Project(id = "app-subproject", base = file("."))
.settings(MyPlug.plug :_*)
.settings(...)
lazy val common = Project(id = "library-subproject", base = file("common"))
.settings(MyPlug.plug :_*)
.settings(...)
With files laid out like
root
|_ common
|_ src
|_ src
Then it works. Note that my change is to put the app
project /src
in the basedir
and set the app
project to have base "."
.
This plugin is used across multiple projects and has no issue when the file layout is in the second form. So I know it isn't an issue with the plugin per-se.
Upvotes: 1
Views: 851
Reputation: 74669
The reason for the error is that you define two submodules common
and app
with the third default root project without the command set.
You should add yet another definition of a project for the default root project so the command is also defined for it as follows:
lazy val root = Project(id = "root", base = file("."))
.settings(MyPlug.plug :_*)
.settings(...)
You've confirmed that thinking with your test when you turned app
into the default root project.
As an additional check before you add the third module definition, do projects
and see what projects are defined. For every project in the list, execute [projectName]/versionWriteSnapshotRelease
. I'm sure it's going to be fine for app
and common
, but not for the default root module.
Upvotes: 1