Skip to content

Match version constraints with DLoad's own comparison instead of composer/semver #154

Closed

Description

@roxblnfk

Description

DLoad orders releases with its own Version::compare() but matches version constraints with composer/semver (Semver::satisfies() in Constraint). The two disagree, and Composer's parser sets limits DLoad's versions no longer have:

  • VersionParser::normalize() reads at most four number parts and a major part of at most five digits (unless it reads as a date). A constraint with five or more parts, like >=1.2.3.4.5 or ^1.2.3.4.5-beta.1, throws a parse error.
  • Versions are pushed through workarounds to fit: a number with five or more parts is passed as a Composer patch (1.2.3.4.5 → 1.2.3.4-p5), and a version Composer cannot read (20250101.1.2.3) is caught and treated as not matching (both from feat(version): match constraints with DLoad's own version ordering #150).
  • Composer has its own stability and pre-release order (patch, -p, dev- branches), while DLoad orders pre-releases by its Stability weights, then the pre-release number, then the tail. So the pre-release part of a constraint is decided by DLoad's code and the number part by Composer's.

Proposed solution

Match constraints with DLoad's own code on top of Version::compare(), so sorting and matching share one ordering:

  • Parse the constraint syntax that works today: the operators =, ==, ^, ~, >=, >, <, <=, @stability, numbered pre-releases and feature suffixes, plus whatever Composer syntax currently reaches Semver::satisfies() intact (wildcards, ||, AND) — check which forms survive Constraint's own parsing before deciding what to keep.
  • Turn every constraint into lower and upper bounds and compare a version against them with Version::compare(): any count of number parts on both sides, trailing zeros ignored, pre-releases and tails ordered as in sorting.
  • Drop composerNumber(), the unreadable-version catch and, if nothing else needs it, the composer/semver dependency.

Existing constraints must keep their meaning: cover the edge cases of ^0.x, ~1.2 versus ~1.2.3, wildcards and ranges with tests that compare against Composer's results.

Additional context

Activity

  1. added 2 commits that reference this issue on Oct 11, 2026
    ca5f07b
    8905861
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions