diff options
| author | Arne Babenhauserheide <arne_bab@web.de> | 2025-08-31 22:31:16 +0200 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2025-11-12 18:34:07 +0100 |
| commit | 1655930d9f4da8a70103d904d399f12be5cffabb (patch) | |
| tree | ed14cd0401dac4f0aec55fe36fde52739de7c4cb | |
| parent | bbd2d8c3d82f31d3ea1599600d9dcd5834a72a59 (diff) | |
graph: Add cyclonedx-json backend.
Validated with:
guix graph guile -b cyclonedx-json > /tmp/cyc.json && \
docker run -v /tmp/:/tmp/ cyclonedx/cyclonedx-cli validate --input-format json --input-file /tmp/cyc.json
* guix/graph.scm (emit-cyclonedx-prologue, emit-cyclonedx-epilogue,
emit-cyclonedx-node, emit-cyclonedx-edge): New procedures.
(%cyclonedx-backend): New variable.
(%graph-backends): Add %cyclonedx-backend.
Change-Id: Icc8c33cbc08da0137489d13bdad618ef55a14923
| -rw-r--r-- | guix/graph.scm | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/guix/graph.scm b/guix/graph.scm index e661c954672..42288062da0 100644 --- a/guix/graph.scm +++ b/guix/graph.scm @@ -26,6 +26,7 @@ #:autoload (guix i18n) (G_) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) + #:use-module (srfi srfi-19) ;; date->string #:use-module (srfi srfi-26) #:use-module (srfi srfi-34) #:use-module (ice-9 match) @@ -258,6 +259,75 @@ NODE1 to NODE2 of the given TYPE. Return #f when there is no path." ;;; +;;; SBOM CycloneDX JSON export. +;;; +;;; Schema: https://cyclonedx.org/docs/1.6/json/#metadata_tools_oneOf_i0_components_items_version +;;; + + +(define (emit-cyclonedx-prologue name port) + (format port "{ + \"bomFormat\": \"CycloneDX\", + \"specVersion\": \"1.6\", + \"metadata\": { + \"timestamp\": \"~a\", + \"tools\": { + \"components\": [ + { + \"type\": \"operating-system\", + \"name\": \"guix\" + }, + { + \"type\": \"application\", + \"name\": \"guix-graph\" + } + ] + } + }, + \"components\": [ +" + (date->string (current-date 0) "~5Z"))) ;; UTC time, iso date-time + +(define (emit-cyclonedx-epilogue port) + ;; the safety of each tool built on Guix depends on Guix + (display "\n { + \"type\": \"operating-system\", + \"name\": \"guix\" + } + ]\n}\n" port)) + +(define (emit-cyclonedx-node id label port) + (match (if (string-contains label "@") + (string-split label #\@) + (list label "N/A")) + ((name version) + (format port "\n { + \"type\": \"application\", + \"name\": \"~a\", + \"version\": \"~a\" + }," + name version)) + (else ;; more than one @ + (format port "\n { + \"type\": \"application\", + \"name\": \"~a\", + }," + label)))) + +(define (emit-cyclonedx-edge id1 id2 port) + ;; Left empty: does not include edges at the moment. Adding them as + ;; dependencies would require <graph-backend> to include a separator between + ;; nodes and edges. + "") + +(define %cyclonedx-backend + (graph-backend "cyclonedx-json" + "Generate an SBOM in CycloneDX JSON format for use with dependencytrack." + emit-cyclonedx-prologue emit-cyclonedx-epilogue + emit-cyclonedx-node emit-cyclonedx-edge)) + + +;;; ;;; d3js export. ;;; @@ -375,7 +445,8 @@ nodeArray.push(nodes[\"~a\"]);~%" (list %graphviz-backend %d3js-backend %cypher-backend - %graphml-backend)) + %graphml-backend + %cyclonedx-backend)) (define (lookup-backend name) "Return the graph backend called NAME. Raise an error if it is not found." |
