Is there a way to connect the sbt plugin in myProject / sbt-plugin to the assembly for myProject / framework in a single assembly?
I have a working Github example eed3si9n / plugin-bootstrap . It's not super pretty, but it's kind of like work. We can take advantage of the fact that sbt is recursive .
The project directory is another assembly inside your assembly that knows how to build your assembly. To distinguish between assemblies, we sometimes use the term correct layout to refer to your assembly and the meta assembly to refer to the project assembly. Projects inside the metabite can do everything that any other project can do. The build definition is an sbt project.
In addition, we may think that sbt plugins are library or interproject dependent for the root project of your metabactor.
meta assembly definition ( project/plugins.sbt )
In this example, we will consider the label as a parallel world or a shadow world that has a parallel structure of a multi-line structure as the correct assembly ( root , model , sbt-plugin ).
To reuse the source code from the model and sbt-plugin subprojects in the correct assembly, we can recreate the multi-project assembly in the metabite. Thus, we do not need to enter into circular dependence.
addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.5") lazy val metaroot = (project in file(".")). dependsOn(metaSbtSomething) lazy val metaModel = (project in file("model")). settings( sbtPlugin := true, scalaVersion := "2.10.6", unmanagedSourceDirectories in Compile := mirrorScalaSource((baseDirectory in ThisBuild).value.getParentFile / "model") ) lazy val metaSbtSomething = (project in file("sbt-plugin")). dependsOn(metaModel). settings( sbtPlugin := true, scalaVersion := "2.10.6", unmanagedSourceDirectories in Compile := mirrorScalaSource((baseDirectory in ThisBuild).value.getParentFile / "sbt-plugin") ) def mirrorScalaSource(baseDirectory: File): Seq[File] = { val scalaSourceDir = baseDirectory / "src" / "main" / "scala" if (scalaSourceDir.exists) scalaSourceDir :: Nil else sys.error(s"Missing source directory: $scalaSourceDir") }
When sbt loads, it will first build metaModel and metaSbtSomething and use metaSbtSomething as a plugin for your proper build.
If you have any other plugins you need, you can simply add it to project/plugins.sbt normally, as I added sbt-doge .
proper assembly (build.sbt)
The correct assembly looks like a normal multi-project assembly. As you can see, the subproject framework uses SomethingPlugin . The important thing is that they share the source code, but the target directory is completely divided, so there is no interference after loading the correct assembly, and you change the code.
import Dependencies._ lazy val root = (project in file(".")). aggregate(model, framework, sbtSomething). settings(inThisBuild(List( scalaVersion := scala210, organization := "com.example" )), name := "Something Root" ) // Defines common models for both sbt-plugin and framework lazy val model = (project in file("model")). settings( name := "Something Model", crossScalaVersions := Seq(scala211, scala210) ) // The framework. Ideally, the sbt plugin is run as part of building this. lazy val framework = (project in file("framework")). enablePlugins(SomethingPlugin). dependsOn(model). settings( name := "Something Framework", crossScalaVersions := Seq(scala211, scala210), // using sbt-something somethingX := "a" ) lazy val sbtSomething = (project in file("sbt-plugin")). dependsOn(model). settings( sbtPlugin := true, name := "sbt-something", crossScalaVersions := Seq(scala210) )
demo
In the SomethingPlugin example, I define a something task that uses foo.Model.x .
package foo import sbt._ object SomethingPlugin extends AutoPlugin { def requries = sbt.plugins.JvmPlugin object autoImport { lazy val something = taskKey[Unit]("") lazy val somethingX = settingKey[String]("") } import autoImport._ override def projectSettings = Seq( something := { println(s"something! ${Model.x}") } ) }
Here we can call the something task from the assembly:
Something Root> framework/something something! 1 [success] Total time: 0 s, completed May 29, 2016 3:01:07 PM
1 comes from foo.Model.x , so this demonstrates that we use the sbt-something plugin in the framework subproject and that the plugin uses metaModel .