我正在开发一个包含sbt插件的库。当然,我正在使用sbt构建这个(多项目)库。我的(简化)项目如下:
myProject/ # Top level of library
-> models # One project in the multi-project sbt build.
-> src/main/scala/... # Defines common models for both sbt-plugin and framework
-> sbt-plugin # The sbt plugin build
-> src/main/scala/...
-> framework # The framework. Ideally, the sbt plugin is run as part of
-> src/main/scala/... # compiling this directory.
-> project/ # Multi-project build configuration是否有办法将myProject/sbt中定义的sbt插件连接到myProject/框架的构建中,这些都是在一个统一的构建中完成的?
注:类似(但更简单)的问题:如何与使用它的项目一起开发多项目构建中的sbt插件?
发布于 2016-05-29 19:10:48
是否有办法将myProject/sbt中定义的sbt插件连接到myProject/框架的构建中,这些都是在一个统一的构建中完成的?
我有一个关于Github Eed3si9n/plugin-引导的工作示例。虽然不是超级漂亮,但还是挺管用的。我们可以利用sbt是递归的这个事实。
project目录是构建中的另一个构建,它知道如何构建您的构建。为了区分这些构建,我们有时使用术语固有的build来指您的构建,而meta指的是project中的构建。元数据库中的项目可以完成任何其他项目所能做的事情。构建定义是一个sbt项目。
通过扩展,我们可以将sbt插件看作是元数据库的根项目的库或项目间的依赖项。
元构建定义(project/plugins.sbt)
在本例中,可以将元数据看作是一个平行的宇宙或影子世界,它具有并行的多构建结构作为适当的构建(root、model、sbt-plugin)。
为了在适当的构建中重用来自model和sbt-plugin子项目的源代码,我们可以在元数据中重新创建多项目构建。这样我们就不需要进入循环依赖关系了。
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")
}当sbt加载时,它将首先构建metaModel和metaSbtSomething,并使用metaSbtSomething作为适当构建的插件。
如果您需要任何其他插件,您只需将其添加到project/plugins.sbt中,就像我添加了sbt-doge一样。
适当构建(build.sbt)
适当的构建看起来像一个正常的多项目构建。如您所见,framework子项目使用SomethingPlugin。重要的是他们共享源代码,但是target目录是完全分开的,所以一旦加载了正确的构建,并且您正在更改代码,就不会有任何干扰。
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)
)演示
在SomethingPlugin示例中,我定义了使用foo.Model.x的something任务。
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}") }
)
}下面是如何从构建中调用something任务:
Something Root> framework/something
something! 1
[success] Total time: 0 s, completed May 29, 2016 3:01:07 PM1来自foo.Model.x,因此这说明我们在framework子项目中使用sbt插件,而插件使用的是metaModel。
https://stackoverflow.com/questions/37424513
复制相似问题