简体   繁体   English

控制依赖性加载SBT多项目的模糊性

[英]Control dependency loading ambiguity on SBT multi-project

I have an SBT Scala multi-project with the following structure: 我有一个SBT Scala多项目,具有以下结构:

multiprojectRoot        
    project/SharedProjectBuildCode.scala
    project1
        src/sourceFiles
        project1-build.sbt
    project2
        src/sourceFiles
        project2-build.sbt
    projectN
        src/sourceFiles
        projectN-build.sbt
  • multiprojectRoot/project/SharedProjectBuildCode.scala: contains multi-project definitions that use dependsOn to create dependencies on local projects. multiprojectRoot / project / SharedProjectBuildCode.scala:包含使用dependsOn创建对本地项目的依赖项的多项目定义。 For example: 例如:

     lazy val project2 = Project( ... ).dependsOn(project1) 
  • multiprojectRoot/project2/project2-build.sbt: Contains the settings and dependencies for a given project. multiprojectRoot / project2 / project2-build.sbt:包含给定项目的设置和依赖项。 For example: 例如:

     name := "project2" libraryDependencies ++= Seq( ... "my.company" % "project1" % "1.0" ) 

First dependency to project1 is declared with dependsOn on SharedProjectBuildCode.scala file and the second is created on standalone project2-build.sbt build definition file. 第一次依赖于project1是在SharedProjectBuildCode.scala文件中使用dependsOn声明的,第二次是在独立的project2-build.sbt构建定义文件中创建的。

So, project2 definition contains either: 因此,project2定义包含:

  • an ambiguous dependency to project1 or 对project1或。的模糊依赖
  • a double dependency to project1 对project1的双重依赖

We want to keep this project structure, because is the best for our current workflow: 我们希望保留这个项目结构,因为它对我们当前的工作流程是最好的:

  • Independent .sbt files serve standalone deployment purposes for each project on our continuous delivery server. 独立的.sbt文件为我们的持续交付服务器上的每个项目提供独立的部署目的。
  • Multi-project .scala file with dependsOn is used to facilitate development, allowing us to avoid things such as continuous publishLocal. 带有dependsOn的多项目.scala文件用于促进开发,允许我们避免诸如连续publishLocal之类的事情。

We need to have control for such dependency ambiguities someway. 我们需要控制这种依赖性歧义。 Can you help me? 你能帮助我吗?

I think you should have in SharedProjectBuildCode.scala 我认为你应该在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)

...

And don't need to add as dependency in build.sbt anymore. 而且不再需要在build.sbt中添加依赖项了。

I was able to control which dependency set loaded on each use case by using the rules of build files loading provided by SBT. 通过使用SBT提供的构建文件加载规则,我能够控制在每个用例上加载的依赖集。

When you load SBT from a given root directory, it looks for *.sbt files on the root directory and also for *.scala on the root/project directory. 从给定的根目录加载SBT时,它会在根目录中查找* .sbt文件,并在根目录/项目目录中查找* .scala文件。 If you have a multi-project build, then it also reads the definitions of .sbt files that are encountered on child projects, but it will not use project/ .scala files on child projects: 如果您有多项目构建,那么它还会读取子项目中遇到.sbt文件的定义,但它不会在子项目中使用project / .scala文件:

.sbt build definition .sbt构建定义

Multi-project builds 多项目构建

So, I changed my multi-project build the following way: 所以,我改变了我的多项目构建方式如下:

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

This way, depending on the use case I run SBT from the multi-project root or a project internal directory: 这样,根据用例我从多项目根目录或项目内部目录运行SBT:

  • Development: SBT is run from multiprojectRoot directory. 开发:SBT从multiprojectRoot目录运行。 It takes the advantages of having a multi-project build (such as using dependsOn and avoiding publishLocal). 它具有多项目构建的优点(例如使用dependsOn并避免使用publishLocal)。
  • Production: SBT is run from within a concrete project directory, such as multiprojectRoot/project2 . 生产:SBT从具体项目目录中运行,例如multiprojectRoot / project2 It allows the project to be built as stand-alone, having all dependencies as explicit external (useful for declaring a sequence of dependencies on production, continuous integration server). 它允许将项目构建为独立项,将所有依赖项作为显式外部项(对于在生产,连续集成服务器上声明一系列依赖项非常有用)。

Now, a project has 3 instances of code that aggregates their attributes for a final build: 现在,一个项目有3个代码实例,它们聚合最终构建的属性:

  1. multiprojectRoot/project/SharedProjectBuildCode.scala: Contains local dependencies and other code relevant for multi-project build. multiprojectRoot / project / SharedProjectBuildCode.scala:包含本地依赖项和与多项目构建相关的其他代码。
  2. multiprojectRoot/project1/project1-build.sbt: Contains project build attributes, common for multi-project and standalone build of a project, such as name or dependencies that are always external. multiprojectRoot / project1 / project1-build.sbt:包含项目构建属性,通常用于项目的多项目和独立构建,例如始终在外部的名称或依赖项。 The same should be done for other multi-project projects of the same level, to be explicitly treated as external dependency artifacts. 对于同一级别的其他多项目项目也应该这样做,明确地将其视为外部依赖项工件。
  3. multiprojectRoot/project1/project/DeploymentOnlyCode.scala: Contains build attributes that will only be taken into consideration for stand-alone build. multiprojectRoot / project1 / project / DeploymentOnlyCode.scala:包含仅在独立构建时考虑的构建属性。 The same can be done on other sub-projects, if these require to define deployment specific attributes. 如果需要定义特定于部署的属性,则可以对其他子项目执行相同的操作。

This also gives maximum control on how a project is built, whether is a releasable artifact or not, and handle source code relevant only for a given project, as a complete and independent piece. 这也可以最大程度地控制项目的构建方式,是否是可释放的工件,并且只处理与给定项目相关的源代码,作为完整且独立的部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM