Masterminds / semver

Work with Semantic Versions in Go
MIT License
1.2k stars 149 forks source link

strict version check constraint bug (or expected?) #242

Open Diliz opened 3 months ago

Diliz commented 3 months ago

Hello!

I actually saw that the version constraint sometimes does not work as expected, as you can see here: https://go.dev/play/p/u1nq3v1-SiS

I got the following versions:

"1.0.0",
"1.0.0-beta.2"
"1.0.0-beta.1"
"1.0.0-alpha.2"
"1.0.0-alpha.1"
"1.0.0+toto.1"

here is a usable snippet:

    versions := []string{
        "1.0.0",
        "1.0.0-beta.2",
        "1.0.0-beta.1",
        "1.0.0-alpha.2",
        "1.0.0-alpha.1",
        "1.0.0+toto.1",
    }
    c, _ := semver.NewConstraint("= 1.0.0")
    for _, vs := range versions {
        v, _ := semver.NewVersion(vs)
        fmt.Println(v, c.Check(v))
    }

What I got:

1.0.0 true
1.0.0-beta.2 false
1.0.0-beta.1 false
1.0.0-alpha.2 false
1.0.0-alpha.1 false
1.0.0+toto.1 true

What I was expecting:

1.0.0 true
1.0.0-beta.2 false
1.0.0-beta.1 false
1.0.0-alpha.2 false
1.0.0-alpha.1 false
1.0.0+toto.1 false

If this was the expected behaviour:

mattfarina commented 1 month ago

Please see the documentation on working with pre-releases as it explains the behavior you are seeing.

Many tools and libraries in this space require you to opt-in to using pre-releases. They do this out of experience in this space as pre-releases may (and sometimes) are not compatible with the stable release guarantees. The constraint needs to opt-in to pre-releases. You'll find the same behavior in other places like JavaScript and Rust.

Diliz commented 1 month ago

For what is documented in the semver:

<valid semver> ::= <version core>
                 | <version core> "-" <pre-release>
                 | <version core> "+" <build>
                 | <version core> "-" <pre-release> "+" <build>

What about this one:

<valid semver> ::= <version core> "+" <build>

How to identify builds from releases without build in it? Which have the exact same issue here.

mattfarina commented 1 month ago

I will start with build metadata. The spec says...

Build metadata MUST be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence.

When comparing versions they are considered the same.

On pre-releases the spec states...

A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version.

In the past, this library did not opt-in for pre-releases and that caused problems. Many other tools opt-in to pre-releases.

Just because pre-release is a valid semver does not mean comparison systems MUST handle them along stable release versions by default. There is no spec for filtering tooling.