Configure Gradle's processResources to include the SBOM

This also configures the BootWar task to add the SBOM location to the
manifest.

Closes gh-40890
This commit is contained in:
Moritz Halbritter 2024-05-29 09:51:50 +02:00
parent 87094edab0
commit b6c9914c0b

View File

@ -21,9 +21,17 @@ import org.cyclonedx.gradle.CycloneDxTask;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.Copy;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.api.tasks.bundling.Jar;
import org.springframework.boot.gradle.tasks.bundling.BootJar;
import org.springframework.boot.gradle.tasks.bundling.BootWar;
/**
* {@link Action} that is executed in response to the {@link CycloneDxPlugin} being
@ -40,24 +48,69 @@ final class CycloneDxPluginAction implements PluginApplicationAction {
@Override
public void execute(Project project) {
TaskProvider<CycloneDxTask> cyclonedxBom = project.getTasks().named("cyclonedxBom", CycloneDxTask.class);
cyclonedxBom.configure((task) -> {
TaskProvider<CycloneDxTask> cycloneDxTaskProvider = project.getTasks()
.named("cyclonedxBom", CycloneDxTask.class);
configureCycloneDxTask(cycloneDxTaskProvider);
configureJavaPlugin(project, cycloneDxTaskProvider);
configureSpringBootPlugin(project, cycloneDxTaskProvider);
}
private void configureCycloneDxTask(TaskProvider<CycloneDxTask> taskProvider) {
taskProvider.configure((task) -> {
task.getProjectType().convention("application");
task.getOutputFormat().convention("json");
task.getOutputName().convention("application.cdx");
task.getIncludeLicenseText().convention(false);
});
project.getTasks().named(SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class).configure((bootJar) -> {
CycloneDxTask cycloneDxTask = cyclonedxBom.get();
String sbomFileName = cycloneDxTask.getOutputName().get() + getSbomExtension(cycloneDxTask);
bootJar.from(cycloneDxTask, (spec) -> spec.include(sbomFileName).into("META-INF/sbom"));
bootJar.manifest((manifest) -> {
manifest.getAttributes().put("Sbom-Format", "CycloneDX");
manifest.getAttributes().put("Sbom-Location", "META-INF/sbom/" + sbomFileName);
}
private void configureJavaPlugin(Project project, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) {
configurePlugin(project, JavaPlugin.class, (javaPlugin) -> {
JavaPluginExtension javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class);
SourceSet main = javaPluginExtension.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME);
configureTask(project, main.getProcessResourcesTaskName(), Copy.class, (copy) -> {
copy.dependsOn(cycloneDxTaskProvider);
Provider<String> sbomFileName = cycloneDxTaskProvider
.map((cycloneDxTask) -> cycloneDxTask.getOutputName().get() + getSbomExtension(cycloneDxTask));
copy.from(cycloneDxTaskProvider, (spec) -> spec.include(sbomFileName.get()).into("META-INF/sbom"));
});
});
}
private void configureSpringBootPlugin(Project project, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) {
configurePlugin(project, SpringBootPlugin.class, (springBootPlugin) -> {
configureBootJarTask(project, cycloneDxTaskProvider);
configureBootWarTask(project, cycloneDxTaskProvider);
});
}
private void configureBootJarTask(Project project, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) {
configureTask(project, SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class,
(bootJar) -> configureBootJarTask(bootJar, cycloneDxTaskProvider));
}
private void configureBootWarTask(Project project, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) {
configureTask(project, SpringBootPlugin.BOOT_WAR_TASK_NAME, BootWar.class,
(bootWar) -> configureBootWarTask(bootWar, cycloneDxTaskProvider));
}
private void configureBootJarTask(BootJar task, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) {
configureJarTask(task, cycloneDxTaskProvider);
}
private void configureBootWarTask(BootWar task, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) {
configureJarTask(task, cycloneDxTaskProvider);
}
private void configureJarTask(Jar task, TaskProvider<CycloneDxTask> cycloneDxTaskProvider) {
Provider<String> sbomFileName = cycloneDxTaskProvider.map((cycloneDxTask) -> "META-INF/sbom/"
+ cycloneDxTask.getOutputName().get() + getSbomExtension(cycloneDxTask));
task.manifest((manifest) -> {
manifest.getAttributes().put("Sbom-Format", "CycloneDX");
manifest.getAttributes().put("Sbom-Location", sbomFileName);
});
}
private String getSbomExtension(CycloneDxTask task) {
String format = task.getOutputFormat().get();
if ("all".equals(format)) {
@ -66,4 +119,16 @@ final class CycloneDxPluginAction implements PluginApplicationAction {
return "." + format;
}
private <T extends Task> void configureTask(Project project, String name, Class<T> type, Action<T> action) {
project.getTasks().withType(type).configureEach((task) -> {
if (task.getName().equals(name)) {
action.execute(task);
}
});
}
private <T extends Plugin<?>> void configurePlugin(Project project, Class<T> plugin, Action<T> action) {
project.getPlugins().withType(plugin, action);
}
}