控制 SBT 多项目上的依赖加载歧义

Control dependency loading ambiguity on SBT multi-project

我有一个具有以下结构的 SBT Scala 多项目:

multiprojectRoot        
    project/SharedProjectBuildCode.scala
    project1
        src/sourceFiles
        project1-build.sbt
    project2
        src/sourceFiles
        project2-build.sbt
    projectN
        src/sourceFiles
        projectN-build.sbt

project1 的第一个依赖项是在 SharedProjectBuildCode.scala 文件中使用 dependsOn 声明的,第二个是在独立的 project2-build.sbt 构建定义文件中创建的。

因此,project2 定义包含:

我们希望保留此项目结构,因为它最适合我们当前的工作流程:

我们需要以某种方式控制这种依赖性歧义。你能帮助我吗?

我想你应该在 SharedProjectBuildCode.scala

lazy val root = Project(id = "Main-Project",
    base = file(".")) aggregate(project1, project2,..)

lazy val project2 = Project(id = "project2",
    base = file("project1")).dependsOn(project1)

...

并且不再需要在 build.sbt 中添加为依赖项。

通过使用 SBT 提供的构建文件加载规则,我能够控制在每个用例上加载哪个依赖集。

当您从给定的根目录加载 SBT 时,它会在根目录中查找 *.sbt 文件,还会在 root/project 目录中查找 *.scala。如果你有一个多项目构建,那么它也会读取在子项目上遇到的 .sbt 文件的定义,但它不会在子项目上使用 project/.scala 文件:

.sbt build definition

Multi-project builds

所以,我按照以下方式更改了我的多项目构建:

multiprojectRoot        
    project/SharedProjectBuildCode.scala
    project1
        src/sourceFiles
        project/DeploymentOnlyCode.scala
        project1-build.sbt
    project2
        src/sourceFiles
        project/DeploymentOnlyCode.scala
        project2-build.sbt
    projectN
        src/sourceFiles
        project/DeploymentOnlyCode.scala
        projectN-build.sbt

这种方式,取决于用例我 运行 来自多项目根目录或项目内部目录的 SBT:

  • 开发:SBT 是 运行 来自 multiprojectRoot 目录。它利用了多项目构建的优势(例如使用 dependsOn 和避免 publishLocal)。
  • 生产:SBT 运行 来自具体的项目目录,例如 multiprojectRoot/project2。它允许将项目构建为独立的,将所有依赖项作为显式外部依赖项(对于在生产、持续集成服务器上声明一系列依赖项很有用)。

现在,一个项目有 3 个代码实例,它们聚合了最终构建的属性:

  1. multiprojectRoot/project/SharedProjectBuildCode.scala: 包含本地依赖和其他与多项目构建相关的代码。
  2. multiprojectRoot/project1/project1-build.sbt:包含项目构建属性,多项目和项目的独立构建通用,例如始终是外部的名称或依赖项。对于同级别的其他多项目项目也应该这样做,被明确地视为外部依赖工件。
  3. multiprojectRoot/project1/project/DeploymentOnlyCode.scala:包含仅在独立构建时才会考虑的构建属性。如果这些需要定义特定于部署的属性,则可以对其他子项目执行相同的操作。

这还可以最大程度地控制项目的构建方式、是否是可发布的工件,并将仅与给定项目相关的源代码作为一个完整且独立的部分来处理。