代码之家  ›  专栏  ›  技术社区  ›  schatten

管理gradle中的可传递依赖关系版本

  •  2
  • schatten  · 技术社区  · 6 年前

    我有三个毕业项目:项目1,项目2,项目3。project-1和project-2是java库,project-3是这些库的使用者。Project-1和Project-2都依赖于模块a。但是,对于它们中的每一个,我希望能够指定它们兼容的确切版本列表例如,project-1与module-a的版本1和2兼容并经过测试,但是project-2与module-a的版本2和3兼容。我希望能够在每个项目的生成配置中指定这些需求。这些依赖项只能是强制的,甚至可以是编译的。

    当project-3使用project-1和project-2构建的库时,我想确保模块a被解析为project-1和project-2中明确列出的最新版本。否则,我想在构建步骤中得到一个错误,即找不到令人满意的依赖项解析。理想情况下,我希望能够在project-3梯度构建中显式地指定module-a的版本,如果module-a与project-1或project-2中的任何一个不兼容,则会收到错误。

    Project-1和Project-2工件使用Maven插件从本地Maven存储库消费并上传到本地Maven存储库。

    1 回复  |  直到 6 年前
        1
  •  0
  •   homerman    6 年前

    看看下面的方法是否有用。它假设一个项目由三个模块构成,如下所示:

    Top-level
    ├── Project-1
    ├── Project-2
    └── Project-3
    

    ……各种版本的番石榴扮演着 Module-A 就像你描述的那样。

    顶层 build.gradle 以下内容:

    ext {
      project1GuavaVersions = ['26.0-jre','27.0-jre']
      project2GuavaVersions = ['25.0-jre','26.0-jre']
    
      if(project1GuavaVersions.disjoint(project2GuavaVersions)) {
        throw new GradleException('No common version(s) of Guava defined')
      } else {
        project3GuavaVersion = new HashSet(project1GuavaVersions + project2GuavaVersions).max()
      }
    
    subprojects {
      apply plugin: 'java'
    }
    

    用于为每个模块指定可接受的番石榴版本的额外属性。project-3的版本计算为project-1和project-2之间使用的最新版本。(另外,为了方便起见,Java插件被应用到三个子项目中)。

    项目1 平地 以下内容:

    archivesBaseName = 'project1'
    
    repositories {
      mavenCentral()
    }
    
    dependencies {
      implementation "com.google.guava:guava:[${project1GuavaVersions.join(',')}]"
    }
    

    project-1的番石榴版本的额外属性被插入,并从字符串列表转换为逗号分隔的字符串。这使用了gradle使用常春藤符号指定一系列版本的能力,即 [26.0-jre,27.0-jre] .

    项目2 build.gradle公司 :

    archivesBaseName = 'project2'
    
    repositories {
      mavenCentral()
    }
    
    dependencies {
      implementation "com.google.guava:guava:[${project2GuavaVersions.join(',')}]"
    }
    

    (与项目1类似)

    项目-3 build.gradle公司 :

    archivesBaseName = 'project3'
    
    repositories {
      mavenCentral()
    }
    
    dependencies {
      implementation project(':project1')
      implementation project(':project2')
      implementation "com.google.guava:guava:$project3GuavaVersion"
    }
    

    project-1和project-2被定义为项目级依赖项,这里使用定义为额外属性的guava显式计算版本。

    我希望这能涵盖一切。如果没有别的,我希望它能激发一些新的想法!

    更新

    正如你在评论中提到的,你的项目不是分层设置的,你也可以在一个“扁平”的安排中设置它们,其中所有的项目都存在于相同的文件夹深度,比如:

    (root)
    ├── project1
    │   └── build.gradle
    ├── project2
    │   └── build.gradle
    ├── project3
    │   └── build.gradle
    └── master
        ├── build.gradle
        └── settings.gradle
    

    这里的“master”是一个特别命名的项目,它与其他项目并驾齐驱。 settings.gradle 应该搬进 master 应该使用 Settings.includeFlat() 指示要包含以相同级别存在的项目:

    includeFlat 'project1'
    includeFlat 'project2'
    includeFlat 'project3'
    

    我最初建议的解决方案的详细信息应适用于此设置。