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

Lea*_*ner 1 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”和“runtime”桶。
  2. 即使我们都是 Java,对于任何一个项目,我们也不能为其“api”和“运行时”提供单独的版本。虽然我确实了解这在某些情况下可能提供的控制级别,但我不明白这些是如何协同工作的,以确保项目获得指定的依赖项。
  3. Gradle 如何知道在使用平台的项目和平台规范之间匹配哪些配置的约束?我想我看到了平台中定义“api”和其他约束的示例,我“理解”项目将通过声明 api platform(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 ...

Fra*_*teo 5

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

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

Gradle 为 Java 项目提供了一个官方平台插件,但除此之外的任何东西,例如 C++/Swift,您都需要推出自己的插件/平台实现。您可以参考源代码来帮助您实现。

即使我们都是 Java,对于任何一个项目,我们也不能为其“api”和“运行时”提供单独的版本

您不需要为每个配置有单独的版本。api扩展implementationruntimeClasspath( runtimeOnly) 从implementation. 所以声明依赖关系api就足够了。请参阅此处的依赖关系图。

Gradle 如何知道在使用平台的项目和平台规范之间匹配哪些配置的约束?

通过您在项目中如何指定它以及 Java 平台插件的平台实现。例如,给定以下平台:

// my-platform

plugins {
    `java-platform`
}

dependencies {
    constraints {
        api("commons-httpclient:commons-httpclient:3.1")
    }
}
Run Code Online (Sandbox Code Playgroud)

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

dependencies {
    api(platform(":my-platform"))
    implementation(platform(":my-platform"))
    annotationProcessor(platform(":my-platform"))
}
Run Code Online (Sandbox Code Playgroud)

我希望 Gradle 不会试图通过简单的名称匹配来将“api”与“api”匹配

根据使用情况进行匹配。看到条线和这些线。api只是为其插件选择的配置名称 Gradle,请参见此处。他们实际上可以选择任何名称,但更有可能选择api/runtime保持与他们拥有的东西相似的东西。

您将在平台上找到的大多数文档都是面向 Java 开发人员的。我相信这主要是因为平台的概念深受Maven 的 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");
    }
}
Run Code Online (Sandbox Code Playgroud)