Skip to content

feat(version): match constraints with DLoad's own version ordering - #150

Merged
roxblnfk merged 3 commits into
1.xfrom
fix/exact-prerelease
Oct 12, 2026
Merged

roxblnfk merged 3 commits into
1.xfrom
fix/exact-prerelease

Conversation

@roxblnfk

@roxblnfk roxblnfk commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

What was changed

  • Version constraints are matched by DLoad's own code (feat(version): match version constraints with DLoad's own ordering #155) instead of composer/semver, so matching and release sorting share one order. The Composer syntax keeps its meaning; hyphen ranges, !=/<>, a v prefix and constraints with five or more number parts now work too, and a malformed constraint fails when parsed. composer/semver moves to require-dev, where a test compares the two.
  • Pre-releases: a constraint with a numbered pre-release matches that release (3.5.0-beta.1, ^2025.1.0-rc.1), pre-releases sort by stability then number (rc.1 after beta.10), a pre-release in a constraint sets the minimum stability for any operator, and a bare keyword in a range is a bound (>2.0-beta takes 2.0.0).
  • An exact version with a pre-release or a suffix matches only that tag (2.0-beta, 2.12.0-hotfix); a bare number still covers every build of its number.
  • Versions: every dotted part counts (1.2.3.4 is a stable release), trailing zero parts and SemVer build metadata (+build.5) are ignored, stability keywords are read only as whole words (-arm64 is not alpha, A word starting with a stability letter is read as a pre-release (-arm64 is alpha) #153), 1.1.1b is a patch letter, suffixes compare token by token regardless of case, and a pre-release glued to the number (2.0.0rc1) is read in tags and constraints alike.
  • A binary's version is read with every dotted part and shown whole, pre-release and build metadata included.

Why?

Constraint took beta.1 for a feature suffix while Version read it as a stability, so an exact pre-release matched nothing (roadrunner-php/cli#49, VersionSelectionTest::installsExactPreRelease). Fixing it on top of composer/semver meant bending versions to its parser — four number parts at most, its own pre-release order — which left matching and sorting disagreeing.

Review notes

  • A bound without a pre-release covers every build of its number, as in Composer: >=3.5.0-beta.1 <3.5.0 is empty; write <3.5.0-RC1.
  • Odd tags (1.0-arm64-beta.1) can be pinned exactly; ranges over them carry no guarantees.

Checklist

@github-actions github-actions Bot added bug Something isn't working tests labels Oct 10, 2026
@codecov

codecov Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
src/Module/Binary/BinaryVersion.php 100.00% <100.00%> (ø)
src/Module/Binary/Internal/AbstractBinary.php 17.24% <100.00%> (ø)
...odule/Repository/Collection/ReleasesCollection.php 100.00% <100.00%> (ø)
src/Module/Version/Comparison.php 100.00% <100.00%> (ø)
src/Module/Version/Constraint.php 100.00% <100.00%> (+7.31%) ⬆️
src/Module/Version/Operator.php 100.00% <100.00%> (ø)
src/Module/Version/PreRelease.php 100.00% <100.00%> (ø)
src/Module/Version/Range.php 100.00% <100.00%> (ø)
src/Module/Version/Version.php 100.00% <100.00%> (+6.52%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@roxblnfk
roxblnfk force-pushed the fix/exact-prerelease branch 2 times, most recently from 785e255 to 3b5003d Compare October 10, 2026 16:19
@roxblnfk
roxblnfk added this pull request to stack #157 October 11, 2026 16:00
@roxblnfk
roxblnfk removed this pull request from stack #157 October 11, 2026 17:48
@roxblnfk roxblnfk changed the title fix(version): match a constraint with a numbered pre-release feat(version): match constraints with DLoad's own version ordering Oct 12, 2026
fix(repository): sort pre-releases by stability weight and number
docs: show pre-release constraints

A constraint like `3.5.0-beta.1` took `beta.1` for a feature suffix, which no parsed version carries, so it matched nothing. A pre-release is now a stability with its number, ordered by the same `Stability` weights the minimum-stability filter uses, so every stability keyword works, `beta.1` matches neither `beta.2` nor the final release, and ranges like `^3.5.0-beta.1` work. Sorting releases uses the same order, which also fixes spellings like `rc.1` that the old string replacement missed.

Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
)

feat(version): support hyphen ranges, `!=`/`<>`, a `v` prefix and constraints with five or more number parts
fix(version): read a version number with every dotted part, so `1.2.3.4` is a stable release, not a preview of `1.2.3`
fix(version): ignore trailing zero parts when comparing versions
fix(version): read a stability keyword only as a whole word, so `-arm64` or `-build.5` is not alpha or beta, and `1.1.1b` is a patch letter
fix(version): match an exact version with a pre-release or suffix as that one tag
fix(version): read a bare stability keyword in a range as a bound, so `>2.0-beta` takes `2.0.0`
fix(version): read a pre-release glued to the number of a constraint, like `^2.0.0rc1`, as a pre-release
fix(version): match a feature suffix in any case
fix(binary): read every dotted part of the version a binary prints

Constraints are matched by DLoad's own code instead of composer/semver, so
matching and release sorting share one order. The Composer syntax keeps its
meaning; a malformed constraint now fails when parsed. A pre-release in a
constraint sets the minimum stability for any operator, and a tail after it
orders right after it. composer/semver moves to require-dev.

Closes #153
Closes #154

Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
…158)

fix(version): accept build metadata like `+build.5` in constraints again, as 1.18.0 did, and after a pre-release
fix(version): read `+…` on a tag as build metadata, so `1.2.3+beta` is a stable `1.2.3`
fix(binary): show the whole version a binary prints, with its pre-release and build metadata

Build metadata follows the SemVer grammar on tags, binary output and constraints, and never changes order, stability or matching. Version numbers compare part by part as digit strings, so parts too long for an integer no longer compare equal.

Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
@roxblnfk
roxblnfk force-pushed the fix/exact-prerelease branch from fc7655f to aefa834 Compare October 12, 2026 07:20
@roxblnfk
roxblnfk merged commit 0bb33e1 into 1.x Oct 12, 2026
22 checks passed
@roxblnfk
roxblnfk deleted the fix/exact-prerelease branch October 12, 2026 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working tests

Projects

None yet

1 participant