Skip to content

Commit

Permalink
Allow pre-releases when the range uses them
Browse files Browse the repository at this point in the history
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 #177

Signed-off-by: Carolyn Van Slyck <me@carolynvanslyck.com>
  • Loading branch information
carolynvs committed Aug 9, 2022
1 parent 1d45b76 commit 68dfa87
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 6 deletions.
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -85,7 +85,8 @@ differences to notes between these two methods of comparison.
different set of rules that are common for ranges with tools like npm/js
and Rust/Cargo. This includes considering prereleases to be invalid if the
ranges does not include one. If you want to have it include pre-releases a
simple solution is to include `-0` in your range.
simple solution is to include `-0` in your range. For example, `~1.2.3-0` or
`1.2.3-0 - 1.5.0`.
3. Constraint ranges can have some complex rules including the shorthand use of
~ and ^. For more details on those see the options below.

Expand Down
33 changes: 28 additions & 5 deletions constraints.go
Expand Up @@ -32,6 +32,10 @@ func NewConstraint(c string) (*Constraints, error) {
return nil, fmt.Errorf("improper constraint: %s", v)
}

// If any part of the range uses a pre-release,
// then allow pre-release versions to match when the range is checked.
var rangeUsesPrerelease bool

cs := findConstraintRegex.FindAllString(v, -1)
if cs == nil {
cs = append(cs, v)
Expand All @@ -44,7 +48,21 @@ func NewConstraint(c string) (*Constraints, error) {
}

result[i] = pc

// Check if the range uses a pre-release
if !rangeUsesPrerelease && pc.con.Prerelease() != "" {
rangeUsesPrerelease = true
}
}

if rangeUsesPrerelease {
// If any part of the range used a pre-release,
// all versions in the range should allow pre-releases
for _, pc := range result {
pc.allowPrerelease = true
}
}

or[k] = result
}

Expand Down Expand Up @@ -202,6 +220,10 @@ type constraint struct {
minorDirty bool
dirty bool
patchDirty bool

// allowPrerelease indicates if the constraint should allow pre-releases,
// such as when part of a range constraint that uses pre-releases
allowPrerelease bool
}

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

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

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

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

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

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

Expand Down
3 changes: 3 additions & 0 deletions constraints_test.go
Expand Up @@ -374,6 +374,9 @@ func TestConstraintsCheck(t *testing.T) {
{"~1.1-alpha", "1.1.1-beta", true},
{"~1.1.1-beta", "1.1.1-alpha", false},
{"~1.1.1-beta", "1.1.1", true},
{constraint: "1.0.0-alpha.1 - 1.0.0", version: "1.0.0-beta.2", check: true},
{constraint: "~1.2.3 || 1.2.3-beta.1", version: "1.2.3-beta.1", check: true},
{constraint: "~1.2.3 || 1.2.3-beta.1", version: "1.2.3-beta.2", check: false},
{"~1.2.3", "1.2.5", true},
{"~1.2.3", "1.2.2", false},
{"~1.2.3", "1.3.2", false},
Expand Down

0 comments on commit 68dfa87

Please sign in to comment.