Skip to content

Commit 68dfa87

Browse files
committed
Allow pre-releases when the range uses them
Currently, when a range uses a pre-release, such as 1.0.0-alpha.1 - 1.1.0, all pre-release versions are being rejected when the constraint is checked because the upper part of the range does include a pre-release. For example, 1.0.0-alpha.2 should match that range, but it is rejected right now. I have updated how we evaluate constraints so that it checks whether a constraint part uses pre-releases OR the larger constraint range that it is part of uses a pre-release. When either part of a range uses a pre-release, the entire range should allow pre-release versions. Fixes Masterminds#177 Signed-off-by: Carolyn Van Slyck <[email protected]>
1 parent 1d45b76 commit 68dfa87

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ differences to notes between these two methods of comparison.
8585
different set of rules that are common for ranges with tools like npm/js
8686
and Rust/Cargo. This includes considering prereleases to be invalid if the
8787
ranges does not include one. If you want to have it include pre-releases a
88-
simple solution is to include `-0` in your range.
88+
simple solution is to include `-0` in your range. For example, `~1.2.3-0` or
89+
`1.2.3-0 - 1.5.0`.
8990
3. Constraint ranges can have some complex rules including the shorthand use of
9091
~ and ^. For more details on those see the options below.
9192

constraints.go

+28-5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ func NewConstraint(c string) (*Constraints, error) {
3232
return nil, fmt.Errorf("improper constraint: %s", v)
3333
}
3434

35+
// If any part of the range uses a pre-release,
36+
// then allow pre-release versions to match when the range is checked.
37+
var rangeUsesPrerelease bool
38+
3539
cs := findConstraintRegex.FindAllString(v, -1)
3640
if cs == nil {
3741
cs = append(cs, v)
@@ -44,7 +48,21 @@ func NewConstraint(c string) (*Constraints, error) {
4448
}
4549

4650
result[i] = pc
51+
52+
// Check if the range uses a pre-release
53+
if !rangeUsesPrerelease && pc.con.Prerelease() != "" {
54+
rangeUsesPrerelease = true
55+
}
4756
}
57+
58+
if rangeUsesPrerelease {
59+
// If any part of the range used a pre-release,
60+
// all versions in the range should allow pre-releases
61+
for _, pc := range result {
62+
pc.allowPrerelease = true
63+
}
64+
}
65+
4866
or[k] = result
4967
}
5068

@@ -202,6 +220,10 @@ type constraint struct {
202220
minorDirty bool
203221
dirty bool
204222
patchDirty bool
223+
224+
// allowPrerelease indicates if the constraint should allow pre-releases,
225+
// such as when part of a range constraint that uses pre-releases
226+
allowPrerelease bool
205227
}
206228

207229
// Check if a version meets the constraint
@@ -257,6 +279,7 @@ func parseConstraint(c string) (*constraint, error) {
257279
cs.minorDirty = minorDirty
258280
cs.patchDirty = patchDirty
259281
cs.dirty = dirty
282+
cs.allowPrerelease = cs.con.Prerelease() != ""
260283

261284
return cs, nil
262285
}
@@ -389,7 +412,7 @@ func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) {
389412
// If there is a pre-release on the version but the constraint isn't looking
390413
// for them assume that pre-releases are not compatible. See issue 21 for
391414
// more details.
392-
if v.Prerelease() != "" && c.con.Prerelease() == "" {
415+
if v.Prerelease() != "" && !c.allowPrerelease {
393416
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
394417
}
395418

@@ -404,7 +427,7 @@ func constraintLessThanEqual(v *Version, c *constraint) (bool, error) {
404427
// If there is a pre-release on the version but the constraint isn't looking
405428
// for them assume that pre-releases are not compatible. See issue 21 for
406429
// more details.
407-
if v.Prerelease() != "" && c.con.Prerelease() == "" {
430+
if v.Prerelease() != "" && !c.allowPrerelease {
408431
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
409432
}
410433

@@ -437,7 +460,7 @@ func constraintTilde(v *Version, c *constraint) (bool, error) {
437460
// If there is a pre-release on the version but the constraint isn't looking
438461
// for them assume that pre-releases are not compatible. See issue 21 for
439462
// more details.
440-
if v.Prerelease() != "" && c.con.Prerelease() == "" {
463+
if v.Prerelease() != "" && !c.allowPrerelease {
441464
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
442465
}
443466

@@ -469,7 +492,7 @@ func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) {
469492
// If there is a pre-release on the version but the constraint isn't looking
470493
// for them assume that pre-releases are not compatible. See issue 21 for
471494
// more details.
472-
if v.Prerelease() != "" && c.con.Prerelease() == "" {
495+
if v.Prerelease() != "" && !c.allowPrerelease {
473496
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
474497
}
475498

@@ -498,7 +521,7 @@ func constraintCaret(v *Version, c *constraint) (bool, error) {
498521
// If there is a pre-release on the version but the constraint isn't looking
499522
// for them assume that pre-releases are not compatible. See issue 21 for
500523
// more details.
501-
if v.Prerelease() != "" && c.con.Prerelease() == "" {
524+
if v.Prerelease() != "" && !c.allowPrerelease {
502525
return false, fmt.Errorf("%s is a prerelease version and the constraint is only looking for release versions", v)
503526
}
504527

constraints_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ func TestConstraintsCheck(t *testing.T) {
374374
{"~1.1-alpha", "1.1.1-beta", true},
375375
{"~1.1.1-beta", "1.1.1-alpha", false},
376376
{"~1.1.1-beta", "1.1.1", true},
377+
{constraint: "1.0.0-alpha.1 - 1.0.0", version: "1.0.0-beta.2", check: true},
378+
{constraint: "~1.2.3 || 1.2.3-beta.1", version: "1.2.3-beta.1", check: true},
379+
{constraint: "~1.2.3 || 1.2.3-beta.1", version: "1.2.3-beta.2", check: false},
377380
{"~1.2.3", "1.2.5", true},
378381
{"~1.2.3", "1.2.2", false},
379382
{"~1.2.3", "1.3.2", false},

0 commit comments

Comments
 (0)