From 26330fc1552635a5340d3cc755008a03e3ce02af Mon Sep 17 00:00:00 2001 From: Thomas Perale Date: Wed, 24 Jun 2026 12:13:36 +0200 Subject: [PATCH] utils/generate-cyclonedx: move license download in a function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the code that retrieves the SPDX licenses into a function instead of doing it top-level. This allows to pass the CycloneDX version as a function argument instead of defining it as a top-level constant. The next commit introduces support for different CycloneDX spec versions. Signed-off-by: Thomas Perale Reviewed-by: Quentin Schulz Signed-off-by: Arnout Vandecappelle (cherry picked from commit 4ba8e2869bdf86b3fa767a5e49897eb575988255) Signed-off-by: Raphaël Mélotte --- utils/generate-cyclonedx | 60 ++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/utils/generate-cyclonedx b/utils/generate-cyclonedx index 44b9b80847..290c3f96e5 100755 --- a/utils/generate-cyclonedx +++ b/utils/generate-cyclonedx @@ -23,12 +23,10 @@ import re CYCLONEDX_VERSION = "1.6" -SPDX_SCHEMA_URL = f"https://raw.githubusercontent.com/CycloneDX/specification/{CYCLONEDX_VERSION}/schema/spdx.schema.json" brpath = Path(__file__).parent.parent cyclonedxpath = Path(os.getenv("BR2_DL_DIR", brpath / "dl")) / "cyclonedx" -SPDX_SCHEMA_PATH = cyclonedxpath / f"spdx-{CYCLONEDX_VERSION}.schema.json" BR2_VERSION_FULL = ( subprocess.check_output( @@ -45,28 +43,47 @@ VULN_WITH_PEDIGREE = set() SPDX_LICENSES = [] -if not SPDX_SCHEMA_PATH.exists(): - if not importlib.util.find_spec("_ssl"): - print(f"ssl module required for downloading {SPDX_SCHEMA_URL}. Try enabling BR2_PACKAGE_HOST_PYTHON3_SSL.", - file=sys.stderr) - exit(1) - # Download the CycloneDX SPDX schema JSON, and cache it locally - cyclonedxpath.mkdir(parents=True, exist_ok=True) +def br2_retrieve_spdx_licenses(version: str): + """Populate the list of supported SPDX licenses for a given CycloneDX + version. If the list is not present locally it will be downloaded + externally. + + Args: + version (str): CycloneDX version + + Returns: + The SPDX license list supported for the argument version. + """ + SPDX_SCHEMA_URL = f"https://raw.githubusercontent.com/CycloneDX/specification/{version}/schema/spdx.schema.json" + + ret = [] + path = cyclonedxpath / f"spdx-{version}.schema.json" + + if not path.exists(): + # Download the CycloneDX SPDX schema JSON, and cache it locally + if not importlib.util.find_spec("_ssl"): + print(f"ssl module required for downloading {SPDX_SCHEMA_URL}. Try enabling BR2_PACKAGE_HOST_PYTHON3_SSL.", + file=sys.stderr) + exit(1) + + cyclonedxpath.mkdir(parents=True, exist_ok=True) + try: + urllib.request.urlretrieve(SPDX_SCHEMA_URL, path) + except urllib.error.URLError as e: + if "CERTIFICATE_VERIFY_FAILED" in str(e.reason): + raise Exception("Couldn't verify certificate. Try enabling BR2_PACKAGE_HOST_CA_CERTIFICATES.") + raise e + try: - urllib.request.urlretrieve(SPDX_SCHEMA_URL, SPDX_SCHEMA_PATH) - except urllib.error.URLError as e: - if "CERTIFICATE_VERIFY_FAILED" in str(e.reason): - raise Exception("Couldn't verify certificate. Try enabling BR2_PACKAGE_HOST_CA_CERTIFICATES.") - raise e + with path.open() as f: + ret = json.load(f).get("enum", []) + except json.JSONDecodeError: + # In case of error the license will just not be matched to the SPDX names + # but the SBOM generation still work. + print(f"Failed to load the SPDX licenses file: {path}", file=sys.stderr) -try: - with SPDX_SCHEMA_PATH.open() as f: - SPDX_LICENSES = json.load(f).get("enum", []) -except json.JSONDecodeError: - # In case of error the license will just not be matched to the SPDX names - # but the SBOM generation still work. - print(f"Failed to load the SPDX licenses file: {SPDX_SCHEMA_PATH}", file=sys.stderr) + return ret def split_top_level_comma(subj): @@ -528,6 +545,7 @@ def main(): parser.print_help() sys.exit(1) + SPDX_LICENSES.extend(br2_retrieve_spdx_licenses(CYCLONEDX_VERSION)) show_info_dict = json.load(args.in_file) # Remove rootfs and virtual packages if not explicitly included