mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Only create effective bom artifact when needed
Closes gh-22143
This commit is contained in:
parent
c000ccdaea
commit
d33a01a13f
@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.boot.build.bom;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -23,21 +27,42 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import groovy.lang.Closure;
|
||||
import groovy.lang.GroovyObjectSupport;
|
||||
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
|
||||
import org.apache.maven.artifact.versioning.VersionRange;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.InvalidUserCodeException;
|
||||
import org.gradle.api.InvalidUserDataException;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.dsl.DependencyHandler;
|
||||
import org.gradle.api.plugins.JavaPlatformPlugin;
|
||||
import org.gradle.api.publish.maven.tasks.GenerateMavenPom;
|
||||
import org.gradle.api.tasks.Sync;
|
||||
import org.gradle.api.tasks.TaskExecutionException;
|
||||
import org.gradle.util.ConfigureUtil;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import org.springframework.boot.build.DeployedPlugin;
|
||||
import org.springframework.boot.build.bom.Library.Exclusion;
|
||||
import org.springframework.boot.build.bom.Library.Group;
|
||||
import org.springframework.boot.build.bom.Library.Module;
|
||||
import org.springframework.boot.build.bom.Library.ProhibitedVersion;
|
||||
import org.springframework.boot.build.bom.bomr.version.DependencyVersion;
|
||||
import org.springframework.boot.build.mavenplugin.MavenExec;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* DSL extensions for {@link BomPlugin}.
|
||||
@ -56,8 +81,11 @@ public class BomExtension {
|
||||
|
||||
private final DependencyHandler dependencyHandler;
|
||||
|
||||
public BomExtension(DependencyHandler dependencyHandler) {
|
||||
private final Project project;
|
||||
|
||||
public BomExtension(DependencyHandler dependencyHandler, Project project) {
|
||||
this.dependencyHandler = dependencyHandler;
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
public List<Library> getLibraries() {
|
||||
@ -80,6 +108,43 @@ public class BomExtension {
|
||||
libraryHandler.prohibitedVersions));
|
||||
}
|
||||
|
||||
public void effectiveBomArtifact() {
|
||||
Configuration effectiveBomConfiguration = this.project.getConfigurations().create("effectiveBom");
|
||||
this.project.getTasks().matching((task) -> task.getName().equals(DeployedPlugin.GENERATE_POM_TASK_NAME))
|
||||
.all((task) -> {
|
||||
Sync syncBom = this.project.getTasks().create("syncBom", Sync.class);
|
||||
syncBom.dependsOn(task);
|
||||
File generatedBomDir = new File(this.project.getBuildDir(), "generated/bom");
|
||||
syncBom.setDestinationDir(generatedBomDir);
|
||||
syncBom.from(((GenerateMavenPom) task).getDestination(), (pom) -> pom.rename((name) -> "pom.xml"));
|
||||
try {
|
||||
String settingsXmlContent = FileCopyUtils
|
||||
.copyToString(new InputStreamReader(
|
||||
getClass().getClassLoader().getResourceAsStream("effective-bom-settings.xml"),
|
||||
StandardCharsets.UTF_8))
|
||||
.replace("localRepositoryPath",
|
||||
new File(this.project.getBuildDir(), "local-m2-repository").getAbsolutePath());
|
||||
syncBom.from(this.project.getResources().getText().fromString(settingsXmlContent),
|
||||
(settingsXml) -> settingsXml.rename((name) -> "settings.xml"));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new GradleException("Failed to prepare settings.xml", ex);
|
||||
}
|
||||
MavenExec generateEffectiveBom = this.project.getTasks().create("generateEffectiveBom",
|
||||
MavenExec.class);
|
||||
generateEffectiveBom.setProjectDir(generatedBomDir);
|
||||
File effectiveBom = new File(this.project.getBuildDir(),
|
||||
"generated/effective-bom/" + this.project.getName() + "-effective-bom.xml");
|
||||
generateEffectiveBom.args("--settings", "settings.xml", "help:effective-pom",
|
||||
"-Doutput=" + effectiveBom);
|
||||
generateEffectiveBom.dependsOn(syncBom);
|
||||
generateEffectiveBom.getOutputs().file(effectiveBom);
|
||||
generateEffectiveBom.doLast(new StripUnrepeatableOutputAction(effectiveBom));
|
||||
this.project.getArtifacts().add(effectiveBomConfiguration.getName(), effectiveBom,
|
||||
(artifact) -> artifact.builtBy(generateEffectiveBom));
|
||||
});
|
||||
}
|
||||
|
||||
private String createDependencyNotation(String groupId, String artifactId, DependencyVersion version) {
|
||||
return groupId + ":" + artifactId + ":" + version;
|
||||
}
|
||||
@ -298,4 +363,38 @@ public class BomExtension {
|
||||
|
||||
}
|
||||
|
||||
private static final class StripUnrepeatableOutputAction implements Action<Task> {
|
||||
|
||||
private final File effectiveBom;
|
||||
|
||||
private StripUnrepeatableOutputAction(File xmlFile) {
|
||||
this.effectiveBom = xmlFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Task task) {
|
||||
try {
|
||||
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(this.effectiveBom);
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
NodeList comments = (NodeList) xpath.evaluate("//comment()", document, XPathConstants.NODESET);
|
||||
for (int i = 0; i < comments.getLength(); i++) {
|
||||
org.w3c.dom.Node comment = comments.item(i);
|
||||
comment.getParentNode().removeChild(comment);
|
||||
}
|
||||
org.w3c.dom.Node build = (org.w3c.dom.Node) xpath.evaluate("/project/build", document,
|
||||
XPathConstants.NODE);
|
||||
build.getParentNode().removeChild(build);
|
||||
org.w3c.dom.Node reporting = (org.w3c.dom.Node) xpath.evaluate("/project/reporting", document,
|
||||
XPathConstants.NODE);
|
||||
reporting.getParentNode().removeChild(reporting);
|
||||
TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document),
|
||||
new StreamResult(this.effectiveBom));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new TaskExecutionException(task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,28 +16,13 @@
|
||||
|
||||
package org.springframework.boot.build.bom;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import groovy.util.Node;
|
||||
import groovy.xml.QName;
|
||||
import org.gradle.api.Action;
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.plugins.JavaPlatformExtension;
|
||||
import org.gradle.api.plugins.JavaPlatformPlugin;
|
||||
@ -45,18 +30,11 @@ import org.gradle.api.plugins.PluginContainer;
|
||||
import org.gradle.api.publish.PublishingExtension;
|
||||
import org.gradle.api.publish.maven.MavenPom;
|
||||
import org.gradle.api.publish.maven.MavenPublication;
|
||||
import org.gradle.api.publish.maven.tasks.GenerateMavenPom;
|
||||
import org.gradle.api.tasks.Sync;
|
||||
import org.gradle.api.tasks.TaskExecutionException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import org.springframework.boot.build.DeployedPlugin;
|
||||
import org.springframework.boot.build.MavenRepositoryPlugin;
|
||||
import org.springframework.boot.build.bom.Library.Group;
|
||||
import org.springframework.boot.build.bom.bomr.UpgradeBom;
|
||||
import org.springframework.boot.build.mavenplugin.MavenExec;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* {@link Plugin} for defining a bom. Dependencies are added as constraints in the
|
||||
@ -78,43 +56,12 @@ public class BomPlugin implements Plugin<Project> {
|
||||
JavaPlatformExtension javaPlatform = project.getExtensions().getByType(JavaPlatformExtension.class);
|
||||
javaPlatform.allowDependencies();
|
||||
createApiEnforcedConfiguration(project);
|
||||
BomExtension bom = project.getExtensions().create("bom", BomExtension.class, project.getDependencies());
|
||||
BomExtension bom = project.getExtensions().create("bom", BomExtension.class, project.getDependencies(),
|
||||
project);
|
||||
project.getTasks().create("bomrCheck", CheckBom.class, bom);
|
||||
project.getTasks().create("bomrUpgrade", UpgradeBom.class, bom);
|
||||
new PublishingCustomizer(project, bom).customize();
|
||||
Configuration effectiveBomConfiguration = project.getConfigurations().create("effectiveBom");
|
||||
project.getTasks().matching((task) -> task.getName().equals(DeployedPlugin.GENERATE_POM_TASK_NAME))
|
||||
.all((task) -> {
|
||||
Sync syncBom = project.getTasks().create("syncBom", Sync.class);
|
||||
syncBom.dependsOn(task);
|
||||
File generatedBomDir = new File(project.getBuildDir(), "generated/bom");
|
||||
syncBom.setDestinationDir(generatedBomDir);
|
||||
syncBom.from(((GenerateMavenPom) task).getDestination(), (pom) -> pom.rename((name) -> "pom.xml"));
|
||||
try {
|
||||
String settingsXmlContent = FileCopyUtils
|
||||
.copyToString(new InputStreamReader(
|
||||
getClass().getClassLoader().getResourceAsStream("effective-bom-settings.xml"),
|
||||
StandardCharsets.UTF_8))
|
||||
.replace("localRepositoryPath",
|
||||
new File(project.getBuildDir(), "local-m2-repository").getAbsolutePath());
|
||||
syncBom.from(project.getResources().getText().fromString(settingsXmlContent),
|
||||
(settingsXml) -> settingsXml.rename((name) -> "settings.xml"));
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new GradleException("Failed to prepare settings.xml", ex);
|
||||
}
|
||||
MavenExec generateEffectiveBom = project.getTasks().create("generateEffectiveBom", MavenExec.class);
|
||||
generateEffectiveBom.setProjectDir(generatedBomDir);
|
||||
File effectiveBom = new File(project.getBuildDir(),
|
||||
"generated/effective-bom/" + project.getName() + "-effective-bom.xml");
|
||||
generateEffectiveBom.args("--settings", "settings.xml", "help:effective-pom",
|
||||
"-Doutput=" + effectiveBom);
|
||||
generateEffectiveBom.dependsOn(syncBom);
|
||||
generateEffectiveBom.getOutputs().file(effectiveBom);
|
||||
generateEffectiveBom.doLast(new StripUnrepeatableOutputAction(effectiveBom));
|
||||
project.getArtifacts().add(effectiveBomConfiguration.getName(), effectiveBom,
|
||||
(artifact) -> artifact.builtBy(generateEffectiveBom));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void createApiEnforcedConfiguration(Project project) {
|
||||
@ -276,38 +223,4 @@ public class BomPlugin implements Plugin<Project> {
|
||||
|
||||
}
|
||||
|
||||
private static final class StripUnrepeatableOutputAction implements Action<Task> {
|
||||
|
||||
private final File effectiveBom;
|
||||
|
||||
private StripUnrepeatableOutputAction(File xmlFile) {
|
||||
this.effectiveBom = xmlFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Task task) {
|
||||
try {
|
||||
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(this.effectiveBom);
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
NodeList comments = (NodeList) xpath.evaluate("//comment()", document, XPathConstants.NODESET);
|
||||
for (int i = 0; i < comments.getLength(); i++) {
|
||||
org.w3c.dom.Node comment = comments.item(i);
|
||||
comment.getParentNode().removeChild(comment);
|
||||
}
|
||||
org.w3c.dom.Node build = (org.w3c.dom.Node) xpath.evaluate("/project/build", document,
|
||||
XPathConstants.NODE);
|
||||
build.getParentNode().removeChild(build);
|
||||
org.w3c.dom.Node reporting = (org.w3c.dom.Node) xpath.evaluate("/project/reporting", document,
|
||||
XPathConstants.NODE);
|
||||
reporting.getParentNode().removeChild(reporting);
|
||||
TransformerFactory.newInstance().newTransformer().transform(new DOMSource(document),
|
||||
new StreamResult(this.effectiveBom));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new TaskExecutionException(task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ plugins {
|
||||
description = "Spring Boot Dependencies"
|
||||
|
||||
bom {
|
||||
effectiveBomArtifact()
|
||||
upgrade {
|
||||
policy = "same-major-version"
|
||||
gitHub {
|
||||
|
Loading…
Reference in New Issue
Block a user