|
16 | 16 |
|
17 | 17 | package org.springframework.boot.gradle.plugin; |
18 | 18 |
|
19 | | -import org.cyclonedx.gradle.CycloneDxPlugin; |
20 | | -import org.cyclonedx.gradle.CycloneDxTask; |
| 19 | +import org.cyclonedx.gradle.CyclonedxAggregateTask; |
| 20 | +import org.cyclonedx.gradle.CyclonedxPlugin; |
| 21 | +import org.cyclonedx.model.Component; |
21 | 22 | import org.gradle.api.Action; |
22 | 23 | import org.gradle.api.Plugin; |
23 | 24 | import org.gradle.api.Project; |
|
34 | 35 | import org.springframework.boot.gradle.tasks.bundling.BootWar; |
35 | 36 |
|
36 | 37 | /** |
37 | | - * {@link Action} that is executed in response to the {@link CycloneDxPlugin} being |
| 38 | + * {@link Action} that is executed in response to the {@link CyclonedxPlugin} being |
38 | 39 | * applied. |
39 | 40 | * |
40 | 41 | * @author Moritz Halbritter |
| 42 | + * @author Andy Wilkinson |
41 | 43 | */ |
42 | | -final class CycloneDxPluginAction implements PluginApplicationAction { |
| 44 | +final class CyclonedxPluginAction implements PluginApplicationAction { |
43 | 45 |
|
44 | 46 | @Override |
45 | 47 | public Class<? extends Plugin<? extends Project>> getPluginClass() { |
46 | | - return CycloneDxPlugin.class; |
| 48 | + return CyclonedxPlugin.class; |
47 | 49 | } |
48 | 50 |
|
49 | 51 | @Override |
50 | 52 | public void execute(Project project) { |
51 | | - TaskProvider<CycloneDxTask> cycloneDxTaskProvider = project.getTasks() |
52 | | - .named("cyclonedxBom", CycloneDxTask.class); |
53 | | - configureCycloneDxTask(cycloneDxTaskProvider); |
| 53 | + TaskProvider<CyclonedxAggregateTask> cycloneDxTaskProvider = project.getTasks() |
| 54 | + .named("cyclonedxBom", CyclonedxAggregateTask.class); |
| 55 | + configureCycloneDxTask(cycloneDxTaskProvider, project); |
54 | 56 | configureJavaPlugin(project, cycloneDxTaskProvider); |
55 | 57 | configureSpringBootPlugin(project, cycloneDxTaskProvider); |
56 | 58 | } |
57 | 59 |
|
58 | | - private void configureCycloneDxTask(TaskProvider<CycloneDxTask> taskProvider) { |
| 60 | + private void configureCycloneDxTask(TaskProvider<CyclonedxAggregateTask> taskProvider, Project project) { |
59 | 61 | taskProvider.configure((task) -> { |
60 | | - task.getProjectType().convention("application"); |
61 | | - task.getOutputFormat().convention("json"); |
62 | | - task.getOutputName().convention("application.cdx"); |
| 62 | + task.getProjectType().convention(Component.Type.APPLICATION); |
| 63 | + task.getXmlOutput().unsetConvention(); |
| 64 | + task.getJsonOutput() |
| 65 | + .convention(project.getLayout().getBuildDirectory().file("reports/cyclonedx/application.cdx.json")); |
63 | 66 | task.getIncludeLicenseText().convention(false); |
64 | 67 | }); |
65 | 68 | } |
66 | 69 |
|
67 | | - private void configureJavaPlugin(Project project, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) { |
| 70 | + private void configureJavaPlugin(Project project, TaskProvider<CyclonedxAggregateTask> cycloneDxTaskProvider) { |
68 | 71 | configurePlugin(project, JavaPlugin.class, (javaPlugin) -> { |
69 | 72 | JavaPluginExtension javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class); |
70 | 73 | SourceSet main = javaPluginExtension.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME); |
71 | 74 | configureTask(project, main.getProcessResourcesTaskName(), Copy.class, (copy) -> { |
72 | 75 | copy.dependsOn(cycloneDxTaskProvider); |
73 | | - Provider<String> sbomFileName = cycloneDxTaskProvider |
74 | | - .map((cycloneDxTask) -> cycloneDxTask.getOutputName().get() + getSbomExtension(cycloneDxTask)); |
75 | | - copy.from(cycloneDxTaskProvider, (spec) -> spec.include(sbomFileName.get()).into("META-INF/sbom")); |
| 76 | + Provider<String> sbomFileName = cycloneDxTaskProvider.flatMap( |
| 77 | + (cycloneDxTask) -> cycloneDxTask.getJsonOutput().map((file) -> file.getAsFile().getName())); |
| 78 | + copy.from(cycloneDxTaskProvider, |
| 79 | + (spec) -> spec.include((element) -> element.getName().equals(sbomFileName.get())) |
| 80 | + .into("META-INF/sbom")); |
76 | 81 | }); |
77 | 82 | }); |
78 | 83 | } |
79 | 84 |
|
80 | | - private void configureSpringBootPlugin(Project project, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) { |
| 85 | + private void configureSpringBootPlugin(Project project, |
| 86 | + TaskProvider<CyclonedxAggregateTask> cycloneDxTaskProvider) { |
81 | 87 | configurePlugin(project, SpringBootPlugin.class, (springBootPlugin) -> { |
82 | 88 | configureBootJarTask(project, cycloneDxTaskProvider); |
83 | 89 | configureBootWarTask(project, cycloneDxTaskProvider); |
84 | 90 | }); |
85 | 91 | } |
86 | 92 |
|
87 | | - private void configureBootJarTask(Project project, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) { |
| 93 | + private void configureBootJarTask(Project project, TaskProvider<CyclonedxAggregateTask> cycloneDxTaskProvider) { |
88 | 94 | configureTask(project, SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class, |
89 | 95 | (bootJar) -> configureBootJarTask(bootJar, cycloneDxTaskProvider)); |
90 | 96 | } |
91 | 97 |
|
92 | | - private void configureBootWarTask(Project project, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) { |
| 98 | + private void configureBootWarTask(Project project, TaskProvider<CyclonedxAggregateTask> cycloneDxTaskProvider) { |
93 | 99 | configureTask(project, SpringBootPlugin.BOOT_WAR_TASK_NAME, BootWar.class, |
94 | 100 | (bootWar) -> configureBootWarTask(bootWar, cycloneDxTaskProvider)); |
95 | 101 | } |
96 | 102 |
|
97 | | - private void configureBootJarTask(BootJar task, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) { |
| 103 | + private void configureBootJarTask(BootJar task, TaskProvider<CyclonedxAggregateTask> cycloneDxTaskProvider) { |
98 | 104 | configureJarTask(task, cycloneDxTaskProvider, ""); |
99 | 105 | } |
100 | 106 |
|
101 | | - private void configureBootWarTask(BootWar task, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) { |
| 107 | + private void configureBootWarTask(BootWar task, TaskProvider<CyclonedxAggregateTask> cycloneDxTaskProvider) { |
102 | 108 | configureJarTask(task, cycloneDxTaskProvider, "WEB-INF/classes/"); |
103 | 109 | } |
104 | 110 |
|
105 | | - private void configureJarTask(Jar task, TaskProvider<CycloneDxTask> cycloneDxTaskProvider, |
| 111 | + private void configureJarTask(Jar task, TaskProvider<CyclonedxAggregateTask> cycloneDxTaskProvider, |
106 | 112 | String sbomLocationPrefix) { |
107 | | - Provider<String> sbomFileName = cycloneDxTaskProvider.map((cycloneDxTask) -> "META-INF/sbom/" |
108 | | - + cycloneDxTask.getOutputName().get() + getSbomExtension(cycloneDxTask)); |
| 113 | + Provider<String> sbomFileName = cycloneDxTaskProvider |
| 114 | + .map((cycloneDxTask) -> "META-INF/sbom/" + cycloneDxTask.getJsonOutput().get().getAsFile().getName()); |
109 | 115 | task.manifest((manifest) -> { |
110 | 116 | manifest.getAttributes().put("Sbom-Format", "CycloneDX"); |
111 | 117 | manifest.getAttributes() |
112 | 118 | .put("Sbom-Location", sbomFileName.map((fileName) -> sbomLocationPrefix + fileName)); |
113 | 119 | }); |
114 | 120 | } |
115 | 121 |
|
116 | | - private String getSbomExtension(CycloneDxTask task) { |
117 | | - String format = task.getOutputFormat().get(); |
118 | | - if ("all".equals(format)) { |
119 | | - return ".json"; |
120 | | - } |
121 | | - return "." + format; |
122 | | - } |
123 | | - |
124 | 122 | private <T extends Task> void configureTask(Project project, String name, Class<T> type, Action<T> action) { |
125 | 123 | project.getTasks().withType(type).configureEach((task) -> { |
126 | 124 | if (task.getName().equals(name)) { |
|
0 commit comments