Skip to content

Commit

Permalink
fix!: prereleases should not match constraints for previous versions.
Browse files Browse the repository at this point in the history
Signed-off-by: i4k <[email protected]>
  • Loading branch information
i4ki committed May 20, 2024
1 parent 7867235 commit 4d99533
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 4 deletions.
28 changes: 26 additions & 2 deletions versions/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,32 @@ func Match(version, constraint string, allowPrereleases bool) (bool, error) {
return false, errors.E(ErrCheck, "invalid constraint", err)
}

allowed := versions.MeetingConstraintsExact(spec)
return allowed.Has(semver), nil
// Prereleases for an upcoming breaking change MUST NOT match the previous release.
// In other words, Semantic Version defines the order below:
// 0.9.9 < 1.0.0-alpha < 1.0.0 < 1.0.1
// But we want the behavior below:
//
// If the constraint does not specify a prerelease, then it will never match

var plainConstraints, rcConstraints constraints.IntersectionSpec
for _, sel := range spec {
if sel.Boundary.Prerelease != "" {
rcConstraints = append(rcConstraints, sel)
} else {
plainConstraints = append(plainConstraints, sel)
}
}

plainAllowed := versions.MeetingConstraintsExact(plainConstraints)
copied := semver
copied.Prerelease = ""
has := plainAllowed.Has(copied)
if !has {
return false, nil
}

rcAllowed := versions.MeetingConstraintsExact(rcConstraints)
return rcAllowed.Has(semver), nil
}

spec, err := hclversion.NewConstraint(constraint)
Expand Down
59 changes: 57 additions & 2 deletions versions/versions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,18 @@ func TestTerramateVersionConstraints(t *testing.T) {
constraint: "> 1.2.2, < 1.2.3",
want: errors.E(versions.ErrCheck),
},
{
version: "1.2.3-alpha",
constraint: "> 1.2.2, < 1.2.3",
prereleases: true,
want: errors.E(versions.ErrCheck),
},
{
version: "1.2.3-alpha",
constraint: "~> 1.2.2",
prereleases: true,
//want: errors.E(versions.ErrCheck),
},
{
version: "1.2.3-dev",
constraint: ">= 1.2.3",
Expand All @@ -201,12 +213,12 @@ func TestTerramateVersionConstraints(t *testing.T) {
version: "1.2.3-dev",
constraint: ">= 1.2.3",
prereleases: true,
want: errors.E(versions.ErrCheck),
},
{
version: "1.2.3-dev",
constraint: "< 1.2.3",
prereleases: true,
want: errors.E(versions.ErrCheck),
},
{
version: "1.2.3-dev",
Expand Down Expand Up @@ -308,11 +320,54 @@ func TestTerramateVersionConstraints(t *testing.T) {
constraint: "< 1.2.3-dev2",
prereleases: true,
},
{
version: "0.6.0-rc1",
constraint: "~> 0.5.0",
want: errors.E(versions.ErrCheck),
},
{
version: "0.6.0-rc1",
constraint: "~> 0.5.0",
prereleases: true,
want: errors.E(versions.ErrCheck),
},
{
version: "0.6.0-rc1",
constraint: "~> 0.6.0-rc1",
},
{
version: "0.6.0-rc1",
constraint: "~> 0.6.0-rc1",
prereleases: true,
},
{
version: "0.6.0-rc1",
constraint: "~> 0.5.0",
want: errors.E(versions.ErrCheck),
},
{
version: "2.0.0-alpha",
constraint: "~> 1",
prereleases: true,
want: errors.E(versions.ErrCheck),
},
{
version: "1.0.0-alpha",
constraint: "< 2",
prereleases: true,
},
// TODO(i4k): review this with Marius.
// looks broken.
{
version: "1.0.0-alpha",
constraint: "< 1.0.0",
prereleases: true,
want: errors.E(versions.ErrCheck),
},
} {
tc := tc
name := fmt.Sprintf("CheckVersionFor(%q,%q, %t)", tc.version, tc.constraint, tc.prereleases)
t.Run(name, func(t *testing.T) {
t.Parallel()
err := versions.Check(tc.version, tc.constraint, tc.prereleases)
errtest.Assert(t, err, tc.want, "error mismatch")
})
Expand Down

0 comments on commit 4d99533

Please sign in to comment.