Rework dep mgmt again to avoid consumers picking up strict constraints

This paves the way for publishing Gradle module metadata once the
problem caused by snapshot versions and our two-step publication
process has been addressed.

See gh-19609
This commit is contained in:
Andy Wilkinson
2020-01-15 12:32:37 +00:00
parent 5ba0a9120e
commit 714a187d8f
79 changed files with 212 additions and 106 deletions

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2020-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.build;
import java.util.Collections;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.plugins.JavaBasePlugin;
import org.springframework.boot.build.optional.OptionalDependenciesPlugin;
/**
* Plugin to apply internal dependency management to Spring Boot's projects. Uses a custom
* configuration to enforce a platform for Spring Boot's own build. This prevents the
* enforced (strict) constraints from being visible to external consumers.
*
* @author Andy Wilkinson
*/
public class InternalDependencyManagementPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.getPlugins().withType(JavaBasePlugin.class, (java) -> configureDependencyManagement(project));
}
private void configureDependencyManagement(Project project) {
ConfigurationContainer configurations = project.getConfigurations();
Configuration dependencyManagement = configurations.create("internalDependencyManagement", (configuration) -> {
configuration.setVisible(false);
configuration.setCanBeConsumed(false);
configuration.setCanBeResolved(false);
});
configurations.matching((configuration) -> configuration.getName().endsWith("Classpath"))
.all((configuration) -> configuration.extendsFrom(dependencyManagement));
Dependency springBootParent = project.getDependencies().enforcedPlatform(project.getDependencies()
.project(Collections.singletonMap("path", ":spring-boot-project:spring-boot-parent")));
dependencyManagement.getDependencies().add(springBootParent);
project.getPlugins().withType(OptionalDependenciesPlugin.class, (optionalDependencies) -> configurations
.getByName(OptionalDependenciesPlugin.OPTIONAL_CONFIGURATION_NAME).extendsFrom(dependencyManagement));
}
}

View File

@@ -30,6 +30,7 @@ import org.apache.maven.artifact.versioning.VersionRange;
import org.gradle.api.InvalidUserCodeException;
import org.gradle.api.InvalidUserDataException;
import org.gradle.api.artifacts.dsl.DependencyHandler;
import org.gradle.api.plugins.JavaPlatformPlugin;
import org.gradle.util.ConfigureUtil;
import org.springframework.boot.build.bom.Library.Exclusion;
@@ -51,10 +52,10 @@ public class BomExtension {
private final List<Library> libraries = new ArrayList<Library>();
private final DependencyHandler dependencyHandler;
private final UpgradeHandler upgradeHandler = new UpgradeHandler();
private final DependencyHandler dependencyHandler;
public BomExtension(DependencyHandler dependencyHandler) {
this.dependencyHandler = dependencyHandler;
}
@@ -107,13 +108,16 @@ public class BomExtension {
for (Group group : library.getGroups()) {
for (Module module : group.getModules()) {
this.putArtifactVersionProperty(group.getId(), module.getName(), library.getVersionProperty());
this.dependencyHandler.getConstraints().add("api",
this.dependencyHandler.getConstraints().add(JavaPlatformPlugin.API_CONFIGURATION_NAME,
createDependencyNotation(group.getId(), module.getName(), library.getVersion()));
}
for (String bomImport : group.getBoms()) {
this.putArtifactVersionProperty(group.getId(), bomImport, library.getVersionProperty());
this.dependencyHandler.add("api", this.dependencyHandler
.enforcedPlatform(createDependencyNotation(group.getId(), bomImport, library.getVersion())));
String bomDependency = createDependencyNotation(group.getId(), bomImport, library.getVersion());
this.dependencyHandler.add(JavaPlatformPlugin.API_CONFIGURATION_NAME,
this.dependencyHandler.platform(bomDependency));
this.dependencyHandler.add(BomPlugin.API_ENFORCED_CONFIGURATION_NAME,
this.dependencyHandler.enforcedPlatform(bomDependency));
}
}
}

View File

@@ -67,6 +67,8 @@ import org.springframework.util.FileCopyUtils;
*/
public class BomPlugin implements Plugin<Project> {
static final String API_ENFORCED_CONFIGURATION_NAME = "apiEnforced";
@Override
public void apply(Project project) {
PluginContainer plugins = project.getPlugins();
@@ -75,6 +77,7 @@ public class BomPlugin implements Plugin<Project> {
plugins.apply(JavaPlatformPlugin.class);
JavaPlatformExtension javaPlatform = project.getExtensions().getByType(JavaPlatformExtension.class);
javaPlatform.allowDependencies();
createApiEnforcedConfiguration(project);
BomExtension bom = project.getExtensions().create("bom", BomExtension.class, project.getDependencies());
project.getTasks().create("bomrCheck", CheckBom.class, bom);
project.getTasks().create("bomrUpgrade", UpgradeBom.class, bom);
@@ -114,6 +117,19 @@ public class BomPlugin implements Plugin<Project> {
});
}
private void createApiEnforcedConfiguration(Project project) {
Configuration apiEnforced = project.getConfigurations().create(API_ENFORCED_CONFIGURATION_NAME,
(configuration) -> {
configuration.setCanBeConsumed(false);
configuration.setCanBeResolved(false);
configuration.setVisible(false);
});
project.getConfigurations().getByName(JavaPlatformPlugin.ENFORCED_API_ELEMENTS_CONFIGURATION_NAME)
.extendsFrom(apiEnforced);
project.getConfigurations().getByName(JavaPlatformPlugin.ENFORCED_RUNTIME_ELEMENTS_CONFIGURATION_NAME)
.extendsFrom(apiEnforced);
}
private static final class PublishingCustomizer {
private final Project project;

View File

@@ -29,6 +29,7 @@ import org.gradle.api.plugins.PluginContainer;
import org.springframework.boot.build.ConventionsPlugin;
import org.springframework.boot.build.DeployedPlugin;
import org.springframework.boot.build.InternalDependencyManagementPlugin;
import org.springframework.boot.build.classpath.CheckClasspathForConflicts;
import org.springframework.boot.build.classpath.CheckClasspathForProhibitedDependencies;
import org.springframework.util.StringUtils;
@@ -46,6 +47,7 @@ public class StarterPlugin implements Plugin<Project> {
plugins.apply(DeployedPlugin.class);
plugins.apply(JavaLibraryPlugin.class);
plugins.apply(ConventionsPlugin.class);
plugins.apply(InternalDependencyManagementPlugin.class);
StarterMetadata starterMetadata = project.getTasks().create("starterMetadata", StarterMetadata.class);
ConfigurationContainer configurations = project.getConfigurations();
Configuration runtimeClasspath = configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);