Repository navigation
Conversation
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
|
Validated with the following test data: All scenarios use this sbom:
supplier: "Organization: ExampleCo"
namespace: "https://sbom.example"
One small nit: the |
|
Can you also please squash both of the commits since the second one just fixes the indentation of the header? |
Derive the default source purl from the resolved package, while preserving explicit upstream purls. Document the configuration migration and cover name, type, namespace, and global type overrides. Co-Authored-By: Hermes Agent <hermes-agent@nousresearch.com> Closes: python-wheel-build#1383 Signed-off-by: Emre K <110906681+kocaemre@users.noreply.github.com>
3522bfb to
dba98b3
Compare
|
Thanks for checking the scenarios. I changed |
|
I re-tested this on top of current A few small non-blocking suggestions:
|
EmilienM
left a comment
There was a problem hiding this comment.
Needs a human read: 5 minor (4 inline, 1 below)
The purl derivation itself is correct and matches the design agreed in #1383; all findings are docs and test polish. Flagging for a human verdict because this is a deep-tier review of a contributor's change to SBOM output.
Outside the diff:
- Minor:
src/fromager/packagesettings/_models.py:123, therepository_urldocstring still says the qualifier is added to "every purl", but the upstream entry never carries it, the opposite of the wheel-only scoping this PR applies topurl_typeright above it.
How this was reviewed
- Commit
dba98b3, round 1 - Deep review, because the change alters SBOM purl generation in
src/fromager/sbom.pyandsrc/fromager/packagesettings/_models.py - Passes: architecture, performance, security, scalability, then correctness
- Independent skeptics checked each candidate finding (1); 1 of 1 held up
- Repo rules read from
main: AGENTS.md, CLAUDE.md, CONTRIBUTING.md - Not covered: nothing skipped
| purl_type = pc.type if pc else None | ||
| purl_namespace = pc.namespace if pc else None | ||
| purl_name = pc.name if pc else None | ||
| return PackageURL( |
There was a problem hiding this comment.
Minor: When purl.type/namespace/name are set without purl.upstream, the upstream entry now changes to pkg:pypi/... with nothing in the logs to say the overrides stopped applying. A warning here would tell operators who don't read release notes:
pc = pbi.purl_config
if pc and pc.upstream:
return PackageURL.from_string(pc.upstream)
+ if pc and (pc.type or pc.namespace or pc.name):
+ logger.warning(
+ "ignoring purl type/namespace/name overrides for the upstream"
+ " identity of %s; set purl.upstream to describe a non-PyPI source",
+ name,
+ )
return PackageURL(| When absent, the upstream purl keeps the downstream name, type, and | ||
| namespace but uses the resolved source version instead of a local | ||
| downstream version override. The ``repository_url`` qualifier is omitted. | ||
| When absent, the upstream purl is ``pkg:pypi/<package name>@<resolved |
There was a problem hiding this comment.
Minor: This is a user-facing semantics change, so both edited docstrings should carry a .. versionchanged:: marker like the rest of the codebase does (downloads.py, wheels.py); next release is 0.103.0. Same for the purl_type docstring above at :118.
|
|
||
| When ``purl.upstream`` is absent, the upstream SBOM entry identifies the | ||
| resolved source as ``pkg:pypi/<package name>@<resolved version>``. The | ||
| per-package ``purl.name``, ``purl.type``, and ``purl.namespace`` settings and |
There was a problem hiding this comment.
Minor: purl.version is also wheel-only (since #1377), and the purl.upstream docstring added in this PR lists all four overrides, so the two docs disagree on the list:
| per-package ``purl.name``, ``purl.type``, and ``purl.namespace`` settings and | |
| per-package ``purl.name``, ``purl.type``, ``purl.namespace``, and | |
| ``purl.version`` settings and |
| [ | ||
| ({"name": "test-pkg-corp"}, "pypi", "pkg:pypi/test-pkg-corp@0.5.5"), | ||
| ({"type": "generic"}, "pypi", "pkg:generic/test-pkg@0.5.5"), | ||
| ({"namespace": "acme"}, "pypi", "pkg:pypi/acme/test-pkg@0.5.5"), |
There was a problem hiding this comment.
Minor: pypi purls take no namespace (the purl spec, and #1383 says so too), so this case locks a spec-invalid string in as expected output. Pairing the namespace with type: generic keeps the coverage without the invalid purl:
| ({"namespace": "acme"}, "pypi", "pkg:pypi/acme/test-pkg@0.5.5"), | |
| ( | |
| {"namespace": "acme", "type": "generic"}, | |
| "pypi", | |
| "pkg:generic/acme/test-pkg@0.5.5", | |
| ), |
Co-Authored-By: Hermes Agent <hermes-agent@nousresearch.com> Signed-off-by: Emre K <110906681+kocaemre@users.noreply.github.com>
|
Thanks for re-testing and the suggestion. I added the upstream SPDX |
Pull Request Description
What
purl.upstreamstill takes precedence.SbomSettings.purl_typeapplies to wheel package entries.Why
Closes #1383. Previously the
GENERATED_FROMentry could identify a downstream-renamed wheel rather than the resolved PyPI source. This changes existing SBOM output for users overriding purl type/name/namespace withoutpurl.upstream; set that field explicitly for a different source.Verification
RED:
uvx --from hatch hatch run test:test tests/test_sbom.py::test_generate_sbom_upstream_ignores_wheel_purl_overrides -q --no-cov --tb=short→ 4 expected upstream identity assertion failures (original test-first cycle).Follow-up RED: deterministic docstring assertion failed while
SbomSettings.purl_typesaid “all packages”; GREEN: same check passed after making it wheel-only.GREEN:
uvx --from hatch hatch run test:test tests/test_sbom.py tests/test_packagesettings.py -q --no-cov --tb=short→ 112 passed.Reviewer follow-up RED (temporary wrong upstream name, restored before commit):
uvx --from hatch hatch run test:test tests/test_sbom.py::test_generate_sbom_upstream_ignores_wheel_purl_overrides -q --no-cov --tb=short→ 1 expected failure (test-pkg-corpvstest-pkg); GREEN: same command → 4 passed, and the two-file suite → 112 passed.uvx --from hatch hatch run lint:check,uvx --from hatch hatch run mypy:check tests/test_sbom.py,git diff --checkpassed.uvx --from hatch hatch run lint:check→ passed;uvx --from hatch hatch run mypy:check src/fromager/sbom.py src/fromager/packagesettings/_models.py tests/test_sbom.py→ 77 source, 51 test, 7 e2e files checked, no issues.uvx --from hatch hatch run docs:build→ build succeeded;git diff --check HEAD~1..HEAD→ passed. Full suite/e2e not run locally (repo guidance favors file-scoped tests for small changes). The original two signed-off commits, including the Sphinx heading correction, were squashed into one signed-off commit at maintainer request; CI is rerunning for the new head.Significant AI assistance: Hermes Agent co-authored the patch; test failures and passing checks were run locally.