-
Notifications
You must be signed in to change notification settings - Fork 86
Add support PEP 770 (SBOMs) #843
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
fangchenli
wants to merge
15
commits into
mesonbuild:main
Choose a base branch
from
fangchenli:feat/distinfo-placeholder
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 14 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
c6d89a1
Route {py_distinfo} placeholder to wheel .dist-info/<subdir>/
fangchenli 739b0fb
Extend .dist-info/ collision check to cover license-files
fangchenli ded08d9
Also check license-files collisions in editable wheels
fangchenli c4b09ba
Use neutral subdir name in dist-info-sboms test fixture
fangchenli b365ecb
Drop {py_distinfo} placeholder; detect dist-info prefix in install paths
fangchenli a384103
Detect dist-info prefix under platlib too, not only purelib
fangchenli 9cec754
Update changelog entry to reflect platlib support
fangchenli 372f344
Polish SBOMs how-to for consistency with the rest of docs/
fangchenli ec05306
Trim changelog entry to match neighbor style
fangchenli 38c25dd
Inline the license-file collision check, drop the _record closure
fangchenli a9b4286
Simplify docstrings and comments
fangchenli bc3c11f
Deduplicate the purelib/platlib branch check
fangchenli b24415b
Clarify where the SBOM generator script lives
fangchenli f32ed4f
Fix pre-commit failures: ruff import spacing + SPDX sidecars
fangchenli 2aac893
update doc
fangchenli File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| .. SPDX-FileCopyrightText: 2026 The meson-python developers | ||
| .. | ||
| .. SPDX-License-Identifier: MIT | ||
|
|
||
| .. _how-to-guides-sboms: | ||
|
|
||
| *********************************** | ||
| Including SBOMs in wheels (PEP 770) | ||
| *********************************** | ||
|
|
||
| `PEP 770`_ defines a location for Software Bill of Materials (SBOM) | ||
| files inside the wheel's ``.dist-info/sboms/`` directory. | ||
| ``meson-python`` routes any file installed under | ||
| ``{py_purelib}/<name>-<version>.dist-info/<subdir>/...`` or | ||
| ``{py_platlib}/<name>-<version>.dist-info/<subdir>/...`` into the | ||
| wheel's own ``.dist-info/<subdir>/`` at pack time, giving projects a | ||
| way to ship SBOMs and other dist-info-bound metadata files without | ||
| post-build wheel surgery. | ||
|
|
||
| .. _PEP 770: https://peps.python.org/pep-0770/ | ||
|
|
||
| Static SBOM files | ||
| ================= | ||
|
|
||
| For SBOMs that are checked into the source tree, typically describing | ||
| source-vendored components: | ||
|
|
||
| .. code-block:: meson | ||
|
|
||
| project('my-project', 'c', version: '1.0.0') | ||
|
|
||
| py = import('python').find_installation(pure: false) | ||
| distinfo = meson.project_name() + '-' + meson.project_version() + '.dist-info' | ||
|
|
||
| install_data( | ||
| 'sboms/component1.cdx.json', | ||
| 'sboms/component2.cdx.json', | ||
| install_dir: py.get_install_dir() / distinfo / 'sboms', | ||
| ) | ||
|
|
||
| The files end up in the wheel at | ||
| ``my_project-1.0.0.dist-info/sboms/component1.cdx.json`` and | ||
| ``component2.cdx.json``. ``py.get_install_dir()`` returns a path under | ||
| ``{py_purelib}`` for ``pure: true`` projects and ``{py_platlib}`` for | ||
| ``pure: false`` projects; both roots are recognized. | ||
|
|
||
| Dynamically generated SBOMs | ||
| =========================== | ||
|
|
||
| When the SBOM is generated at build time, use a ``custom_target`` that | ||
| writes the file and installs it to the same location: | ||
|
|
||
| .. code-block:: meson | ||
|
|
||
| custom_target('vendored-sbom', | ||
| output: 'vendored.cdx.json', | ||
| command: [py, files('scripts/generate_sbom.py'), '@OUTPUT@', | ||
| '--version', meson.project_version()], | ||
| install: true, | ||
| install_dir: py.get_install_dir() / distinfo / 'sboms', | ||
| ) | ||
|
|
||
| The generator runs during the build, and the output is routed into | ||
| ``my_project-1.0.0.dist-info/sboms/vendored.cdx.json``. | ||
|
|
||
| The generator is provided by the project; ``meson-python`` does not | ||
| ship one. It can be a script checked into the source tree | ||
| (``scripts/`` is a common convention) or a third-party generator | ||
| installed via ``[build-system] requires``. For guidance on generator | ||
| implementations and the SBOM format itself, see the PSF | ||
| `SBOMs for Python packages`_ proposal. | ||
|
|
||
| Other ``.dist-info`` subdirectories | ||
| =================================== | ||
|
|
||
| Any subdirectory works the same way. Additional PEP 639 license files, | ||
| for example, can go under ``licenses``: | ||
|
|
||
| .. code-block:: meson | ||
|
|
||
| install_data('LICENSES/extra.txt', | ||
| install_dir: py.get_install_dir() / distinfo / 'licenses') | ||
|
|
||
| License files declared via ``project.license-files`` in | ||
| ``pyproject.toml`` are already placed in ``.dist-info/licenses/`` | ||
| automatically and do not need a ``meson.build`` entry. Use the pattern | ||
| above only for additional files outside the standard | ||
| ``project.license-files`` list. | ||
|
|
||
| File naming and validation | ||
| ========================== | ||
|
|
||
| * Files installed under ``<name>-<version>.dist-info/<subdir>/`` must | ||
| have unique basenames within their subdirectory. ``meson-python`` | ||
| raises a ``BuildError`` at build time if two files would write to | ||
| the same path, including collisions between files routed through | ||
| this mechanism and files written from ``project.license-files``. | ||
| * The ``<name>-<version>.dist-info`` directory name is matched | ||
| canonically, so hyphens and underscores in the user's project name | ||
| do not break routing. | ||
| * Recommended file extensions are ``.cdx.json`` for CycloneDX and | ||
| ``.spdx.json`` for SPDX, per the PSF | ||
| `SBOMs for Python packages`_ proposal. | ||
|
|
||
| .. _SBOMs for Python packages: https://github.com/psf/sboms-for-python-packages | ||
|
|
||
| Editable installs | ||
| ================= | ||
|
|
||
| Files staged via this mechanism are only placed in non-editable wheels | ||
| (``pip install .`` or ``python -m build``). Editable wheels | ||
| (``pip install -e .``) redirect imports to the build directory and do | ||
| not carry dist-info-bound payloads. Since SBOMs are distribution | ||
| artifacts, this limitation does not affect development workflows. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Top-level LICENSE.txt referenced by project.license-files in pyproject.toml. |
2 changes: 2 additions & 0 deletions
2
tests/packages/dist-info-sboms-collision/duplicate/LICENSE.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Second LICENSE.txt routed via py.dist_info_install_dir('licenses'). | ||
| Colliding basename should trigger a BuildError. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # SPDX-FileCopyrightText: 2026 The meson-python developers | ||
| # | ||
| # SPDX-License-Identifier: MIT | ||
|
|
||
| project('dist-info-sboms-collision', version: '1.0.0') | ||
|
|
||
| py = import('python').find_installation() | ||
|
|
||
| distinfo = meson.project_name() + '-' + meson.project_version() + '.dist-info' | ||
|
|
||
| # This install_data targets the same wheel path as the PEP 639 | ||
| # license-files entry in pyproject.toml (.dist-info/licenses/LICENSE.txt). | ||
| # meson-python should surface the collision as a BuildError rather than | ||
| # silently clobber. | ||
| install_data('duplicate/LICENSE.txt', | ||
| install_dir: py.get_install_dir() / distinfo / 'licenses') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # SPDX-FileCopyrightText: 2026 The meson-python developers | ||
| # | ||
| # SPDX-License-Identifier: MIT | ||
|
|
||
| [build-system] | ||
| build-backend = 'mesonpy' | ||
| requires = ['meson-python'] | ||
|
|
||
| [project] | ||
| name = 'dist-info-sboms-collision' | ||
| version = '1.0.0' | ||
| license = 'MIT' | ||
| license-files = ['LICENSE.txt'] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # SPDX-FileCopyrightText: 2026 The meson-python developers | ||
| # | ||
| # SPDX-License-Identifier: MIT | ||
|
|
||
| project('dist-info-sboms-platlib', version: '1.0.0') | ||
|
|
||
| # pure: false exercises the platlib routing path. Projects shipping | ||
| # C extensions (pandas, numpy, scipy) all use this; the distinfo | ||
| # prefix detection must work for both purelib and platlib roots. | ||
| py = import('python').find_installation(pure: false) | ||
|
|
||
| distinfo = meson.project_name() + '-' + meson.project_version() + '.dist-info' | ||
|
|
||
| install_data('sboms/static.cdx.json', | ||
| install_dir: py.get_install_dir() / distinfo / 'sboms') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # SPDX-FileCopyrightText: 2026 The meson-python developers | ||
| # | ||
| # SPDX-License-Identifier: MIT | ||
|
|
||
| [build-system] | ||
| build-backend = 'mesonpy' | ||
| requires = ['meson-python'] | ||
|
|
||
| [project] | ||
| name = 'dist-info-sboms-platlib' | ||
| version = '1.0.0' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "$schema": "https://cyclonedx.org/schema/bom-1.6.schema.json", | ||
| "bomFormat": "CycloneDX", | ||
| "specVersion": "1.6", | ||
| "version": 1, | ||
| "components": [] | ||
| } |
3 changes: 3 additions & 0 deletions
3
tests/packages/dist-info-sboms-platlib/sboms/static.cdx.json.license
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # SPDX-FileCopyrightText: 2026 The meson-python developers | ||
| # | ||
| # SPDX-License-Identifier: MIT |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # SPDX-FileCopyrightText: 2026 The meson-python developers | ||
| # | ||
| # SPDX-License-Identifier: MIT | ||
|
|
||
| """Trivial SBOM generator for the dist-info-sboms test package.""" | ||
|
|
||
| import json | ||
| import sys | ||
|
|
||
|
|
||
| with open(sys.argv[1], 'w') as f: | ||
| json.dump({ | ||
| 'bomFormat': 'CycloneDX', | ||
| 'specVersion': '1.6', | ||
| 'version': 1, | ||
| 'components': [], | ||
| }, f) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.