简体   繁体   English

在Gradle中管理传递依赖版本

[英]Managing transitive dependency versions in Gradle

I have 3 gradle projects: Project-1, Project-2, Project-3. 我有3个gradle项目:Project-1,Project-2,Project-3。 Project-1 and Project-2 are Java libraries, Project-3 is a consumer of these libraries. Project-1和Project-2是Java库,Project-3是这些库的使用者。 Both Project-1 and Project-2 have a dependency on Module-A. Project-1和Project-2都依赖于Module-A。 However, for every one of them I want to be able to specify a list of exact versions that they are compatible with. 但是,对于它们中的每一个,我希望能够指定一列与它们兼容的确切版本。 For example, Project-1 is compatible and tested with Module-A, versions 1 and 2, but Project-2 is compatible with Module-A, versions 2 and 3. I want to be able to specify these requirements in the build configuration of each project. 例如,Project-1与版本1和2的Module-A兼容并经过测试,但是Project-2与版本2和3的Module-A兼容。我希望能够在构建配置中指定这些要求。每个项目。 These dependencies can be impelementation only or even compileOnly. 这些依赖关系只能是基本实现,甚至可以是仅编译。

When Project-3 consumes libraries built by Project-1 and Project-2, I want to make sure that Module-A is resolved to the latest version that is explicitly listed in both Project-1 and Project-2. 当Project-3使用Project-1和Project-2构建的库时,我想确保将Module-A解析为Project-1和Project-2中明确列出的最新版本。 Otherwise, I would like to get an error at the build step, that no satisfying dependency resolution can be found. 否则,我想在构建步骤中得到一个错误,那就是找不到令人满意的依赖项解析。 Ideally, I would like to be able to explicitly specify version of Module-A in Project-3 Gradle build and receive an error if it's not compatible with any of Project-1 or Project-2. 理想情况下,我希望能够在Project-3 Gradle构建中明确指定Module-A的版本,如果与Project-1或Project-2都不兼容,则会收到错误消息。

Project-1 and Project-2 artifacts are consumed from and uploaded to a local Maven repository using Maven plugin. 使用Maven插件将Project-1和Project-2工件从本地Maven存储库中消费并上传到本地Maven存储库。

see if the below approach helps. 看看下面的方法是否有帮助。 it assumes a project structured with three modules like so: 它假定一个项目由三个模块构成,如下所示:

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

...and various versions of Guava assume the role of Module-A as you've described the setup. ...以及您描述过的番石榴的各种版本都扮演Module-A的角色。

Top-level build.gradle : 顶级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'
}

extra properties used to specify acceptable versions of Guava for each module. 用于为每个模块指定可接受的Guava版本的额外属性。 Project-3's version is calculated as the latest version used between Project-1 and Project-2. Project-3的版本计算为Project-1和Project-2之间使用的最新版本。 (additionally, the Java plugin is applied to the three sub-projects for convenience). (此外,为方便起见,Java插件已应用于三个子项目)。

Project-1's build.gradle : Project-1的build.gradle

archivesBaseName = 'project1'

repositories {
  mavenCentral()
}

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

the extra property for Project-1's Guava versions is interpolated and transformed from a list of strings to a comma-delimited string. 将插入Project-1的Guava版本的extra属性,并将其从字符串列表转换为以逗号分隔的字符串。 this uses Gradle's ability to use Ivy notation for specifying a range of versions, ie [26.0-jre,27.0-jre] . 这使用了Gradle使用Ivy表示法指定版本范围的能力,即[26.0-jre,27.0-jre]

Project-2's build.gradle : Project-2的build.gradle

archivesBaseName = 'project2'

repositories {
  mavenCentral()
}

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

(similar implementation to Project-1) (类似于Project-1的实现)

Project-3's build.gradle : Project-3的build.gradle

archivesBaseName = 'project3'

repositories {
  mavenCentral()
}

dependencies {
  implementation project(':project1')
  implementation project(':project2')
  implementation "com.google.guava:guava:$project3GuavaVersion"
}

Project-1 and Project-2 are defined as project-level dependencies, and the explicitly calculated version for Guava defined as an extra property is used here. Project-1和Project-2被定义为项目级别的依赖项,此处使用了定义为额外属性的Guava显式计算版本。

i hope that covers everything. 我希望能涵盖一切。 if nothing else, i hope it inspires some new thought! 如果没有别的,我希望它能激发一些新的想法!

UPDATE UPDATE

as you've mentioned in the comments that your projects are not setup hierarchically, you also have the option of setting them up in a "flat" arrangement in which all the projects exist at the same folder depth, like so: 正如您在评论中提到的那样,您的项目不是分层设置的,您还可以选择以“扁平”方式设置它们,其中所有项目都位于相同的文件夹深度,例如:

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

"master" here is a specially named project that sits alongside the other projects. 这里的“主”是一个特别命名的项目,与其他项目并列。 settings.gradle should be moved into master and should use Settings.includeFlat() to indicate that you want to include projects that exist as the same level: settings.gradle应该被移入master并且应该使用Settings.includeFlat()来指示您要包含存在于同一级别的项目:

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

the details of my originally proposed solution should be applicable to this setup. 我最初提出的解决方案的详细信息应适用于此设置。

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

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