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

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-trusted-release.git


The following commit(s) were added to refs/heads/main by this push:
     new 59b5ddf  Use the C# version of the CycloneDX tool for validation
59b5ddf is described below

commit 59b5ddf8f1b57101f1a411c5e48052bc67c664c3
Author: Sean B. Palmer <[email protected]>
AuthorDate: Mon Sep 1 20:15:52 2025 +0100

    Use the C# version of the CycloneDX tool for validation
---
 Dockerfile.alpine |  6 ++++++
 Dockerfile.ubuntu |  5 +++++
 atr/sbomtool.py   | 46 +++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/Dockerfile.alpine b/Dockerfile.alpine
index ef04c55..f63922b 100644
--- a/Dockerfile.alpine
+++ b/Dockerfile.alpine
@@ -71,6 +71,7 @@ ENV RAT_VERSION=0.16.1
 RUN mkdir -p /opt/tools
 RUN mkdir -p /tmp/apache-rat
 WORKDIR /tmp/apache-rat
+# TODO: Check hash
 RUN curl -L 
https://dlcdn.apache.org/creadur/apache-rat-${RAT_VERSION}/apache-rat-${RAT_VERSION}-bin.tar.gz
 -o apache-rat.tar.gz
 RUN tar -xzf apache-rat.tar.gz
 RUN find apache-rat-${RAT_VERSION} -type f -name "*.jar" -exec cp {} . \;
@@ -87,6 +88,11 @@ RUN GOPATH=/usr/local go install 
github.com/anchore/syft/cmd/[email protected]
 RUN GOPATH=/usr/local go install github.com/snyk/[email protected]
 RUN GOPATH=/usr/local go install github.com/interlynk-io/[email protected]
 
+ENV CDXCLI_VERSION=0.29.1
+# TODO: Check hash
+RUN curl -L 
https://github.com/CycloneDX/cyclonedx-cli/releases/download/v{CDXCLI_VERSION}/cyclonedx-linux-musl-x64
 \
+    -o /usr/local/bin/cyclonedx
+
 EXPOSE 4443
 
 WORKDIR /opt/atr
diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu
index 5f30a16..beae078 100644
--- a/Dockerfile.ubuntu
+++ b/Dockerfile.ubuntu
@@ -99,6 +99,11 @@ RUN GOPATH=/usr/local go install 
github.com/anchore/syft/cmd/[email protected]
 RUN GOPATH=/usr/local go install github.com/snyk/[email protected]
 RUN GOPATH=/usr/local go install github.com/interlynk-io/[email protected]
 
+ENV CDXCLI_VERSION=0.29.1
+# TODO: Check hash
+RUN curl -L 
https://github.com/CycloneDX/cyclonedx-cli/releases/download/v{CDXCLI_VERSION}/cyclonedx-linux-x64
 \
+    -o /usr/local/bin/cyclonedx
+
 EXPOSE 4443
 
 WORKDIR /opt/atr
diff --git a/atr/sbomtool.py b/atr/sbomtool.py
index 7ef3afd..5761424 100644
--- a/atr/sbomtool.py
+++ b/atr/sbomtool.py
@@ -330,6 +330,7 @@ OutdatedAdapter = pydantic.TypeAdapter(Outdated)
 class Bundle:
     doc: yyjson.Document
     bom: Bom
+    path: pathlib.Path
     text: str
 
 
@@ -578,8 +579,8 @@ def main() -> None:
                 print(sbomqs_total_score(bundle.doc), "->", 
sbomqs_total_score(merged))
             else:
                 print(sbomqs_total_score(bundle.doc))
-        case "validate":
-            errors = validate_cyclonedx_json(bundle)
+        case "validate-atr":
+            errors = validate_cyclonedx_atr(bundle)
             if not errors:
                 print("valid")
             else:
@@ -588,8 +589,18 @@ def main() -> None:
                     if i > 10:
                         print("...")
                         break
-        case "validate-atr":
-            errors = validate_atr(bundle)
+        case "validate-cli":
+            errors = validate_cyclonedx_cli(bundle)
+            if not errors:
+                print("valid")
+            else:
+                for i, e in enumerate(errors):
+                    print(e)
+                    if i > 25:
+                        print("...")
+                        break
+        case "validate-py":
+            errors = validate_cyclonedx_py(bundle)
             if not errors:
                 print("valid")
             else:
@@ -848,7 +859,7 @@ def patch_to_data(patch: Patch) -> list[dict[str, Any]]:
 
 def path_to_bundle(path: pathlib.Path) -> Bundle:
     text = path.read_text(encoding="utf-8")
-    return Bundle(doc=yyjson.Document(text), 
bom=Bom.model_validate_json(text), text=text)
+    return Bundle(doc=yyjson.Document(text), 
bom=Bom.model_validate_json(text), path=path, text=text)
 
 
 def sbomqs_total_score(value: pathlib.Path | str | yyjson.Document) -> float:
@@ -875,7 +886,7 @@ def sbomqs_total_score(value: pathlib.Path | str | 
yyjson.Document) -> float:
     return report.summary.total_score
 
 
-def validate_atr(bundle: Bundle) -> Iterable[Any] | None:
+def validate_cyclonedx_atr(bundle: Bundle) -> Iterable[Any] | None:
     if models_cyclonedx is None:
         raise RuntimeError("models_cyclonedx is not loaded")
     try:
@@ -885,7 +896,28 @@ def validate_atr(bundle: Bundle) -> Iterable[Any] | None:
     return None
 
 
-def validate_cyclonedx_json(bundle: Bundle) -> 
Iterable[cyclonedx.validation.json.JsonValidationError] | None:
+def validate_cyclonedx_cli(bundle: Bundle) -> Iterable[Any] | None:
+    args = [
+        "cyclonedx",
+        "validate",
+        "--fail-on-errors",
+        "--input-format",
+        "json",
+        "--input-file",
+        bundle.path.as_posix(),
+    ]
+    proc = subprocess.run(
+        args,
+        text=True,
+        capture_output=True,
+    )
+    if proc.returncode != 0:
+        err = proc.stdout.strip() or proc.stderr.strip() or "cyclonedx failed"
+        return err.splitlines()
+    return None
+
+
+def validate_cyclonedx_py(bundle: Bundle) -> 
Iterable[cyclonedx.validation.json.JsonValidationError] | None:
     json_sv = get_pointer(bundle.doc, "/specVersion")
     sv = cyclonedx.schema.SchemaVersion.V1_6
     if isinstance(json_sv, str):


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to