fix(alpine,hackage): keep constraints out of PURL names and encode components - #1352
Merged
Merged
Conversation
…mponents An apk dependency token carries its constraint inline — `musl>=1.2.0`, `busybox=1.36.1-r5`, `zlib~1.3` — so it is not a package name. Treating it as one put the constraint inside the PURL, which re-parses to a name of `musl>=1.2.0`, and on the installed-db path left the constraint recorded nowhere else at all. Split the token: the name identifies the package, the full token becomes the declared requirement. A bare name keeps no requirement, since that would only repeat the identity the PURL already carries. hackage takes its name from a free-text `.cabal` field, where a `/` would be read back as a namespace separator — prohibited for that type, so the PURL does not parse at all. Both now build through the shared encoders. One golden line changes: the apk archive fixture's `pkg:apk/alpine/musl>=1.2.0` becomes `pkg:apk/alpine/musl`, with the constraint already present in its `extracted_requirement`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Maxim Stykow <maxim.stykow@gmail.com>
Greptile SummaryThe PR corrects Alpine dependency identities by separating inline constraints from package names and routes Alpine and Hackage PURLs through shared component encoders.
Confidence Score: 5/5The PR appears safe to merge with no concrete blocking or non-blocking defects identified. The changed parsers preserve dependency requirements while producing component-encoded PURLs, and the investigated edge cases did not establish a realistic reachable regression.
|
| Filename | Overview |
|---|---|
| src/parsers/alpine.rs | Splits inline APK constraints from dependency identities and consistently encodes Alpine source and dependency PURLs. |
| src/parsers/hackage.rs | Replaces direct Hackage PURL formatting with the shared component-aware encoder across dependency paths. |
| src/parsers/hackage_test.rs | Verifies that slash-containing Hackage names are encoded, parse successfully, and round-trip without becoming namespaces. |
| testdata/alpine/apk/basic/test-package-1.0-r0.apk.expected.json | Updates the expected Alpine dependency identity while preserving its declared requirement. |
Reviews (1): Last reviewed commit: "fix(alpine,hackage): keep constraints ou..." | Re-trigger Greptile
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
musl>=1.2.0,busybox=1.36.1-r5,zlib~1.3— so it is not a package name. Treating it as one put the constraint inside the PURL:pkg:apk/alpine/musl>=1.2.0re-parses to a name ofmusl>=1.2.0, and this form ships in a golden today.extracted_requirementwas left null, so the version requirement was recorded nowhere usable..cabalfield. A/there is read back as a namespace separator, which hackage prohibits — so the PURL does not parse at all.Scope and exclusions
D:muslkeepsextracted_requirementunset — repeating the identity the PURL already carries would be noise, and "prefer honest unknowns" applies: there is no version requirement to record.How to verify
Before:
{"purl": "pkg:apk/alpine/musl>=1.2.0", ...}. After:{"purl": "pkg:apk/alpine/musl", "extracted_requirement": "musl>=1.2.0"}.For hackage, a
.cabalwithname: ns/pkggavepkg:hackage/ns/pkg@2.0(rejected by any PURL parser) and now givespkg:hackage/ns%2Fpkg@2.0, which decodes back to the literal name.Intentional differences from Python
Expected-output fixture changes
testdata/alpine/apk/basic/test-package-1.0-r0.apk.expected.json, one line.pkg:apk/alpine/musl>=1.2.0was never a valid identity — the PURL name is the package, and>=1.2.0is a constraint. The same entry already carried"extracted_requirement": "musl>=1.2.0", so the constraint is not lost; it simply stops being part of the package's identity. No other fixture moves, including the alpine assembly golden, whose fixture declares a bareD:musl.