Skip to content

Support tildes, carets, hyphens, wildcards, etc #54

@jmorrell

Description

@jmorrell

👋 Hi there!

tl;dr - I forked your (very good!) library. Are you interested in upstreaming the changes?

I'm in the unenviable position of needing to migrate a Node server that uses node-semver to golang without breaking any user who is currently relying on the logic in the Node library. Currently there is no equivalent semver library for Go that supports the range of inputs that the Node library does. Some examples:

~>1.2.x
^1.2.0
^10.14.1 || ^8.15.0
8 - 10
~7.x || ~8.x || ~9.x
~10.1.x
1.* || >=2.0.* <2.2.*
etc

To that end, I basically translated the (regex heavy) logic from the Node library directly and added it as a pre-processing step that normalizes the above input into the >=1.2.3 <2.0.0 type ranges that your library expects.

Changes here: master...jmorrell:master

I'm happy to either clean up these changes and upstream them into your library, or fork and support as a separate semver library for those who need these other features and something that is compatible with Node's semver library. Or I can maintain my fork separately if you are not interested.

Downsides:

  • Lots of regex, which your library has avoided
  • Parsing is substantially slower as a result

Benchmark after changes:

$ go test -v -bench .
...
goos: darwin
goarch: amd64
pkg: github.com/jmorrell/semver
BenchmarkRangeParseSimple-8                 1000           1332107 ns/op         1155055 B/op       9163 allocs/op
BenchmarkRangeParseAverage-8                1000           1325482 ns/op         1163610 B/op       9283 allocs/op
BenchmarkRangeParseComplex-8                 300           3933910 ns/op         3485886 B/op      27792 allocs/op
BenchmarkRangeMatchSimple-8             100000000               12.7 ns/op             0 B/op          0 allocs/op
BenchmarkRangeMatchAverage-8            50000000                26.7 ns/op             0 B/op          0 allocs/op
BenchmarkRangeMatchComplex-8            20000000                73.2 ns/op             0 B/op          0 allocs/op
BenchmarkParseSimple-8                  10000000               162 ns/op              48 B/op          1 allocs/op
BenchmarkParseComplex-8                  2000000               826 ns/op             256 B/op          7 allocs/op
BenchmarkParseAverage-8                  3000000               537 ns/op             163 B/op          4 allocs/op
BenchmarkParseTolerantAverage-8          5000000               356 ns/op             101 B/op          3 allocs/op
BenchmarkStringSimple-8                 30000000                38.1 ns/op             5 B/op          1 allocs/op
BenchmarkStringLarger-8                 20000000                83.0 ns/op            32 B/op          2 allocs/op
BenchmarkStringComplex-8                10000000               127 ns/op              80 B/op          3 allocs/op
BenchmarkStringAverage-8                20000000               107 ns/op              47 B/op          2 allocs/op
BenchmarkValidateSimple-8               500000000                3.41 ns/op            0 B/op          0 allocs/op
BenchmarkValidateComplex-8               5000000               259 ns/op               0 B/op          0 allocs/op
BenchmarkValidateAverage-8              10000000               141 ns/op               0 B/op          0 allocs/op
BenchmarkCompareSimple-8                300000000                4.22 ns/op            0 B/op          0 allocs/op
BenchmarkCompareComplex-8               100000000               16.4 ns/op             0 B/op          0 allocs/op
BenchmarkCompareAverage-8               100000000               22.1 ns/op             0 B/op          0 allocs/op
BenchmarkSort-8                         10000000               184 ns/op             256 B/op          2 allocs/op

Your repo on master on the same machine:

$ go test -v -bench .
...
goos: darwin
goarch: amd64
pkg: github.com/blang/semver
BenchmarkRangeParseSimple-8              3000000               553 ns/op             240 B/op          7 allocs/op
BenchmarkRangeParseAverage-8             1000000              1058 ns/op             480 B/op         13 allocs/op
BenchmarkRangeParseComplex-8              500000              3309 ns/op            1792 B/op         39 allocs/op
BenchmarkRangeMatchSimple-8             100000000               12.0 ns/op             0 B/op          0 allocs/op
BenchmarkRangeMatchAverage-8            50000000                26.1 ns/op             0 B/op          0 allocs/op
BenchmarkRangeMatchComplex-8            20000000                75.3 ns/op             0 B/op          0 allocs/op
BenchmarkParseSimple-8                  10000000               172 ns/op              48 B/op          1 allocs/op
BenchmarkParseComplex-8                  2000000               762 ns/op             256 B/op          7 allocs/op
BenchmarkParseAverage-8                  3000000               561 ns/op             163 B/op          4 allocs/op
BenchmarkParseTolerantAverage-8          5000000               359 ns/op             101 B/op          3 allocs/op
BenchmarkStringSimple-8                 50000000                37.7 ns/op             5 B/op          1 allocs/op
BenchmarkStringLarger-8                 20000000                79.3 ns/op            32 B/op          2 allocs/op
BenchmarkStringComplex-8                10000000               120 ns/op              80 B/op          3 allocs/op
BenchmarkStringAverage-8                20000000               103 ns/op              47 B/op          2 allocs/op
BenchmarkValidateSimple-8               500000000                3.38 ns/op            0 B/op          0 allocs/op
BenchmarkValidateComplex-8              10000000               191 ns/op               0 B/op          0 allocs/op
BenchmarkValidateAverage-8              20000000               113 ns/op               0 B/op          0 allocs/op
BenchmarkCompareSimple-8                300000000                4.21 ns/op            0 B/op          0 allocs/op
BenchmarkCompareComplex-8               100000000               17.5 ns/op             0 B/op          0 allocs/op
BenchmarkCompareAverage-8               100000000               21.7 ns/op             0 B/op          0 allocs/op
BenchmarkSort-8                         10000000               175 ns/op             256 B/op          2 allocs/op

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions