This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ant-antlibs-cyclonedx.git


The following commit(s) were added to refs/heads/main by this push:
     new 82724a5  support for components beyond the main component
82724a5 is described below

commit 82724a54a5a04562780026de8ed93a6d920b0d44
Author: Stefan Bodewig <[email protected]>
AuthorDate: Fri May 1 16:28:34 2026 +0200

    support for components beyond the main component
---
 src/main/org/apache/ant/cyclonedx/Component.java   | 30 +++++++++++++++++++++-
 .../org/apache/ant/cyclonedx/ComponentBomTask.java | 18 ++++++++++++-
 src/main/org/apache/ant/cyclonedx/ToolData.java    |  2 +-
 src/tests/antunit/componentbom-test.xml            | 29 +++++++++++++++++++++
 4 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/src/main/org/apache/ant/cyclonedx/Component.java 
b/src/main/org/apache/ant/cyclonedx/Component.java
index b590674..8dd72a1 100644
--- a/src/main/org/apache/ant/cyclonedx/Component.java
+++ b/src/main/org/apache/ant/cyclonedx/Component.java
@@ -27,6 +27,8 @@ public class Component {
     private String purl;
     private String bomRef;
     private List<org.cyclonedx.model.ExternalReference> externalReferences = 
new ArrayList<>();
+    private org.cyclonedx.model.Component.Scope scope;
+    private boolean isExternal = false;
 
     public void add(Resource resource) {
         if (this.resource != null) {
@@ -96,7 +98,32 @@ public class Component {
         externalReferences.add(ref.toCycloneDxExternalReference());
     }
 
-    public org.cyclonedx.model.Component toCycloneDxComponent(Version 
bomVersion)
+    public void setScope(org.cyclonedx.model.Component.Scope scope) {
+        this.scope = scope;
+    }
+
+    public void setIsExternal(boolean isExternal) {
+        this.isExternal = isExternal;
+    }
+
+    public org.cyclonedx.model.Component toMainCycloneDxComponent(Version 
bomVersion)
+        throws IOException {
+        if (isExternal) {
+            throw new BuildException("isExternal can not be true for the main 
bom component");
+        }
+        return toCycloneDxComponent(bomVersion);
+    }
+
+    public org.cyclonedx.model.Component 
toAdditionalCycloneDxComponent(Version bomVersion)
+        throws IOException {
+        org.cyclonedx.model.Component component = 
toCycloneDxComponent(bomVersion);
+        if (scope != null) {
+            component.setScope(scope);
+        }
+        return component;
+    }
+
+    private org.cyclonedx.model.Component toCycloneDxComponent(Version 
bomVersion)
         throws IOException {
         if (name == null) {
             throw new BuildException("component name is required");
@@ -134,6 +161,7 @@ public class Component {
         if (!externalReferences.isEmpty()) {
             component.setExternalReferences(externalReferences);
         }
+        // add isExternal once VERSION_17 is supported by cyclonedx-java-core
         addHashes(component, bomVersion);
         return component;
     }
diff --git a/src/main/org/apache/ant/cyclonedx/ComponentBomTask.java 
b/src/main/org/apache/ant/cyclonedx/ComponentBomTask.java
index 0615bf0..027371d 100644
--- a/src/main/org/apache/ant/cyclonedx/ComponentBomTask.java
+++ b/src/main/org/apache/ant/cyclonedx/ComponentBomTask.java
@@ -5,8 +5,10 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
+import java.util.List;
 import java.util.UUID;
 
 import org.apache.tools.ant.BuildException;
@@ -31,6 +33,7 @@ public class ComponentBomTask extends Task {
     private File bomFile;
     private Format format = Format.JSON;
     private Component component;
+    private List<Component> additionalComponents = new ArrayList<>();
 
     public void setBomFile(File f) {
         bomFile = f;
@@ -48,6 +51,10 @@ public class ComponentBomTask extends Task {
         return component;
     }
 
+    public void addAdditionalComponent(Component c) {
+        additionalComponents.add(c);
+    }
+
     public void execute() {
         try {
             Bom bom = createBom();
@@ -74,9 +81,18 @@ public class ComponentBomTask extends Task {
         if (component == null) {
             throw new BuildException("nested component element is required");
         }
-        meta.setComponent(component.toCycloneDxComponent(Version.VERSION_16));
+        
meta.setComponent(component.toMainCycloneDxComponent(Version.VERSION_16));
 
         bom.setMetadata(meta);
+
+        if (!additionalComponents.isEmpty()) {
+            List<org.cyclonedx.model.Component> cs = new ArrayList<>();
+            for (Component c : additionalComponents) {
+                cs.add(c.toAdditionalCycloneDxComponent(Version.VERSION_16));
+            }
+            bom.setComponents(cs);
+        }
+
         return bom;
     }
 
diff --git a/src/main/org/apache/ant/cyclonedx/ToolData.java 
b/src/main/org/apache/ant/cyclonedx/ToolData.java
index fe441b8..b686206 100644
--- a/src/main/org/apache/ant/cyclonedx/ToolData.java
+++ b/src/main/org/apache/ant/cyclonedx/ToolData.java
@@ -57,7 +57,7 @@ public class ToolData {
         }
 
         org.cyclonedx.model.Component cdxComponent =
-            antlibComponent.toCycloneDxComponent(Version.VERSION_16);
+            antlibComponent.toMainCycloneDxComponent(Version.VERSION_16);
         cdxComponent.setBomRef(null);
         tool.setComponents(Collections.singletonList(cdxComponent));
         return tool;
diff --git a/src/tests/antunit/componentbom-test.xml 
b/src/tests/antunit/componentbom-test.xml
index 0113821..1c6ed7c 100644
--- a/src/tests/antunit/componentbom-test.xml
+++ b/src/tests/antunit/componentbom-test.xml
@@ -266,4 +266,33 @@
         value='&lt;url&gt;https://example.com/&lt;/url&gt;'/>
   </target>
 
+  <target name="testMinimalAdditionalComponentData">
+    <mkdir dir="${output}"/>
+    <cdx:componentbom bomfile="${output}/bom.json" format="JSON"
+                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
+      <component name="testname"/>
+      <additionalComponent name="dependency" scope="OPTIONAL"/>
+    </cdx:componentbom>
+    <copy file="${output}/bom.json" todir="/tmp"/>
+    <cdx:componentbom bomfile="${output}/bom.xml" format="XML"
+                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
+      <component name="testname"/>
+      <additionalComponent name="dependency" scope="OPTIONAL"/>
+    </cdx:componentbom>
+    <copy file="${output}/bom.xml" todir="/tmp"/>
+    <xmlproperty file="${output}/bom.xml"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.name"
+        value="dependency"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component(type)"
+        value="library"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.scope"
+        value="optional"/>
+  </target>
+
 </project>

Reply via email to