如何建立具有继承和共享依赖关系的多项目SBT项目

时间:2018-08-15 23:41:08

标签: sbt

我想创建一个具有继承和共享依赖关系的SBT项目。

有了Maven的POM文件,就有了Project Inheritance的想法,您可以在其中设置parent项目。我想对SBT做同样的事情。

xchange-stream library使用Maven的Project Inheritance(项目继承)来解决从父项目进行编译时的子项目依赖关系。

这是我对文件结构的看法:

sbt-project/
  project/
    dependencies.scala    # Contains dependencies common to all projects
  build.sbt               # Contains definition of parent project with references
                          # to subprojects

  subproject1/
    build.sbt             # Contains `subproject3` as a dependency

  subproject2/
    build.sbt             # Contains `subproject3` as a dependency

  subproject3/
    build.sbt             # Is a dependency for `subproject1` and `subproject2`

project1project2可以在其依赖项列表中包含project3,如下所示:

libraryDependencies ++= "tld.organization" % "project3" % "1.0.0"

subproject1subproject2通过从其子目录中调用sbt compile进行编译时,或者当父级sbt-project从主{{1}进行编译时}目录,然后sbt-project将使用SBT在本地编译和发布,或者以其他方式提供给需要它的项目。

此外,如何在subproject3sbt-project/build.sbt目录中的任何地方指定共享的依赖关系,以使它们在调用{{时在sbt-project/projectsubproject1中可用1}}在这些子目录中?

以下示例不能帮助回答以上几点:

  1. jbruggem/sbt-multiproject-example: 使用递归subproject2文件,但不在子项目之间共享依赖项。

  2. Defining Multi-project Builds with sbtpbassiner/sbt-multi-project-example: 对子目录中的项目使用单个sbt compile文件。

  3. sachabarber/SBT_MultiProject_Demo: 使用单个build.sbt文件。

2 个答案:

答案 0 :(得分:1)

  

subproject1subproject2通过从子目录中调用sbt compile进行编译时……

也许Maven打算与shell环境和cd命令一起使用,但这并不是sbt至少从2019年的sbt 1.x开始工作的方式。

sbt方法是使用sbt作为交互式shell,并在顶层启动它。然后,您可以以subproject1/compile的形式调用编译,也可以使用project subproject1切换到其中,然后在其中调用compile

房屋插件

通过创建自定义插件,可以实现与父POM类似的功能。

package com.example

import sbt._
import Keys._

object FooProjectPlugin extends AutoPlugin {
  override def requires = plugins.JvmPlugin

  val commonsIo = "commons-io" % "commons-io" % "2.6"

  override def buildSettings: Seq[Def.Setting[_]] = Seq(
    organization := "com.example"
  )
  override def projectSettings: Seq[Def.Setting[_]] = Seq(
    libraryDependencies += commonsIo
  )
}

sbt-sriracha

这并不是您所要的,但我有一个实验性插件,可让您在源依赖和二进制依赖之间进行切换。参见hot source dependencies using sbt-sriracha

您可以为project1project2project3创建三个单独的sbt构建,它们都位于$HOME/workspace目录中。

ThisBuild / scalaVersion     := "2.12.8"
ThisBuild / version          := "0.1.1-SNAPSHOT"

lazy val project3Ref = ProjectRef(workspaceDirectory / "project3", "project3")
lazy val project3Lib = "tld.organization" %% "project3" % "0.1.0"

lazy val project1 = (project in file("."))
  .enablePlugins(FooProjectPlugin)
  .sourceDependency(project3Ref, project3Lib)
  .settings(
    name := "project1"
  )

使用此设置,您可以启动sbt -Dsbt.sourcemode=true,它将把project3作为子项目。

答案 1 :(得分:0)

您可以使用Mecha超级仓库概念。在此处查看设置和文档:https://github.com/storm-enroute/mecha

基本思想是,您可以在单个超级超级仓库sbt项目下合并相关的sbt项目(及其自己的build.sbt):

/root
  /project/plugins.sbt
  repos.conf

  /project1
    /src/..
    /project/plugins.sbt
    build.sbt

  /project2
    /src/..
    /project/plugins.sbt
    build.sbt

请注意,根文件夹中没有build.sbt! 而是有repos.conf文件。它包含子仓库的定义,如下所示:

  root {
    dir = "."
    origin = ""
    mirrors = []
  }

  project1 {
    dir = "project1"
    origin = "git@github.com:some_user/project1.git"
    mirrors = []
  }

  project2 {
    dir = "project2"
    origin = "git@github.com:some_user/project2.git"
    mirrors = []
  }

然后,您可以在单个项目中指定项目间,源级别的依赖项

有两种方法:

  • dependencies.conf文件
  • 或在构建源代码中

有关更多详细信息,请参见docs