From 2c6ca44a0b2ccebcdbb78200747704b260bfe037 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Mon, 13 Apr 2026 19:54:16 +0100 Subject: [PATCH 1/4] Generate an SBOM --- templates/sbom.cdx.json.in | 38 ++++++++++++++++++++++++++++++++++++++ update.py | 9 +++++++++ 2 files changed, 47 insertions(+) create mode 100644 templates/sbom.cdx.json.in diff --git a/templates/sbom.cdx.json.in b/templates/sbom.cdx.json.in new file mode 100644 index 0000000..1648d8b --- /dev/null +++ b/templates/sbom.cdx.json.in @@ -0,0 +1,38 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json", + "version": 1, + "bomFormat": "CycloneDX", + "specVersion": "1.7", + "metadata": { + "component": { + "bom-ref": "pkg:pypi/tzdata@%%PACKAGE_VERSION%%", + "name": "tzdata", + "version": "%%PACKAGE_VERSION%%", + "purl": "pkg:pypi/tzdata@%%PACKAGE_VERSION%%", + "type": "library", + "components": [ + { + "bom-ref": "https://www.iana.org/time-zones", + "name": "tz", + "version": "%%IANA_VERSION%%", + "type": "data", + "data": [ + { + "type": "dataset", + "name": "IANA Time Zone Database", + "description": "zic-compiled TZif timezone files" + } + ], + "licenses": [ + { + "license": { + "name": "tz database license", + "url": "https://data.iana.org/time-zones/tz-link.html" + } + } + ] + } + ] + } + } +} diff --git a/update.py b/update.py index 5090cdc..c90fbce 100644 --- a/update.py +++ b/update.py @@ -196,6 +196,15 @@ def create_package(version: str, zonenames: Sequence[str], zoneinfo_dir: pathlib with open(target_dir / "__init__.py", "w") as f_out: f_out.write(contents) + # Generate the SBOM from a template. + with open(TEMPLATES_DIR / "sbom.cdx.json.in", "r") as f_in: + contents = f_in.read() + contents = contents.replace("%%PACKAGE_VERSION%%", package_version) + contents = contents.replace("%%IANA_VERSION%%", version) + + with open(REPO_ROOT / "sbom.cdx.json", "w") as f_out: + f_out.write(contents) + with open(REPO_ROOT / "VERSION", "w") as f: f.write(package_version) From 191791a6d17ab965c0d0a760845e84e91d75230f Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Thu, 16 Apr 2026 18:12:49 +0100 Subject: [PATCH 2/4] Use an override in `setup.py` instead --- setup.py | 28 ++++++++++++++++++++++++++++ update.py | 9 --------- 2 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 setup.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..c1ed4d7 --- /dev/null +++ b/setup.py @@ -0,0 +1,28 @@ +import re +from pathlib import Path + +from setuptools import setup +from wheel.bdist_wheel import bdist_wheel as _bdist_wheel + +ROOT = Path(__file__).parent + + +def generate_sbom(): + version = (ROOT / "VERSION").read_text().strip() + init_text = (ROOT / "src" / "tzdata" / "__init__.py").read_text() + iana_version = re.search(r'IANA_VERSION\s*=\s*"([^"]+)"', init_text).group(1) + template = (ROOT / "templates" / "sbom.cdx.json.in").read_text() + return template.replace("%%PACKAGE_VERSION%%", version).replace( + "%%IANA_VERSION%%", iana_version + ) + + +class bdist_wheel(_bdist_wheel): + def write_wheelfile(self, wheelfile_base, *args, **kwargs): + super().write_wheelfile(wheelfile_base, *args, **kwargs) + (Path(wheelfile_base) / "sboms").mkdir(exist_ok=True) + (Path(wheelfile_base) / "sboms" / "sbom.cdx.json").write_text(generate_sbom()) + + +cmdclass = {"bdist_wheel": bdist_wheel} +setup(cmdclass=cmdclass) diff --git a/update.py b/update.py index c90fbce..5090cdc 100644 --- a/update.py +++ b/update.py @@ -196,15 +196,6 @@ def create_package(version: str, zonenames: Sequence[str], zoneinfo_dir: pathlib with open(target_dir / "__init__.py", "w") as f_out: f_out.write(contents) - # Generate the SBOM from a template. - with open(TEMPLATES_DIR / "sbom.cdx.json.in", "r") as f_in: - contents = f_in.read() - contents = contents.replace("%%PACKAGE_VERSION%%", package_version) - contents = contents.replace("%%IANA_VERSION%%", version) - - with open(REPO_ROOT / "sbom.cdx.json", "w") as f_out: - f_out.write(contents) - with open(REPO_ROOT / "VERSION", "w") as f: f.write(package_version) From 6fa1e33ec6f0b4840f566d1f57be906abdcc91b8 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Thu, 16 Apr 2026 18:19:40 +0100 Subject: [PATCH 3/4] Use `os` instead :-( --- setup.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/setup.py b/setup.py index c1ed4d7..611c2f9 100644 --- a/setup.py +++ b/setup.py @@ -1,17 +1,20 @@ +import os import re -from pathlib import Path from setuptools import setup from wheel.bdist_wheel import bdist_wheel as _bdist_wheel -ROOT = Path(__file__).parent +ROOT = os.path.dirname(os.path.abspath(__file__)) def generate_sbom(): - version = (ROOT / "VERSION").read_text().strip() - init_text = (ROOT / "src" / "tzdata" / "__init__.py").read_text() + with open(os.path.join(ROOT, "VERSION")) as f: + version = f.read().strip() + with open(os.path.join(ROOT, "src", "tzdata", "__init__.py")) as f: + init_text = f.read() iana_version = re.search(r'IANA_VERSION\s*=\s*"([^"]+)"', init_text).group(1) - template = (ROOT / "templates" / "sbom.cdx.json.in").read_text() + with open(os.path.join(ROOT, "templates", "sbom.cdx.json.in")) as f: + template = f.read() return template.replace("%%PACKAGE_VERSION%%", version).replace( "%%IANA_VERSION%%", iana_version ) @@ -19,9 +22,12 @@ def generate_sbom(): class bdist_wheel(_bdist_wheel): def write_wheelfile(self, wheelfile_base, *args, **kwargs): - super().write_wheelfile(wheelfile_base, *args, **kwargs) - (Path(wheelfile_base) / "sboms").mkdir(exist_ok=True) - (Path(wheelfile_base) / "sboms" / "sbom.cdx.json").write_text(generate_sbom()) + super(bdist_wheel, self).write_wheelfile(wheelfile_base, *args, **kwargs) + sboms_dir = os.path.join(wheelfile_base, "sboms") + if not os.path.isdir(sboms_dir): + os.makedirs(sboms_dir) + with open(os.path.join(sboms_dir, "sbom.cdx.json"), "w") as f: + f.write(generate_sbom()) cmdclass = {"bdist_wheel": bdist_wheel} From 0900609e0be499f3baa8439226b64ee24a51c273 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Thu, 16 Apr 2026 18:22:53 +0100 Subject: [PATCH 4/4] Can't have anything, there goes my `super()`... --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 611c2f9..10c14e3 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ def generate_sbom(): class bdist_wheel(_bdist_wheel): def write_wheelfile(self, wheelfile_base, *args, **kwargs): - super(bdist_wheel, self).write_wheelfile(wheelfile_base, *args, **kwargs) + _bdist_wheel.write_wheelfile(self, wheelfile_base, *args, **kwargs) sboms_dir = os.path.join(wheelfile_base, "sboms") if not os.path.isdir(sboms_dir): os.makedirs(sboms_dir)