首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sbt插件与使用插件本身的多项目构建中的项目之间的相互依赖关系

sbt插件与使用插件本身的多项目构建中的项目之间的相互依赖关系
EN

Stack Overflow用户
提问于 2016-05-24 21:50:21
回答 1查看 810关注 0票数 5

我正在开发一个包含sbt插件的库。当然,我正在使用sbt构建这个(多项目)库。我的(简化)项目如下:

代码语言:javascript
复制
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插件?

EN

回答 1

Stack Overflow用户

发布于 2016-05-29 19:10:48

是否有办法将myProject/sbt中定义的sbt插件连接到myProject/框架的构建中,这些都是在一个统一的构建中完成的?

我有一个关于Github Eed3si9n/plugin-引导的工作示例。虽然不是超级漂亮,但还是挺管用的。我们可以利用sbt是递归的这个事实。

project目录是构建中的另一个构建,它知道如何构建您的构建。为了区分这些构建,我们有时使用术语固有的build来指您的构建,而meta指的是project中的构建。元数据库中的项目可以完成任何其他项目所能做的事情。构建定义是一个sbt项目。

通过扩展,我们可以将sbt插件看作是元数据库的根项目的库或项目间的依赖项。

元构建定义(project/plugins.sbt)

在本例中,可以将元数据看作是一个平行的宇宙或影子世界,它具有并行的多构建结构作为适当的构建(rootmodelsbt-plugin)。

为了在适当的构建中重用来自modelsbt-plugin子项目的源代码,我们可以在元数据中重新创建多项目构建。这样我们就不需要进入循环依赖关系了。

代码语言:javascript
复制
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加载时,它将首先构建metaModelmetaSbtSomething,并使用metaSbtSomething作为适当构建的插件。

如果您需要任何其他插件,您只需将其添加到project/plugins.sbt中,就像我添加了sbt-doge一样。

适当构建(build.sbt)

适当的构建看起来像一个正常的多项目构建。如您所见,framework子项目使用SomethingPlugin。重要的是他们共享源代码,但是target目录是完全分开的,所以一旦加载了正确的构建,并且您正在更改代码,就不会有任何干扰。

代码语言:javascript
复制
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.xsomething任务。

代码语言:javascript
复制
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任务:

代码语言:javascript
复制
Something Root> framework/something
something! 1
[success] Total time: 0 s, completed May 29, 2016 3:01:07 PM

1来自foo.Model.x,因此这说明我们在framework子项目中使用sbt插件,而插件使用的是metaModel

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37424513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档