加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – sbt插件与使用插件本身的多项目构建中的项目之间的相互

发布时间:2020-12-16 09:58:37 所属栏目:安全 来源:网络整理
导读:我正在开发一个包含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-pl
我正在开发一个包含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-plugin中定义的sbt-plugin在统一版本中挂钩到myProject / framework的构建中?

注意:类似(但更简单)的问题:How to develop sbt plugin in multi-project build with projects that use it?

解决方法

Is there a way to have the sbt-plugin defined in myProject/sbt-plugin be hooked into the build for myProject/framework all in a unified build?

我在Github eed3si9n/plugin-bootstrap上有一个工作示例.它不是很漂亮,但它有点有效.我们可以利用sbt is recursive的事实.

The project directory is another build inside your build,which knows how to build your build. To distinguish the builds,we sometimes use the term proper build to refer to your build,and meta-build to refer to the build in project. The projects inside the metabuild can do anything any other project can do. Your build definition is an sbt project.

通过扩展,我们可以将sbt插件视为元库的根项目的库或项目间依赖项.

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

在此示例中,将metabuild视为具有并行多构建结构的并行Universe或阴影世界,作为正确的构建(root,model,sbt-plugin).

要在正确的构建中重用模型和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,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)

正确的构建看起来像一个普通的多项目构建.
正如您所见,框架子项目使用SomethingPlugin.重要的是它们共享源代码,但目标目录是完全分开的,因此一旦加载了正确的构建,就不会产生干扰,并且您正在更改代码.

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",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的任务.

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 Root> framework/something
something! 1
[success] Total time: 0 s,completed May 29,2016 3:01:07 PM

1来自foo.Model.x,所以这表明我们在框架子项目中使用了sbt-something插件,并且该插件使用了metaModel.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读