1 /* 2 Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go. 3 4 Specifically it provides the ability to: 5 6 - Parse semantic versions 7 - Sort semantic versions 8 - Check if a semantic version fits within a set of constraints 9 - Optionally work with a `v` prefix 10 11 # Parsing Semantic Versions 12 13 There are two functions that can parse semantic versions. The `StrictNewVersion` 14 function only parses valid version 2 semantic versions as outlined in the 15 specification. The `NewVersion` function attempts to coerce a version into a 16 semantic version and parse it. For example, if there is a leading v or a version 17 listed without all 3 parts (e.g. 1.2) it will attempt to coerce it into a valid 18 semantic version (e.g., 1.2.0). In both cases a `Version` object is returned 19 that can be sorted, compared, and used in constraints. 20 21 When parsing a version an optional error can be returned if there is an issue 22 parsing the version. For example, 23 24 v, err := semver.NewVersion("1.2.3-beta.1+b345") 25 26 The version object has methods to get the parts of the version, compare it to 27 other versions, convert the version back into a string, and get the original 28 string. For more details please see the documentation 29 at https://godoc.org/github.com/Masterminds/semver. 30 31 # Sorting Semantic Versions 32 33 A set of versions can be sorted using the `sort` package from the standard library. 34 For example, 35 36 raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} 37 vs := make([]*semver.Version, len(raw)) 38 for i, r := range raw { 39 v, err := semver.NewVersion(r) 40 if err != nil { 41 t.Errorf("Error parsing version: %s", err) 42 } 43 44 vs[i] = v 45 } 46 47 sort.Sort(semver.Collection(vs)) 48 49 # Checking Version Constraints and Comparing Versions 50 51 There are two methods for comparing versions. One uses comparison methods on 52 `Version` instances and the other is using Constraints. There are some important 53 differences to notes between these two methods of comparison. 54 55 1. When two versions are compared using functions such as `Compare`, `LessThan`, 56 and others it will follow the specification and always include prereleases 57 within the comparison. It will provide an answer valid with the comparison 58 spec section at https://semver.org/#spec-item-11 59 2. When constraint checking is used for checks or validation it will follow a 60 different set of rules that are common for ranges with tools like npm/js 61 and Rust/Cargo. This includes considering prereleases to be invalid if the 62 ranges does not include on. If you want to have it include pre-releases a 63 simple solution is to include `-0` in your range. 64 3. Constraint ranges can have some complex rules including the shorthard use of 65 ~ and ^. For more details on those see the options below. 66 67 There are differences between the two methods or checking versions because the 68 comparison methods on `Version` follow the specification while comparison ranges 69 are not part of the specification. Different packages and tools have taken it 70 upon themselves to come up with range rules. This has resulted in differences. 71 For example, npm/js and Cargo/Rust follow similar patterns which PHP has a 72 different pattern for ^. The comparison features in this package follow the 73 npm/js and Cargo/Rust lead because applications using it have followed similar 74 patters with their versions. 75 76 Checking a version against version constraints is one of the most featureful 77 parts of the package. 78 79 c, err := semver.NewConstraint(">= 1.2.3") 80 if err != nil { 81 // Handle constraint not being parsable. 82 } 83 84 v, err := semver.NewVersion("1.3") 85 if err != nil { 86 // Handle version not being parsable. 87 } 88 // Check if the version meets the constraints. The a variable will be true. 89 a := c.Check(v) 90 91 # Basic Comparisons 92 93 There are two elements to the comparisons. First, a comparison string is a list 94 of comma or space separated AND comparisons. These are then separated by || (OR) 95 comparisons. For example, `">= 1.2 < 3.0.0 || >= 4.2.3"` is looking for a 96 comparison that's greater than or equal to 1.2 and less than 3.0.0 or is 97 greater than or equal to 4.2.3. This can also be written as 98 `">= 1.2, < 3.0.0 || >= 4.2.3"` 99 100 The basic comparisons are: 101 102 - `=`: equal (aliased to no operator) 103 - `!=`: not equal 104 - `>`: greater than 105 - `<`: less than 106 - `>=`: greater than or equal to 107 - `<=`: less than or equal to 108 109 # Hyphen Range Comparisons 110 111 There are multiple methods to handle ranges and the first is hyphens ranges. 112 These look like: 113 114 - `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` 115 - `2.3.4 - 4.5` which is equivalent to `>= 2.3.4 <= 4.5` 116 117 # Wildcards In Comparisons 118 119 The `x`, `X`, and `*` characters can be used as a wildcard character. This works 120 for all comparison operators. When used on the `=` operator it falls 121 back to the tilde operation. For example, 122 123 - `1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` 124 - `>= 1.2.x` is equivalent to `>= 1.2.0` 125 - `<= 2.x` is equivalent to `<= 3` 126 - `*` is equivalent to `>= 0.0.0` 127 128 Tilde Range Comparisons (Patch) 129 130 The tilde (`~`) comparison operator is for patch level ranges when a minor 131 version is specified and major level changes when the minor number is missing. 132 For example, 133 134 - `~1.2.3` is equivalent to `>= 1.2.3 < 1.3.0` 135 - `~1` is equivalent to `>= 1, < 2` 136 - `~2.3` is equivalent to `>= 2.3 < 2.4` 137 - `~1.2.x` is equivalent to `>= 1.2.0 < 1.3.0` 138 - `~1.x` is equivalent to `>= 1 < 2` 139 140 Caret Range Comparisons (Major) 141 142 The caret (`^`) comparison operator is for major level changes once a stable 143 (1.0.0) release has occurred. Prior to a 1.0.0 release the minor versions acts 144 as the API stability level. This is useful when comparisons of API versions as a 145 major change is API breaking. For example, 146 147 - `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` 148 - `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` 149 - `^2.3` is equivalent to `>= 2.3, < 3` 150 - `^2.x` is equivalent to `>= 2.0.0, < 3` 151 - `^0.2.3` is equivalent to `>=0.2.3 <0.3.0` 152 - `^0.2` is equivalent to `>=0.2.0 <0.3.0` 153 - `^0.0.3` is equivalent to `>=0.0.3 <0.0.4` 154 - `^0.0` is equivalent to `>=0.0.0 <0.1.0` 155 - `^0` is equivalent to `>=0.0.0 <1.0.0` 156 157 # Validation 158 159 In addition to testing a version against a constraint, a version can be validated 160 against a constraint. When validation fails a slice of errors containing why a 161 version didn't meet the constraint is returned. For example, 162 163 c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") 164 if err != nil { 165 // Handle constraint not being parseable. 166 } 167 168 v, _ := semver.NewVersion("1.3") 169 if err != nil { 170 // Handle version not being parseable. 171 } 172 173 // Validate a version against a constraint. 174 a, msgs := c.Validate(v) 175 // a is false 176 for _, m := range msgs { 177 fmt.Println(m) 178 179 // Loops over the errors which would read 180 // "1.3 is greater than 1.2.3" 181 // "1.3 is less than 1.4" 182 } 183 */ 184 package semver 185