Skip to content

Add SoftwareVersion::Rpm comparing versions with rpmvercmp semantics#31

Open
jinxka wants to merge 1 commit into
Cyberwatch:masterfrom
jinxka:issue_737
Open

Add SoftwareVersion::Rpm comparing versions with rpmvercmp semantics#31
jinxka wants to merge 1 commit into
Cyberwatch:masterfrom
jinxka:issue_737

Conversation

@jinxka

@jinxka jinxka commented Jul 3, 2026

Copy link
Copy Markdown

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.

# 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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est ce que fait RPM mais pas sur de si on veut vraiment garder ce comportement la.

# 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

@jinxka jinxka Jul 3, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
@jinxka jinxka marked this pull request as ready for review July 3, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant