在Gradle中管理传递依赖版本

时间:2018-11-02 21:45:44

标签: java gradle dependency-management

我有3个gradle项目:Project-1,Project-2,Project-3。 Project-1和Project-2是Java库,Project-3是这些库的使用者。 Project-1和Project-2都依赖于Module-A。但是,对于它们中的每一个,我希望能够指定一列与它们兼容的确切版本。例如,Project-1与版本1和2的Module-A兼容并经过测试,但是Project-2与版本2和3的Module-A兼容。我希望能够在构建配置中指定这些要求。每个项目。这些依赖关系只能是基本实现,甚至可以是仅编译。

当Project-3使用Project-1和Project-2构建的库时,我要确保将Module-A解析为Project-1和Project-2中明确列出的最新版本。否则,我想在构建步骤中得到一个错误,那就是找不到令人满意的依赖项解析。理想情况下,我希望能够在Project-3 Gradle构建中明确指定Module-A的版本,如果与Project-1或Project-2都不兼容,则会收到错误消息。

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

1 个答案:

答案 0 :(得分:0)

查看以下方法是否有帮助。它假定一个项目由三个模块构成,如下所示:

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'
}

额外属性用于为每个模块指定可接受的Guava版本。 Project-3的版本计算为Project-1和Project-2之间使用的最新版本。 (此外,为方便起见,Java插件已应用于三个子项目)。

Project-1的build.gradle

archivesBaseName = 'project1'

repositories {
  mavenCentral()
}

dependencies {
  implementation "com.google.guava:guava:[${project1GuavaVersions.join(',')}]"
}

插入Project-1的Guava版本的多余属性,并将其从字符串列表转换为逗号分隔的字符串。这使用了Gradle使用Ivy表示法指定版本范围(即[26.0-jre,27.0-jre])的能力。

Project-2的build.gradle

archivesBaseName = 'project2'

repositories {
  mavenCentral()
}

dependencies {
  implementation "com.google.guava:guava:[${project2GuavaVersions.join(',')}]"
}

(类似于Project-1的实现)

Project-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显式计算版本。

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

更新

正如您在评论中提到的那样,您的项目不是分层设置的,您还可以选择将它们设置为“平面”排列,其中所有项目都位于相同的文件夹深度,例如: / p>

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

这里的“主”是一个特别命名的项目,与其他项目并列。 settings.gradle应移至master,并应使用Settings.includeFlat()来指示您要包含存在相同级别的项目:

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

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