-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathutils.go
97 lines (75 loc) · 2.14 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package api
import (
"fmt"
"regexp"
"strings"
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/i18n"
"github.com/Masterminds/semver"
)
const (
ConstraintAllVersions = "*"
)
var coercableSemver = regexp.MustCompile(`^\d+(\.\d+)?$`)
type SemverConstraintInvalidError struct {
Constraint string
Err error
}
func (e SemverConstraintInvalidError) Error() string {
return i18n.T("Version constraint {{.Constraint}} is invalid:\n",
map[string]interface{}{"Constraint": e.Constraint}) + e.Err.Error()
}
type SemverConstraint interface {
Satisfied(string) bool
IsRange() bool
fmt.Stringer
}
func NewSemverConstraint(versionOrRange string) (SemverConstraint, error) {
versionOrRange = strings.TrimPrefix(versionOrRange, "v")
versionOrRange = coerce(versionOrRange)
if _, err := semver.NewVersion(versionOrRange); err == nil {
return semverVersion(versionOrRange), nil
}
constraints, err := semver.NewConstraint(versionOrRange)
if err != nil {
return nil, SemverConstraintInvalidError{Constraint: versionOrRange, Err: err}
}
return semverRange{repr: versionOrRange, constraints: constraints}, nil
}
type semverVersion string
func (v semverVersion) Satisfied(version string) bool {
return strings.EqualFold(string(v), version)
}
func (v semverVersion) IsRange() bool {
return false
}
func (v semverVersion) String() string {
return string(v)
}
type semverRange struct {
repr string // user-provided string representation
constraints *semver.Constraints
}
func (r semverRange) Satisfied(version string) bool {
sv, err := semver.NewVersion(version)
if err != nil {
return false
}
return r.constraints.Check(sv)
}
func (r semverRange) IsRange() bool {
return true
}
func (r semverRange) String() string {
return r.repr
}
// coerce takes an incomplete semver range (e.g. '1' or '1.2') and turns them into a valid constraint. github.com/mastermind/semver's
// default behavior will fill any a missing minor/patch with 0's, so we bypass that to create ranges; e.g.
//
// '1' -> '1.x'
// '1.2' -> '1.2.x'
func coerce(semverRange string) string {
if !coercableSemver.MatchString(semverRange) {
return semverRange
}
return semverRange + ".x"
}