Add SoftwareVersion::Rpm comparing versions with rpmvercmp semantics#31
Open
jinxka wants to merge 1 commit into
Open
Add SoftwareVersion::Rpm comparing versions with rpmvercmp semantics#31jinxka wants to merge 1 commit into
jinxka wants to merge 1 commit into
Conversation
jinxka
commented
Jul 3, 2026
| # dash, and each part is compared fully before the next one; | ||
| # - words carry no semantic (no pre-version like alpha/rc, no dropped | ||
| # rev/update) and are compared as raw case-sensitive strings; | ||
| # - the number of segments matters: 1.0 > 1, unlike the generic 1.0 = 1. |
Author
There was a problem hiding this comment.
C'est ce que fait RPM mais pas sur de si on veut vraiment garder ce comportement la.
jinxka
commented
Jul 3, 2026
| # separator without semantic value. Words are left raw: rpmvercmp has no | ||
| # special words and compares them as case-sensitive ASCII strings. | ||
| # | ||
| # A trailing '^' keeps the generic "highest version possible" meaning |
Author
There was a problem hiding this comment.
Comportement différent de rpmvercmp mais très utile chez nous.
Les versions de RPM ne se terminent pas naturellement par ^ donc pas de risque de casse.
The generic tokenizer drops '.' but keeps '+' as an ordered token, so modular dist-tags (RHEL 8 lineage) like `module+el8+2468` vs `module+el8.1.0+3366` misalign and compare differently from dnf/rpm. Add a SoftwareVersion::Rpm subclass reusing the generic lexer and token comparison, overriding only what rpm does differently: the string is split into [epoch:]version[-release] on the last dash and compared part by part, every non-alphanumeric character other than '~' and '^' is a mute separator, words carry no semantic and are compared as raw case-sensitive strings, and the number of segments matters (1.0 > 1). To keep the lexer reusable, it no longer downcases words; the generic parse does it instead, with unchanged behavior. One deliberate exception to rpmvercmp: a trailing '^' keeps the generic "highest version possible" meaning so that ranges like `>= 1.0, <= 1.0^` keep matching every 1.0 subversion. Real rpm versions never end with '^', so this costs no fidelity. The new spec/fixtures/rpm_vercmp_sort.txt is rpm_version.txt sorted by the real rpmvercmp (rpm.vercmp, rpm 4.19 in a Fedora container); Rpm reproduces rpm's ordering on all 42366 consecutive pairs. The existing rpm_version_sort.txt intentionally differs from rpmvercmp (1466 inversions) and keeps testing the generic semantics. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
The generic tokenizer drops '.' but keeps '+' as an ordered token, so modular dist-tags (RHEL 8 lineage) like
module+el8+2468vsmodule+el8.1.0+3366misalign and compare differently from dnf/rpm.Add a SoftwareVersion::Rpm subclass reusing the generic lexer and token comparison, overriding only what rpm does differently: the string is split into [epoch:]version[-release] on the last dash and compared part by part, every non-alphanumeric character other than '~' and '^' is a mute separator, words carry no semantic and are compared as raw case-sensitive strings, and the number of segments matters (1.0 > 1). To keep the lexer reusable, it no longer downcases words; the generic parse does it instead, with unchanged behavior.
One deliberate exception to rpmvercmp: a trailing '^' keeps the generic "highest version possible" meaning so that ranges like
>= 1.0, <= 1.0^keep matching every 1.0 subversion. Real rpm versions never end with '^', so this costs no fidelity.The new spec/fixtures/rpm_vercmp_sort.txt is rpm_version.txt sorted by the real rpmvercmp (rpm.vercmp, rpm 4.19 in a Fedora container); Rpm reproduces rpm's ordering on all 42366 consecutive pairs. The existing rpm_version_sort.txt intentionally differs from rpmvercmp (1466 inversions) and keeps testing the generic semantics.