|
17 | 17 | package org.springframework.boot.build.mavenplugin;
|
18 | 18 |
|
19 | 19 | import java.io.File;
|
| 20 | +import java.io.IOException; |
20 | 21 | import java.nio.charset.StandardCharsets;
|
21 | 22 | import java.nio.file.Files;
|
22 | 23 | import java.nio.file.Path;
|
| 24 | +import java.nio.file.StandardCopyOption; |
23 | 25 | import java.util.Arrays;
|
24 | 26 |
|
25 | 27 | import io.spring.javaformat.formatter.FileEdit;
|
|
28 | 30 | import org.gradle.api.Plugin;
|
29 | 31 | import org.gradle.api.Project;
|
30 | 32 | import org.gradle.api.Task;
|
| 33 | +import org.gradle.api.artifacts.ComponentMetadataContext; |
| 34 | +import org.gradle.api.artifacts.ComponentMetadataRule; |
| 35 | +import org.gradle.api.artifacts.Configuration; |
| 36 | +import org.gradle.api.artifacts.ModuleVersionIdentifier; |
| 37 | +import org.gradle.api.artifacts.component.ModuleComponentIdentifier; |
| 38 | +import org.gradle.api.artifacts.result.ResolvedArtifactResult; |
| 39 | +import org.gradle.api.attributes.DocsType; |
31 | 40 | import org.gradle.api.file.CopySpec;
|
| 41 | +import org.gradle.api.file.DirectoryProperty; |
| 42 | +import org.gradle.api.model.ObjectFactory; |
32 | 43 | import org.gradle.api.plugins.JavaLibraryPlugin;
|
33 | 44 | import org.gradle.api.plugins.JavaPlugin;
|
34 | 45 | import org.gradle.api.plugins.JavaPluginConvention;
|
35 | 46 | import org.gradle.api.publish.PublishingExtension;
|
36 | 47 | import org.gradle.api.publish.maven.MavenPublication;
|
37 | 48 | import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
|
| 49 | +import org.gradle.api.tasks.Classpath; |
38 | 50 | import org.gradle.api.tasks.Copy;
|
39 | 51 | import org.gradle.api.tasks.JavaExec;
|
40 | 52 | import org.gradle.api.tasks.OutputDirectory;
|
@@ -85,16 +97,30 @@ private void setPackaging(MavenPublication mavenPublication) {
|
85 | 97 | }
|
86 | 98 |
|
87 | 99 | private void addPopulateIntTestMavenRepositoryTask(Project project) {
|
| 100 | + RuntimeClasspathMavenRepository runtimeClasspathMavenRepository = project.getTasks() |
| 101 | + .create("runtimeClasspathMavenRepository", RuntimeClasspathMavenRepository.class); |
| 102 | + runtimeClasspathMavenRepository.getOutputDirectory() |
| 103 | + .set(new File(project.getBuildDir(), "runtime-classpath-repository")); |
| 104 | + Configuration runtimeClasspathWithMetadata = project.getConfigurations().create("runtimeClasspathWithMetadata"); |
| 105 | + runtimeClasspathWithMetadata |
| 106 | + .extendsFrom(project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)); |
| 107 | + runtimeClasspathWithMetadata.attributes((attributes) -> attributes.attribute(DocsType.DOCS_TYPE_ATTRIBUTE, |
| 108 | + project.getObjects().named(DocsType.class, "maven-repository"))); |
| 109 | + project.getDependencies() |
| 110 | + .components((components) -> components.all(MavenRepositoryComponentMetadataRule.class)); |
88 | 111 | Copy task = project.getTasks().create("populateIntTestMavenRepository", Copy.class);
|
89 | 112 | task.setDestinationDir(project.getBuildDir());
|
90 |
| - task.into("int-test-maven-repository", (copy) -> copyIntTestMavenRepositoryFiles(project, copy)); |
| 113 | + task.into("int-test-maven-repository", |
| 114 | + (copy) -> copyIntTestMavenRepositoryFiles(project, copy, runtimeClasspathMavenRepository)); |
91 | 115 | task.dependsOn(project.getTasks().getByName(MavenRepositoryPlugin.PUBLISH_TO_PROJECT_REPOSITORY_TASK_NAME));
|
92 | 116 | project.getTasks().getByName(IntegrationTestPlugin.INT_TEST_TASK_NAME).dependsOn(task);
|
93 | 117 | }
|
94 | 118 |
|
95 |
| - private void copyIntTestMavenRepositoryFiles(Project project, CopySpec copy) { |
| 119 | + private void copyIntTestMavenRepositoryFiles(Project project, CopySpec copy, |
| 120 | + RuntimeClasspathMavenRepository runtimeClasspathMavenRepository) { |
96 | 121 | copy.from(project.getConfigurations().getByName(MavenRepositoryPlugin.MAVEN_REPOSITORY_CONFIGURATION_NAME));
|
97 | 122 | copy.from(new File(project.getBuildDir(), "maven-repository"));
|
| 123 | + copy.from(runtimeClasspathMavenRepository); |
98 | 124 | }
|
99 | 125 |
|
100 | 126 | private void addDocumentPluginGoalsTask(Project project, MavenExec generatePluginDescriptorTask) {
|
@@ -252,4 +278,72 @@ private void save(File output, FileEdit edit) {
|
252 | 278 |
|
253 | 279 | }
|
254 | 280 |
|
| 281 | + public static class MavenRepositoryComponentMetadataRule implements ComponentMetadataRule { |
| 282 | + |
| 283 | + private final ObjectFactory objects; |
| 284 | + |
| 285 | + @javax.inject.Inject |
| 286 | + public MavenRepositoryComponentMetadataRule(ObjectFactory objects) { |
| 287 | + this.objects = objects; |
| 288 | + } |
| 289 | + |
| 290 | + @Override |
| 291 | + public void execute(ComponentMetadataContext context) { |
| 292 | + context.getDetails().maybeAddVariant("compileWithMetadata", "compile", (variant) -> { |
| 293 | + variant.attributes((attributes) -> attributes.attribute(DocsType.DOCS_TYPE_ATTRIBUTE, |
| 294 | + this.objects.named(DocsType.class, "maven-repository"))); |
| 295 | + variant.withFiles((files) -> { |
| 296 | + ModuleVersionIdentifier id = context.getDetails().getId(); |
| 297 | + files.addFile(id.getName() + "-" + id.getVersion() + ".pom"); |
| 298 | + }); |
| 299 | + }); |
| 300 | + } |
| 301 | + |
| 302 | + } |
| 303 | + |
| 304 | + public static class RuntimeClasspathMavenRepository extends DefaultTask { |
| 305 | + |
| 306 | + private final Configuration runtimeClasspath; |
| 307 | + |
| 308 | + private final DirectoryProperty outputDirectory; |
| 309 | + |
| 310 | + public RuntimeClasspathMavenRepository() { |
| 311 | + this.runtimeClasspath = getProject().getConfigurations() |
| 312 | + .getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME); |
| 313 | + this.outputDirectory = getProject().getObjects().directoryProperty(); |
| 314 | + } |
| 315 | + |
| 316 | + @OutputDirectory |
| 317 | + public DirectoryProperty getOutputDirectory() { |
| 318 | + return this.outputDirectory; |
| 319 | + } |
| 320 | + |
| 321 | + @Classpath |
| 322 | + public Configuration getRuntimeClasspath() { |
| 323 | + return this.runtimeClasspath; |
| 324 | + } |
| 325 | + |
| 326 | + @TaskAction |
| 327 | + public void createRepository() { |
| 328 | + for (ResolvedArtifactResult result : this.runtimeClasspath.getIncoming().getArtifacts()) { |
| 329 | + if (result.getId().getComponentIdentifier() instanceof ModuleComponentIdentifier) { |
| 330 | + ModuleComponentIdentifier identifier = (ModuleComponentIdentifier) result.getId() |
| 331 | + .getComponentIdentifier(); |
| 332 | + File repositoryLocation = this.outputDirectory.dir(identifier.getGroup().replace('.', '/') + "/" |
| 333 | + + identifier.getModule() + "/" + identifier.getVersion() + "/" + result.getFile().getName()) |
| 334 | + .get().getAsFile(); |
| 335 | + repositoryLocation.getParentFile().mkdirs(); |
| 336 | + try { |
| 337 | + Files.copy(result.getFile().toPath(), repositoryLocation.toPath(), |
| 338 | + StandardCopyOption.REPLACE_EXISTING); |
| 339 | + } |
| 340 | + catch (IOException ex) { |
| 341 | + throw new RuntimeException("Failed to copy artifact '" + result + "'", ex); |
| 342 | + } |
| 343 | + } |
| 344 | + } |
| 345 | + } |
| 346 | + |
| 347 | + } |
| 348 | + |
255 | 349 | }
|
0 commit comments