Skip to content

Instantly share code, notes, and snippets.

@johngrimes
Created May 8, 2025 06:37
Show Gist options
  • Save johngrimes/13e765c88bad7cd17a5b9af811c807e4 to your computer and use it in GitHub Desktop.
Save johngrimes/13e765c88bad7cd17a5b9af811c807e4 to your computer and use it in GitHub Desktop.
Human-readable CycloneDX SBOM
#!/usr/bin/env python3
"""
Read a CycloneDX 1.4 *JSON* BOM from stdin and print one line per component:
<name>@<version> – <license1>, <license2>, …
Usage:
python3 cyclonedx-deps-json.py < bom.json
"""
import json
import sys
def licenses(comp):
"""Return a list of licence identifiers/names for a component."""
out = []
for l in comp.get("licenses", []):
if "license" in l: # structured licence object
lic = l["license"]
out.append(lic.get("id") or lic.get("name", ""))
elif "expression" in l: # SPDX expression string
out.append(l["expression"])
return [x for x in out if x]
def main():
try:
bom = json.load(sys.stdin)
except json.JSONDecodeError as e:
sys.exit(f"Invalid JSON BOM: {e}")
for c in bom.get("components", []):
name = c.get("name", "UNKNOWN")
version = c.get("version") or ""
label = f"{name}{'@'+version if version else ''}"
lic_txt = ", ".join(licenses(c)) or "No licence information"
print(f"{label} – {lic_txt}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment