如何使用Gradle“平台”在多项目设置中对齐依赖项版本?

时间:2020-04-07 15:44:38

标签: gradle gradle-dependencies gradle-multi-project-build gradle-groovy-dsl

我正在尝试学习如何使用“平台”在多项目设置中的项目之间对齐依赖项版本。到目前为止,我已经看到:

  1. https://docs.gradle.org/6.2.1/userguide/platforms.html
  2. https://docs.gradle.org/6.2.1/userguide/dependency_management_terminology.html#sub::terminology_platform
  3. https://docs.gradle.org/6.2.1/userguide/dependency_version_alignment.html#sec:virtual_platform
  4. https://docs.gradle.org/6.2.1/userguide/dependency_constraints.html#sec:adding-constraints-transitive-deps
  5. https://docs.gradle.org/6.2.1/userguide/java_platform_plugin.html
  6. …以及其他一些外部网站试图查找示例,例如 https://dzone.com/articles/gradle-goodness-use-bill-of-materials-bom-as-depen

我了解如何在项目中声明约束。我想我也了解如何为此目的使用BOM。但是,我想为此目的使用“强制平台项目”,并且我在这里不了解很多事情:

  1. 我是否必须使用“ java平台”插件??我们有非Java项目。我们的配置不太适合“ api”和“运行时”存储桶。
  2. 即使我们都是Java,对于任何一个项目,我们都无法为其“ api”和“运行时”使用单独的版本。虽然我确实了解在某些情况下可能提供的控制级别,但我不了解它们如何协同工作以确保项目获得指定的依赖性。
  3. Gradle如何知道使用平台的项目和平台规范之间要匹配的配置约束?我想我看到了在平台上定义“ api”和其他约束的示例, “了解”,这些项目将通过声明api平台(project(':platform'))来引用此内容。我希望Gradle不会尝试通过简单的名称匹配将“ api”与“ api”进行匹配。我需要多个不同的依赖项配置,以使其与同一个平台“配置”(无论其名称如何)保持一致。

通常,我找不到足够的信息来对它的功能或工作方式充满信心。有人可以填补空白还是将我指向某些文档,其中提供了比上述示例更多的示例和详细信息?目前,我不知道我应该为该平台项目(其build.gradle)实际写什么,和/或如何从当前的现有项目中正确引用它。

谢谢!

更新1 :在https://discuss.gradle.org/t/can-someone-tell-me-what-i-am-doing-wrong-to-align-dependency-versions-across-projects/35601上发布了一个最小的实验来测试我对此的理解(缺乏)...

1 个答案:

答案 0 :(得分:1)

我是否必须使用“ java平台”插件?

不。如果您有非Java项目,则不应使用Java平台插件。如插件名称所示,它用于Java项目。

Gradle为Java项目提供了一个官方平台插件,但是除C ++ / Swift之外的任何东西,您都需要滚动自己的平台插件/实现。您可以参考source code来帮助您实施。

即使我们都是Java,对于任何一个项目,我们都无法为其“ api”和“运行时”使用单独的版本

您不需要为每个配置使用单独的版本。 api扩展了implementation,而runtimeClasspathruntimeOnly)从implementation扩展了。因此,声明api的依赖关系就足够了。请参阅依赖性图here

Gradle如何知道使用平台的项目和平台规范之间要匹配的配置限制?

根据您在项目中的指定方式以及Java平台插件的平台实现方式。例如,给定以下平台:

// my-platform

plugins {
    `java-platform`
}

dependencies {
    constraints {
        api("commons-httpclient:commons-httpclient:3.1")
    }
}

我可以在项目中执行以下任何操作:

dependencies {
    api(platform(":my-platform"))
    implementation(platform(":my-platform"))
    annotationProcessor(platform(":my-platform"))
}

我希望Gradle不要尝试通过简单的名称匹配将“ api”与“ api”进行匹配

根据使用情况进行匹配。请参见this行和these行。 api只是为其插件选择的配置名称Gradle,请参见here。他们从字面上可以选择任何名称,但更有可能选择api / runtime来保持与他们现有的相似。

您将在平台上找到的大多数文档都是针对Java开发人员的。我认为,这主要是由于平台的概念受到Maven's BOM

的极大启发

如果您真的想了解Gradle在平台上的工作方式,则可以痛苦地检查源代码或编写使用平台的简单Gradle插件,然后使用GradleRunner并使用断点进行调试。示例插件可以是:

public class ExamplePlatformPlugin implements Plugin<Project> {

    @Override
    public void apply(Project project) {
        project.getRepositories().mavenCentral();

        DependencyHandler dependencies = project.getDependencies();

        // api(platform(""org.springframework.boot:spring-boot-dependencies:2.2.6.RELEASE"")
        Dependency springBootPlatform = dependencies.platform("org.springframework.boot:spring-boot-dependencies:2.2.6.RELEASE");
        dependencies.add(JavaPlugin.API_CONFIGURATION_NAME, springBootPlatform);

        // api("org.apache.commons:commons-lang3")
        dependencies.add(JavaPlugin.API_CONFIGURATION_NAME, "org.apache.commons:commons-lang3");
    }
}