From 2ea7866e3b10a7ea813d9f5eaf0d5181f4364c49 Mon Sep 17 00:00:00 2001 From: Louis Seubert Date: Sat, 11 Jul 2026 21:57:12 +0200 Subject: [PATCH] fix: range exact/non-equal matches ignore build metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build metadata does not affect precedence (SemVer 2.0.0 §10), so the Eq and Neq constraints now use SemanticVersionComparer.Priority instead of the structural == operator. This makes [1.2.3] match 1.2.3+build, consistent with precedence semantics. Add a failing-then-passing test. --- CHANGELOG.md | 1 + src/semver.tests/SemanticVersionRangeTests.cs | 9 +++++++++ src/semver/SemanticVersionRange.cs | 6 ++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1784b3..32f4f5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Fixed - Reject invalid SemVer identifiers when parsing versions. +- Range exact and non-equal comparators ignore build metadata when matching versions. ### Removed diff --git a/src/semver.tests/SemanticVersionRangeTests.cs b/src/semver.tests/SemanticVersionRangeTests.cs index 2fb4c13..5bc065f 100644 --- a/src/semver.tests/SemanticVersionRangeTests.cs +++ b/src/semver.tests/SemanticVersionRangeTests.cs @@ -248,6 +248,15 @@ internal sealed class SemanticVersionRangeTests await Assert.That(new string(destination[..charsWritten])).IsEqualTo("^1.2.3"); } + [Test] + public async Task I_can_match_exact_range_ignoring_build_metadata() + { + var range = SemanticVersionRange.Parse("[1.2.3]"); + + await Assert.That(range.Contains(SemanticVersion.Parse("1.2.3+build.7"))).IsTrue(); + await Assert.That(range.Contains(SemanticVersion.Parse("1.2.4"))).IsFalse(); + } + [Test] public async Task I_fail_formatting_when_the_tentative_short_form_overflows() { diff --git a/src/semver/SemanticVersionRange.cs b/src/semver/SemanticVersionRange.cs index 3e56048..fa1ee37 100644 --- a/src/semver/SemanticVersionRange.cs +++ b/src/semver/SemanticVersionRange.cs @@ -50,8 +50,10 @@ internal readonly struct Constraint { return Operation switch { - Comparison.Eq => v == Version, - Comparison.Neq => v != Version, + // Build metadata does not affect precedence (SemVer 2.0.0 §10), so exact + // and non-equal comparisons on the version part ignore it. + Comparison.Eq => SemanticVersionComparer.Priority.Equals(v, Version), + Comparison.Neq => !SemanticVersionComparer.Priority.Equals(v, Version), Comparison.Lt => v < Version, Comparison.Lte => v <= Version, Comparison.Gt => v > Version,