• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.github/workflows/H23-Nov-2020-2726

.gitignoreH A D23-Nov-20206 11

.golangci.ymlH A D23-Nov-2020337 2724

CHANGELOG.mdH A D23-Nov-20205.5 KiB195119

MakefileH A D23-Nov-2020972 3728

README.mdH A D23-Nov-202010 KiB245189

benchmark_test.goH A D23-Nov-20205 KiB248199

collection.goH A D23-Nov-2020729 2511

collection_test.goH A D23-Nov-2020589 4738

constraints.goH A D23-Nov-202015.4 KiB569382

constraints_test.goH A D23-Nov-202019.1 KiB667603

doc.goH A D23-Nov-20206.8 KiB1851

fuzz.goH A D23-Nov-2020515 238

go.modH A D23-Nov-202049 42

version.goH A D23-Nov-202015 KiB607397

version_test.goH A D23-Nov-202013.6 KiB618562

README.md

1# SemVer
2
3The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to:
4
5* Parse semantic versions
6* Sort semantic versions
7* Check if a semantic version fits within a set of constraints
8* Optionally work with a `v` prefix
9
10[![Stability:
11Active](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html)
12[![](https://github.com/Masterminds/semver/workflows/Tests/badge.svg)](https://github.com/Masterminds/semver/actions)
13[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/Masterminds/semver/v3)
14[![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/semver)](https://goreportcard.com/report/github.com/Masterminds/semver)
15
16If you are looking for a command line tool for version comparisons please see
17[vert](https://github.com/Masterminds/vert) which uses this library.
18
19## Package Versions
20
21There are three major versions fo the `semver` package.
22
23* 3.x.x is the new stable and active version. This version is focused on constraint
24  compatibility for range handling in other tools from other languages. It has
25  a similar API to the v1 releases. The development of this version is on the master
26  branch. The documentation for this version is below.
27* 2.x was developed primarily for [dep](https://github.com/golang/dep). There are
28  no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer).
29  There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x).
30* 1.x.x is the most widely used version with numerous tagged releases. This is the
31  previous stable and is still maintained for bug fixes. The development, to fix
32  bugs, occurs on the release-1 branch. You can read the documentation [here](https://github.com/Masterminds/semver/blob/release-1/README.md).
33
34## Parsing Semantic Versions
35
36There are two functions that can parse semantic versions. The `StrictNewVersion`
37function only parses valid version 2 semantic versions as outlined in the
38specification. The `NewVersion` function attempts to coerce a version into a
39semantic version and parse it. For example, if there is a leading v or a version
40listed without all 3 parts (e.g. `v1.2`) it will attempt to coerce it into a valid
41semantic version (e.g., 1.2.0). In both cases a `Version` object is returned
42that can be sorted, compared, and used in constraints.
43
44When parsing a version an error is returned if there is an issue parsing the
45version. For example,
46
47    v, err := semver.NewVersion("1.2.3-beta.1+build345")
48
49The version object has methods to get the parts of the version, compare it to
50other versions, convert the version back into a string, and get the original
51string. Getting the original string is useful if the semantic version was coerced
52into a valid form.
53
54## Sorting Semantic Versions
55
56A set of versions can be sorted using the `sort` package from the standard library.
57For example,
58
59```go
60raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
61vs := make([]*semver.Version, len(raw))
62for i, r := range raw {
63    v, err := semver.NewVersion(r)
64    if err != nil {
65        t.Errorf("Error parsing version: %s", err)
66    }
67
68    vs[i] = v
69}
70
71sort.Sort(semver.Collection(vs))
72```
73
74## Checking Version Constraints
75
76There are two methods for comparing versions. One uses comparison methods on
77`Version` instances and the other uses `Constraints`. There are some important
78differences to notes between these two methods of comparison.
79
801. When two versions are compared using functions such as `Compare`, `LessThan`,
81   and others it will follow the specification and always include prereleases
82   within the comparison. It will provide an answer that is valid with the
83   comparison section of the spec at https://semver.org/#spec-item-11
842. When constraint checking is used for checks or validation it will follow a
85   different set of rules that are common for ranges with tools like npm/js
86   and Rust/Cargo. This includes considering prereleases to be invalid if the
87   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.
893. Constraint ranges can have some complex rules including the shorthand use of
90   ~ and ^. For more details on those see the options below.
91
92There are differences between the two methods or checking versions because the
93comparison methods on `Version` follow the specification while comparison ranges
94are not part of the specification. Different packages and tools have taken it
95upon themselves to come up with range rules. This has resulted in differences.
96For example, npm/js and Cargo/Rust follow similar patterns while PHP has a
97different pattern for ^. The comparison features in this package follow the
98npm/js and Cargo/Rust lead because applications using it have followed similar
99patters with their versions.
100
101Checking a version against version constraints is one of the most featureful
102parts of the package.
103
104```go
105c, err := semver.NewConstraint(">= 1.2.3")
106if err != nil {
107    // Handle constraint not being parsable.
108}
109
110v, err := semver.NewVersion("1.3")
111if err != nil {
112    // Handle version not being parsable.
113}
114// Check if the version meets the constraints. The a variable will be true.
115a := c.Check(v)
116```
117
118### Basic Comparisons
119
120There are two elements to the comparisons. First, a comparison string is a list
121of space or comma separated AND comparisons. These are then separated by || (OR)
122comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a
123comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
124greater than or equal to 4.2.3.
125
126The basic comparisons are:
127
128* `=`: equal (aliased to no operator)
129* `!=`: not equal
130* `>`: greater than
131* `<`: less than
132* `>=`: greater than or equal to
133* `<=`: less than or equal to
134
135### Working With Prerelease Versions
136
137Pre-releases, for those not familiar with them, are used for software releases
138prior to stable or generally available releases. Examples of prereleases include
139development, alpha, beta, and release candidate releases. A prerelease may be
140a version such as `1.2.3-beta.1` while the stable release would be `1.2.3`. In the
141order of precedence, prereleases come before their associated releases. In this
142example `1.2.3-beta.1 < 1.2.3`.
143
144According to the Semantic Version specification prereleases may not be
145API compliant with their release counterpart. It says,
146
147> 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.
148
149SemVer comparisons using constraints without a prerelease comparator will skip
150prerelease versions. For example, `>=1.2.3` will skip prereleases when looking
151at a list of releases while `>=1.2.3-0` will evaluate and find prereleases.
152
153The reason for the `0` as a pre-release version in the example comparison is
154because pre-releases can only contain ASCII alphanumerics and hyphens (along with
155`.` separators), per the spec. Sorting happens in ASCII sort order, again per the
156spec. The lowest character is a `0` in ASCII sort order
157(see an [ASCII Table](http://www.asciitable.com/))
158
159Understanding ASCII sort ordering is important because A-Z comes before a-z. That
160means `>=1.2.3-BETA` will return `1.2.3-alpha`. What you might expect from case
161sensitivity doesn't apply here. This is due to ASCII sort ordering which is what
162the spec specifies.
163
164### Hyphen Range Comparisons
165
166There are multiple methods to handle ranges and the first is hyphens ranges.
167These look like:
168
169* `1.2 - 1.4.5` which is equivalent to `>= 1.2 <= 1.4.5`
170* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5`
171
172### Wildcards In Comparisons
173
174The `x`, `X`, and `*` characters can be used as a wildcard character. This works
175for all comparison operators. When used on the `=` operator it falls
176back to the patch level comparison (see tilde below). For example,
177
178* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
179* `>= 1.2.x` is equivalent to `>= 1.2.0`
180* `<= 2.x` is equivalent to `< 3`
181* `*` is equivalent to `>= 0.0.0`
182
183### Tilde Range Comparisons (Patch)
184
185The tilde (`~`) comparison operator is for patch level ranges when a minor
186version is specified and major level changes when the minor number is missing.
187For example,
188
189* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
190* `~1` is equivalent to `>= 1, < 2`
191* `~2.3` is equivalent to `>= 2.3, < 2.4`
192* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
193* `~1.x` is equivalent to `>= 1, < 2`
194
195### Caret Range Comparisons (Major)
196
197The caret (`^`) comparison operator is for major level changes once a stable
198(1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts
199as the API stability level. This is useful when comparisons of API versions as a
200major change is API breaking. For example,
201
202* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
203* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
204* `^2.3` is equivalent to `>= 2.3, < 3`
205* `^2.x` is equivalent to `>= 2.0.0, < 3`
206* `^0.2.3` is equivalent to `>=0.2.3 <0.3.0`
207* `^0.2` is equivalent to `>=0.2.0 <0.3.0`
208* `^0.0.3` is equivalent to `>=0.0.3 <0.0.4`
209* `^0.0` is equivalent to `>=0.0.0 <0.1.0`
210* `^0` is equivalent to `>=0.0.0 <1.0.0`
211
212## Validation
213
214In addition to testing a version against a constraint, a version can be validated
215against a constraint. When validation fails a slice of errors containing why a
216version didn't meet the constraint is returned. For example,
217
218```go
219c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
220if err != nil {
221    // Handle constraint not being parseable.
222}
223
224v, err := semver.NewVersion("1.3")
225if err != nil {
226    // Handle version not being parseable.
227}
228
229// Validate a version against a constraint.
230a, msgs := c.Validate(v)
231// a is false
232for _, m := range msgs {
233    fmt.Println(m)
234
235    // Loops over the errors which would read
236    // "1.3 is greater than 1.2.3"
237    // "1.3 is less than 1.4"
238}
239```
240
241## Contribute
242
243If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
244or [create a pull request](https://github.com/Masterminds/semver/pulls).
245