2017-04-20 02:04:09 +02:00
|
|
|
package discovery
|
|
|
|
|
|
|
|
import (
|
2017-06-09 15:15:38 +02:00
|
|
|
"sort"
|
|
|
|
|
2017-04-20 02:04:09 +02:00
|
|
|
version "github.com/hashicorp/go-version"
|
|
|
|
)
|
|
|
|
|
|
|
|
// A ConstraintStr is a string containing a possibly-invalid representation
|
|
|
|
// of a version constraint provided in configuration. Call Parse on it to
|
|
|
|
// obtain a real Constraint object, or discover that it is invalid.
|
|
|
|
type ConstraintStr string
|
|
|
|
|
2017-05-03 23:31:46 +02:00
|
|
|
// Parse transforms a ConstraintStr into a Constraints if it is
|
2017-04-20 02:04:09 +02:00
|
|
|
// syntactically valid. If it isn't then an error is returned instead.
|
2017-05-03 23:31:46 +02:00
|
|
|
func (s ConstraintStr) Parse() (Constraints, error) {
|
2017-04-20 02:04:09 +02:00
|
|
|
raw, err := version.NewConstraint(string(s))
|
|
|
|
if err != nil {
|
2017-05-03 23:31:46 +02:00
|
|
|
return Constraints{}, err
|
2017-04-20 02:04:09 +02:00
|
|
|
}
|
2017-05-03 23:31:46 +02:00
|
|
|
return Constraints{raw}, nil
|
2017-04-20 02:04:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// MustParse is like Parse but it panics if the constraint string is invalid.
|
2017-05-03 23:31:46 +02:00
|
|
|
func (s ConstraintStr) MustParse() Constraints {
|
2017-04-20 02:04:09 +02:00
|
|
|
ret, err := s.Parse()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
2017-05-03 23:31:46 +02:00
|
|
|
// Constraints represents a set of versions which any given Version is either
|
2017-04-20 02:04:09 +02:00
|
|
|
// a member of or not.
|
2017-05-03 23:31:46 +02:00
|
|
|
type Constraints struct {
|
2017-04-20 02:04:09 +02:00
|
|
|
raw version.Constraints
|
|
|
|
}
|
|
|
|
|
2017-05-03 23:31:46 +02:00
|
|
|
// AllVersions is a Constraints containing all versions
|
|
|
|
var AllVersions Constraints
|
2017-04-21 03:13:54 +02:00
|
|
|
|
|
|
|
func init() {
|
2017-05-03 23:31:46 +02:00
|
|
|
AllVersions = Constraints{
|
2017-04-21 03:13:54 +02:00
|
|
|
raw: make(version.Constraints, 0),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-25 00:03:36 +02:00
|
|
|
// Allows returns true if the given version permitted by the receiving
|
|
|
|
// constraints set.
|
2017-05-05 00:53:02 +02:00
|
|
|
func (s Constraints) Allows(v Version) bool {
|
2017-04-20 02:04:09 +02:00
|
|
|
return s.raw.Check(v.raw)
|
|
|
|
}
|
|
|
|
|
2017-05-05 00:53:02 +02:00
|
|
|
// Append combines the receiving set with the given other set to produce
|
2017-05-03 23:31:46 +02:00
|
|
|
// a set that is the intersection of both sets, which is to say that resulting
|
|
|
|
// constraints contain only the versions that are members of both.
|
2017-05-05 00:53:02 +02:00
|
|
|
func (s Constraints) Append(other Constraints) Constraints {
|
2017-04-20 02:04:09 +02:00
|
|
|
raw := make(version.Constraints, 0, len(s.raw)+len(other.raw))
|
|
|
|
|
|
|
|
// Since "raw" is a list of constraints that remove versions from the set,
|
|
|
|
// "Intersection" is implemented by concatenating together those lists,
|
|
|
|
// thus leaving behind only the versions not removed by either list.
|
|
|
|
raw = append(raw, s.raw...)
|
|
|
|
raw = append(raw, other.raw...)
|
|
|
|
|
2017-06-09 15:15:38 +02:00
|
|
|
// while the set is unordered, we sort these lexically for consistent output
|
|
|
|
sort.Slice(raw, func(i, j int) bool {
|
|
|
|
return raw[i].String() < raw[j].String()
|
|
|
|
})
|
|
|
|
|
2017-05-03 23:31:46 +02:00
|
|
|
return Constraints{raw}
|
2017-04-20 02:04:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// String returns a string representation of the set members as a set
|
|
|
|
// of range constraints.
|
2017-05-03 23:31:46 +02:00
|
|
|
func (s Constraints) String() string {
|
2017-04-20 02:04:09 +02:00
|
|
|
return s.raw.String()
|
|
|
|
}
|
2017-06-02 02:57:43 +02:00
|
|
|
|
|
|
|
// Unconstrained returns true if and only if the receiver is an empty
|
|
|
|
// constraint set.
|
|
|
|
func (s Constraints) Unconstrained() bool {
|
|
|
|
return len(s.raw) == 0
|
|
|
|
}
|