diff --git a/Gopkg.lock b/Gopkg.lock index adf97a6dad..92186ad471 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -4,7 +4,7 @@ memo = "932b7b1663f6eecccb1fada1d3670ae24cd8aa7c8b61e3b224edfefebe25954e" branch = "2.x" name = "github.com/Masterminds/semver" packages = ["."] - revision = "94ad6eaf8457cf85a68c9b53fa42e9b1b8683783" + revision = "139cc0982c53f1367af5636b12b7643cd03757fc" [[projects]] name = "github.com/Masterminds/vcs" diff --git a/cmd/dep/testdata/harness_tests/init/case1/final/Gopkg.lock b/cmd/dep/testdata/harness_tests/init/case1/final/Gopkg.lock index d43aa9f9ac..2124b073e6 100644 --- a/cmd/dep/testdata/harness_tests/init/case1/final/Gopkg.lock +++ b/cmd/dep/testdata/harness_tests/init/case1/final/Gopkg.lock @@ -1,4 +1,4 @@ -memo = "88d2718cda70cce45158f953d2c6ead79c1db38e67e9704aff72be8fddb096e7" +memo = "1b381263a360eafafe3ef7f9be626672668d17250a3c9a8debd169d1b5e2eebb" [[projects]] name = "github.com/sdboyer/deptest" diff --git a/cmd/dep/testdata/harness_tests/init/case1/final/Gopkg.toml b/cmd/dep/testdata/harness_tests/init/case1/final/Gopkg.toml index a5284b92c0..2a429541ca 100644 --- a/cmd/dep/testdata/harness_tests/init/case1/final/Gopkg.toml +++ b/cmd/dep/testdata/harness_tests/init/case1/final/Gopkg.toml @@ -1,4 +1,4 @@ [[dependencies]] name = "github.com/sdboyer/deptest" - version = ">=0.8.0, <1.0.0" + version = "^0.8.0" \ No newline at end of file diff --git a/cmd/dep/testdata/harness_tests/init/case2/final/Gopkg.lock b/cmd/dep/testdata/harness_tests/init/case2/final/Gopkg.lock index 50ed86f68e..38b72a81a9 100644 --- a/cmd/dep/testdata/harness_tests/init/case2/final/Gopkg.lock +++ b/cmd/dep/testdata/harness_tests/init/case2/final/Gopkg.lock @@ -1,4 +1,4 @@ -memo = "b4fe6e8bceac924197838b6ea47989abbdd3a8d31035d20ee0a1dabc0994c368" +memo = "ced51326ad990b11098d8076d0f7d72d89eee1ba6e8dacc7bc73be05cddac438" [[projects]] name = "github.com/sdboyer/deptest" diff --git a/cmd/dep/testdata/harness_tests/init/case2/final/Gopkg.toml b/cmd/dep/testdata/harness_tests/init/case2/final/Gopkg.toml index 487298ca78..55921055ae 100644 --- a/cmd/dep/testdata/harness_tests/init/case2/final/Gopkg.toml +++ b/cmd/dep/testdata/harness_tests/init/case2/final/Gopkg.toml @@ -1,7 +1,7 @@ [[dependencies]] name = "github.com/sdboyer/deptest" - version = ">=0.8.0, <1.0.0" + version = "^0.8.0" [[dependencies]] name = "github.com/sdboyer/deptestdos" diff --git a/cmd/dep/testdata/harness_tests/remove/force/case1/final/Gopkg.lock b/cmd/dep/testdata/harness_tests/remove/force/case1/final/Gopkg.lock index 03b152c335..b808a70fc4 100644 --- a/cmd/dep/testdata/harness_tests/remove/force/case1/final/Gopkg.lock +++ b/cmd/dep/testdata/harness_tests/remove/force/case1/final/Gopkg.lock @@ -1,4 +1,4 @@ -memo = "88d2718cda70cce45158f953d2c6ead79c1db38e67e9704aff72be8fddb096e7" +memo = "1b381263a360eafafe3ef7f9be626672668d17250a3c9a8debd169d1b5e2eebb" [[projects]] name = "github.com/sdboyer/deptest" diff --git a/cmd/dep/testdata/harness_tests/remove/force/case1/final/Gopkg.toml b/cmd/dep/testdata/harness_tests/remove/force/case1/final/Gopkg.toml index 413feb4eb0..1fc0f2191c 100644 --- a/cmd/dep/testdata/harness_tests/remove/force/case1/final/Gopkg.toml +++ b/cmd/dep/testdata/harness_tests/remove/force/case1/final/Gopkg.toml @@ -4,7 +4,7 @@ [[dependencies]] name = "github.com/sdboyer/deptest" - version = ">=0.8.0, <1.0.0" + version = "^0.8.0" [[dependencies]] name = "github.com/sdboyer/deptestdos" diff --git a/cmd/dep/testdata/harness_tests/remove/force/case1/initial/Gopkg.toml b/cmd/dep/testdata/harness_tests/remove/force/case1/initial/Gopkg.toml index 413feb4eb0..1fc0f2191c 100644 --- a/cmd/dep/testdata/harness_tests/remove/force/case1/initial/Gopkg.toml +++ b/cmd/dep/testdata/harness_tests/remove/force/case1/initial/Gopkg.toml @@ -4,7 +4,7 @@ [[dependencies]] name = "github.com/sdboyer/deptest" - version = ">=0.8.0, <1.0.0" + version = "^0.8.0" [[dependencies]] name = "github.com/sdboyer/deptestdos" diff --git a/cmd/dep/testdata/harness_tests/remove/specific/case1/final/Gopkg.lock b/cmd/dep/testdata/harness_tests/remove/specific/case1/final/Gopkg.lock index 89372cc518..a3f2f608c3 100644 --- a/cmd/dep/testdata/harness_tests/remove/specific/case1/final/Gopkg.lock +++ b/cmd/dep/testdata/harness_tests/remove/specific/case1/final/Gopkg.lock @@ -1,4 +1,4 @@ -memo = "d414dbf5fc668c1085effa68372d02e54b23d058cc66f9fd19ba094c6a946d9b" +memo = "722f8e1427ab6d4dd1bc92376e4ce41ba6034a74e283a3fe4d65c7c838c7e0d2" [[projects]] name = "github.com/sdboyer/deptest" diff --git a/cmd/dep/testdata/harness_tests/remove/specific/case1/final/Gopkg.toml b/cmd/dep/testdata/harness_tests/remove/specific/case1/final/Gopkg.toml index 26653704de..a007e12ac5 100644 --- a/cmd/dep/testdata/harness_tests/remove/specific/case1/final/Gopkg.toml +++ b/cmd/dep/testdata/harness_tests/remove/specific/case1/final/Gopkg.toml @@ -4,7 +4,7 @@ [[dependencies]] name = "github.com/sdboyer/deptest" - version = ">=0.8.0, <1.0.0" + version = "^0.8.0" [[dependencies]] name = "github.com/sdboyer/deptestdos" diff --git a/cmd/dep/testdata/harness_tests/remove/specific/case1/initial/Gopkg.toml b/cmd/dep/testdata/harness_tests/remove/specific/case1/initial/Gopkg.toml index 26653704de..a007e12ac5 100644 --- a/cmd/dep/testdata/harness_tests/remove/specific/case1/initial/Gopkg.toml +++ b/cmd/dep/testdata/harness_tests/remove/specific/case1/initial/Gopkg.toml @@ -4,7 +4,7 @@ [[dependencies]] name = "github.com/sdboyer/deptest" - version = ">=0.8.0, <1.0.0" + version = "^0.8.0" [[dependencies]] name = "github.com/sdboyer/deptestdos" diff --git a/cmd/dep/testdata/harness_tests/remove/specific/case2/final/Gopkg.lock b/cmd/dep/testdata/harness_tests/remove/specific/case2/final/Gopkg.lock index cb091e429d..3c588e4d62 100644 --- a/cmd/dep/testdata/harness_tests/remove/specific/case2/final/Gopkg.lock +++ b/cmd/dep/testdata/harness_tests/remove/specific/case2/final/Gopkg.lock @@ -1,4 +1,4 @@ -memo = "38d8431865759ee3bf28fbdfc464f98ee8b56319394ec717df45e9969544cfca" +memo = "e7725ea56516a42a641aaaf5d48754258d9f3c59949cb8a0e8a21b1ab6e07179" [[projects]] name = "github.com/sdboyer/deptest" diff --git a/cmd/dep/testdata/harness_tests/remove/specific/case2/final/Gopkg.toml b/cmd/dep/testdata/harness_tests/remove/specific/case2/final/Gopkg.toml index 0bb0ab1d1b..6a818bfc82 100644 --- a/cmd/dep/testdata/harness_tests/remove/specific/case2/final/Gopkg.toml +++ b/cmd/dep/testdata/harness_tests/remove/specific/case2/final/Gopkg.toml @@ -4,7 +4,7 @@ [[dependencies]] name = "github.com/sdboyer/deptest" - version = ">=0.8.0, <1.0.0" + version = "^0.8.0" [[dependencies]] name = "github.com/sdboyer/deptestdos" diff --git a/cmd/dep/testdata/harness_tests/remove/specific/case2/initial/Gopkg.toml b/cmd/dep/testdata/harness_tests/remove/specific/case2/initial/Gopkg.toml index 0bb0ab1d1b..6a818bfc82 100644 --- a/cmd/dep/testdata/harness_tests/remove/specific/case2/initial/Gopkg.toml +++ b/cmd/dep/testdata/harness_tests/remove/specific/case2/initial/Gopkg.toml @@ -4,7 +4,7 @@ [[dependencies]] name = "github.com/sdboyer/deptest" - version = ">=0.8.0, <1.0.0" + version = "^0.8.0" [[dependencies]] name = "github.com/sdboyer/deptestdos" diff --git a/cmd/dep/testdata/harness_tests/remove/unused/case1/final/Gopkg.lock b/cmd/dep/testdata/harness_tests/remove/unused/case1/final/Gopkg.lock index 89372cc518..a3f2f608c3 100644 --- a/cmd/dep/testdata/harness_tests/remove/unused/case1/final/Gopkg.lock +++ b/cmd/dep/testdata/harness_tests/remove/unused/case1/final/Gopkg.lock @@ -1,4 +1,4 @@ -memo = "d414dbf5fc668c1085effa68372d02e54b23d058cc66f9fd19ba094c6a946d9b" +memo = "722f8e1427ab6d4dd1bc92376e4ce41ba6034a74e283a3fe4d65c7c838c7e0d2" [[projects]] name = "github.com/sdboyer/deptest" diff --git a/cmd/dep/testdata/harness_tests/remove/unused/case1/final/Gopkg.toml b/cmd/dep/testdata/harness_tests/remove/unused/case1/final/Gopkg.toml index 0bb0ab1d1b..6a818bfc82 100644 --- a/cmd/dep/testdata/harness_tests/remove/unused/case1/final/Gopkg.toml +++ b/cmd/dep/testdata/harness_tests/remove/unused/case1/final/Gopkg.toml @@ -4,7 +4,7 @@ [[dependencies]] name = "github.com/sdboyer/deptest" - version = ">=0.8.0, <1.0.0" + version = "^0.8.0" [[dependencies]] name = "github.com/sdboyer/deptestdos" diff --git a/cmd/dep/testdata/harness_tests/remove/unused/case1/initial/Gopkg.toml b/cmd/dep/testdata/harness_tests/remove/unused/case1/initial/Gopkg.toml index 0bb0ab1d1b..6a818bfc82 100644 --- a/cmd/dep/testdata/harness_tests/remove/unused/case1/initial/Gopkg.toml +++ b/cmd/dep/testdata/harness_tests/remove/unused/case1/initial/Gopkg.toml @@ -4,7 +4,7 @@ [[dependencies]] name = "github.com/sdboyer/deptest" - version = ">=0.8.0, <1.0.0" + version = "^0.8.0" [[dependencies]] name = "github.com/sdboyer/deptestdos" diff --git a/cmd/dep/testdata/harness_tests/status/case1/dot/final/Gopkg.lock b/cmd/dep/testdata/harness_tests/status/case1/dot/final/Gopkg.lock index 9b7e4cbf29..3e4f06ebb9 100644 --- a/cmd/dep/testdata/harness_tests/status/case1/dot/final/Gopkg.lock +++ b/cmd/dep/testdata/harness_tests/status/case1/dot/final/Gopkg.lock @@ -1,4 +1,4 @@ -memo = "88d2718cda70cce45158f953d2c6ead79c1db38e67e9704aff72be8fddb096e7" +memo = "1b381263a360eafafe3ef7f9be626672668d17250a3c9a8debd169d1b5e2eebb" [[projects]] name = "github.com/sdboyer/deptest" diff --git a/cmd/dep/testdata/harness_tests/status/case1/json/final/Gopkg.lock b/cmd/dep/testdata/harness_tests/status/case1/json/final/Gopkg.lock index 9b7e4cbf29..3e4f06ebb9 100644 --- a/cmd/dep/testdata/harness_tests/status/case1/json/final/Gopkg.lock +++ b/cmd/dep/testdata/harness_tests/status/case1/json/final/Gopkg.lock @@ -1,4 +1,4 @@ -memo = "88d2718cda70cce45158f953d2c6ead79c1db38e67e9704aff72be8fddb096e7" +memo = "1b381263a360eafafe3ef7f9be626672668d17250a3c9a8debd169d1b5e2eebb" [[projects]] name = "github.com/sdboyer/deptest" diff --git a/cmd/dep/testdata/harness_tests/status/case1/table/final/Gopkg.lock b/cmd/dep/testdata/harness_tests/status/case1/table/final/Gopkg.lock index 9b7e4cbf29..3e4f06ebb9 100644 --- a/cmd/dep/testdata/harness_tests/status/case1/table/final/Gopkg.lock +++ b/cmd/dep/testdata/harness_tests/status/case1/table/final/Gopkg.lock @@ -1,4 +1,4 @@ -memo = "88d2718cda70cce45158f953d2c6ead79c1db38e67e9704aff72be8fddb096e7" +memo = "1b381263a360eafafe3ef7f9be626672668d17250a3c9a8debd169d1b5e2eebb" [[projects]] name = "github.com/sdboyer/deptest" diff --git a/cmd/dep/testdata/harness_tests/status/case1/table/stdout.txt b/cmd/dep/testdata/harness_tests/status/case1/table/stdout.txt index f78a4eb4b1..f77f65a927 100644 --- a/cmd/dep/testdata/harness_tests/status/case1/table/stdout.txt +++ b/cmd/dep/testdata/harness_tests/status/case1/table/stdout.txt @@ -1,3 +1,3 @@ -PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED -github.com/sdboyer/deptest >=0.8.0, <1.0.0 v0.8.0 ff2948a 3f4c3be 1 -github.com/sdboyer/deptestdos * v2.0.0 5c60720 5c60720 1 +PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED +github.com/sdboyer/deptest ^0.8.0 v0.8.0 ff2948a 3f4c3be 1 +github.com/sdboyer/deptestdos * v2.0.0 5c60720 5c60720 1 diff --git a/internal/gps/constraints.go b/internal/gps/constraints.go index cb9d4f5ae1..eb89467e00 100644 --- a/internal/gps/constraints.go +++ b/internal/gps/constraints.go @@ -58,7 +58,7 @@ func NewSemverConstraint(body string) (Constraint, error) { } // If we got a simple semver.Version, simplify by returning our // corresponding type - if sv, ok := c.(*semver.Version); ok { + if sv, ok := c.(semver.Version); ok { return semVersion{sv: sv}, nil } return semverConstraint{c: c}, nil diff --git a/internal/gps/manager_test.go b/internal/gps/manager_test.go index 0f71ca42e1..ae522f8a8d 100644 --- a/internal/gps/manager_test.go +++ b/internal/gps/manager_test.go @@ -35,7 +35,7 @@ func (a naiveAnalyzer) Info() (name string, version int) { return "naive-analyzer", 1 } -func sv(s string) *semver.Version { +func sv(s string) semver.Version { sv, err := semver.NewVersion(s) if err != nil { panic(fmt.Sprintf("Error creating semver from %q: %s", s, err)) diff --git a/internal/gps/solve_test.go b/internal/gps/solve_test.go index de561672b6..22001370a4 100644 --- a/internal/gps/solve_test.go +++ b/internal/gps/solve_test.go @@ -204,7 +204,7 @@ func fixtureSolveSimpleChecks(fix specfix, soln Solution, err error, t *testing. if err != nil { if fixfail == nil { t.Errorf("Solve failed unexpectedly:\n%s", err) - } else if !reflect.DeepEqual(fixfail, err) { + } else if !(fixfail.Error() == err.Error()) { // TODO(sdboyer) reflect.DeepEqual works for now, but once we start // modeling more complex cases, this should probably become more robust t.Errorf("Failure mismatch:\n\t(GOT): %s\n\t(WNT): %s", err, fixfail) diff --git a/internal/gps/vcs_source.go b/internal/gps/vcs_source.go index 189f5d6982..d382a6d297 100644 --- a/internal/gps/vcs_source.go +++ b/internal/gps/vcs_source.go @@ -291,7 +291,7 @@ func (s *gopkginSource) listVersions(ctx context.Context) ([]PairedVersion, erro vlist := make([]PairedVersion, len(ovlist)) k := 0 var dbranch int // index of branch to be marked default - var bsv *semver.Version + var bsv semver.Version for _, v := range ovlist { // all git versions will always be paired pv := v.(versionPair) @@ -318,7 +318,7 @@ func (s *gopkginSource) listVersions(ctx context.Context) ([]PairedVersion, erro // which one to mark as default until we've seen them all tv.isDefault = false // Figure out if this is the current leader for default branch - if bsv == nil || bsv.LessThan(sv) { + if bsv == (semver.Version{}) || bsv.LessThan(sv) { bsv = sv dbranch = k } @@ -331,7 +331,7 @@ func (s *gopkginSource) listVersions(ctx context.Context) ([]PairedVersion, erro } vlist = vlist[:k] - if bsv != nil { + if bsv != (semver.Version{}) { dbv := vlist[dbranch].(versionPair) vlist[dbranch] = branchVersion{ name: dbv.v.(branchVersion).name, diff --git a/internal/gps/version.go b/internal/gps/version.go index 4aa1f40410..a75e38aad6 100644 --- a/internal/gps/version.go +++ b/internal/gps/version.go @@ -344,7 +344,7 @@ func (v plainVersion) Is(r Revision) PairedVersion { } type semVersion struct { - sv *semver.Version + sv semver.Version } func (v semVersion) String() string { diff --git a/manifest_test.go b/manifest_test.go index 3eb87df105..7ccb021008 100644 --- a/manifest_test.go +++ b/manifest_test.go @@ -61,7 +61,7 @@ func TestWriteManifest(t *testing.T) { golden := "manifest/golden.toml" want := h.GetTestFileString(golden) - c, _ := gps.NewSemverConstraint("^v0.12.0") + c, _ := gps.NewSemverConstraint(">=0.12.0, <1.0.0") m := &Manifest{ Dependencies: map[gps.ProjectRoot]gps.ProjectProperties{ gps.ProjectRoot("github.com/golang/dep/internal/gps"): { diff --git a/vendor/github.com/Masterminds/semver/.travis.yml b/vendor/github.com/Masterminds/semver/.travis.yml index 3231840778..fa92a5a326 100644 --- a/vendor/github.com/Masterminds/semver/.travis.yml +++ b/vendor/github.com/Masterminds/semver/.travis.yml @@ -1,7 +1,6 @@ language: go go: - - 1.5 - 1.6 - 1.7 - tip @@ -13,8 +12,8 @@ go: sudo: false script: - - GO15VENDOREXPERIMENT=1 make setup - - GO15VENDOREXPERIMENT=1 make test + - make setup + - make test notifications: webhooks: diff --git a/vendor/github.com/Masterminds/semver/collection.go b/vendor/github.com/Masterminds/semver/collection.go index a78235895f..459fbe0e3d 100644 --- a/vendor/github.com/Masterminds/semver/collection.go +++ b/vendor/github.com/Masterminds/semver/collection.go @@ -3,7 +3,7 @@ package semver // Collection is a collection of Version instances and implements the sort // interface. See the sort package for more details. // https://golang.org/pkg/sort/ -type Collection []*Version +type Collection []Version // Len returns the length of a collection. The number of Version instances // on the slice. diff --git a/vendor/github.com/Masterminds/semver/collection_test.go b/vendor/github.com/Masterminds/semver/collection_test.go index 71b909c4e0..a1d745f476 100644 --- a/vendor/github.com/Masterminds/semver/collection_test.go +++ b/vendor/github.com/Masterminds/semver/collection_test.go @@ -15,7 +15,7 @@ func TestCollection(t *testing.T) { "0.4.2", } - vs := make([]*Version, len(raw)) + vs := make([]Version, len(raw)) for i, r := range raw { v, err := NewVersion(r) if err != nil { diff --git a/vendor/github.com/Masterminds/semver/constraints.go b/vendor/github.com/Masterminds/semver/constraints.go index bf2f500380..628a44a161 100644 --- a/vendor/github.com/Masterminds/semver/constraints.go +++ b/vendor/github.com/Masterminds/semver/constraints.go @@ -46,15 +46,26 @@ func init() { cvRegex, cvRegex)) } +// Constraint is the interface that wraps checking a semantic version against +// one or more constraints to find a match. type Constraint interface { - // Constraints compose the fmt.Stringer interface. Printing a constraint - // will yield a string that, if passed to NewConstraint(), will produce the - // original constraint. (Bidirectional serialization) + // Constraints compose the fmt.Stringer interface. This method is the + // bijective inverse of NewConstraint(): if a string yielded from this + // method is passed to NewConstraint(), a byte-identical instance of the + // original Constraint will be returend. fmt.Stringer + // ImpliedCaretString converts the Constraint to a string in the same manner + // as String(), but treats the empty operator as equivalent to ^, rather + // than =. + // + // In the same way that String() is the inverse of NewConstraint(), this + // method is the inverse of to NewConstraintIC(). + ImpliedCaretString() string + // Matches checks that a version satisfies the constraint. If it does not, // an error is returned indcating the problem; if it does, the error is nil. - Matches(v *Version) error + Matches(v Version) error // Intersect computes the intersection between the receiving Constraint and // passed Constraint, and returns a new Constraint representing the result. @@ -84,9 +95,10 @@ type realConstraint interface { _real() } -// Controls whether or not parsed constraints are cached +// CacheConstraints controls whether or not parsed constraints are cached var CacheConstraints = true var constraintCache = make(map[string]ccache) +var constraintCacheIC = make(map[string]ccache) var constraintCacheLock sync.RWMutex type ccache struct { @@ -102,9 +114,19 @@ type ccache struct { // If an invalid constraint string is passed, more information is provided in // the returned error string. func NewConstraint(in string) (Constraint, error) { + return newConstraint(in, false, constraintCache) +} + +// NewConstraintIC (ImpliedConstraint) is the same as NewConstraint, except that +// it treats an absent operator as being equivalent to ^ instead of =. +func NewConstraintIC(in string) (Constraint, error) { + return newConstraint(in, true, constraintCacheIC) +} + +func newConstraint(in string, ic bool, cache map[string]ccache) (Constraint, error) { if CacheConstraints { constraintCacheLock.RLock() - if final, exists := constraintCache[in]; exists { + if final, exists := cache[in]; exists { constraintCacheLock.RUnlock() return final.c, final.err } @@ -120,11 +142,11 @@ func NewConstraint(in string) (Constraint, error) { cs := strings.Split(v, ",") result := make([]Constraint, len(cs)) for i, s := range cs { - pc, err := parseConstraint(s) + pc, err := parseConstraint(s, ic) if err != nil { if CacheConstraints { constraintCacheLock.Lock() - constraintCache[in] = ccache{err: err} + cache[in] = ccache{err: err} constraintCacheLock.Unlock() } return nil, err @@ -139,7 +161,7 @@ func NewConstraint(in string) (Constraint, error) { if CacheConstraints { constraintCacheLock.Lock() - constraintCache[in] = ccache{c: final} + cache[in] = ccache{c: final} constraintCacheLock.Unlock() } @@ -201,10 +223,8 @@ func Union(cg ...Constraint) Constraint { return c case none: continue - case *Version: - //if tc != nil { + case Version: //heap.Push(&real, tc) - //} real = append(real, tc) case rangeConstraint: //heap.Push(&real, tc) @@ -233,9 +253,9 @@ func Union(cg ...Constraint) Constraint { last := nuc[len(nuc)-1] switch lt := last.(type) { - case *Version: + case Version: switch ct := c.(type) { - case *Version: + case Version: // Two versions in a row; only append if they're not equal if !lt.Equal(ct) { nuc = append(nuc, ct) @@ -257,7 +277,7 @@ func Union(cg ...Constraint) Constraint { } case rangeConstraint: switch ct := c.(type) { - case *Version: + case Version: // Last was range, current is version. constraintList sort invariants guarantee // that the version will be greater than the min, so we have to // determine if the version is less than the max. If it is, we diff --git a/vendor/github.com/Masterminds/semver/constraints_test.go b/vendor/github.com/Masterminds/semver/constraints_test.go index df85e82412..a45714d746 100644 --- a/vendor/github.com/Masterminds/semver/constraints_test.go +++ b/vendor/github.com/Masterminds/semver/constraints_test.go @@ -11,28 +11,34 @@ func TestParseConstraint(t *testing.T) { {"*", Any(), false}, {">= 1.2", rangeConstraint{ min: newV(1, 2, 0), + max: Version{special: infiniteVersion}, includeMin: true, }, false}, {"1.0", newV(1, 0, 0), false}, {"foo", nil, true}, {"<= 1.2", rangeConstraint{ + min: Version{special: zeroVersion}, max: newV(1, 2, 0), includeMax: true, }, false}, {"=< 1.2", rangeConstraint{ + min: Version{special: zeroVersion}, max: newV(1, 2, 0), includeMax: true, }, false}, {"=> 1.2", rangeConstraint{ min: newV(1, 2, 0), + max: Version{special: infiniteVersion}, includeMin: true, }, false}, {"v1.2", newV(1, 2, 0), false}, {"=1.5", newV(1, 5, 0), false}, {"> 1.3", rangeConstraint{ min: newV(1, 3, 0), + max: Version{special: infiniteVersion}, }, false}, {"< 1.4.1", rangeConstraint{ + min: Version{special: zeroVersion}, max: newV(1, 4, 1), }, false}, {"~1.1.0", rangeConstraint{ @@ -50,7 +56,7 @@ func TestParseConstraint(t *testing.T) { } for _, tc := range tests { - c, err := parseConstraint(tc.in) + c, err := parseConstraint(tc.in, false) if tc.err && err == nil { t.Errorf("Expected error for %s didn't occur", tc.in) } else if !tc.err && err != nil { @@ -81,8 +87,8 @@ func constraintEq(c1, c2 Constraint) bool { return false } return true - case *Version: - if tc2, ok := c2.(*Version); ok { + case Version: + if tc2, ok := c2.(Version); ok { return tc1.Equal(tc2) } return false @@ -136,8 +142,8 @@ func constraintEq(c1, c2 Constraint) bool { } // newV is a helper to create a new Version object. -func newV(major, minor, patch uint64) *Version { - return &Version{ +func newV(major, minor, patch uint64) Version { + return Version{ major: major, minor: minor, patch: patch, @@ -177,18 +183,22 @@ func TestConstraintCheck(t *testing.T) { {">2.x", "3.0.0", true}, {">2.x", "2.9.9", false}, {">2.x", "1.9.9", false}, - // TODO these are all pending the changes in #10 - //{"<=2.x-beta1", "3.0.0-alpha2", false}, - //{">2.x-beta1", "3.0.0-alpha2", true}, - //{"<2.0.0", "2.0.0-alpha1", false}, - //{"<=2.0.0", "2.0.0-alpha1", true}, + {"<=2.x-alpha2", "3.0.0-alpha3", false}, + {"<=2.0.0", "2.0.0-alpha1", false}, + {">2.x-beta1", "3.0.0-alpha2", false}, + {"^2.0.0", "3.0.0-alpha2", false}, + {"^2.0.0", "2.0.0-alpha1", false}, + {"^2.1.0-alpha1", "2.1.0-alpha2", true}, // allow prerelease match within same major/minor/patch + {"^2.1.0-alpha1", "2.1.1-alpha2", false}, // but ONLY within same major/minor/patch + {"^2.1.0-alpha3", "2.1.0-alpha2", false}, // still respect prerelease ordering + {"^2.0.0", "2.0.0-alpha2", false}, // and only if the min has a prerelease } for _, tc := range tests { if testing.Verbose() { t.Logf("Testing if %q allows %q", tc.constraint, tc.version) } - c, err := parseConstraint(tc.constraint) + c, err := parseConstraint(tc.constraint, false) if err != nil { t.Errorf("err: %s", err) continue @@ -219,6 +229,7 @@ func TestNewConstraint(t *testing.T) { }{ {">= 1.1", rangeConstraint{ min: newV(1, 1, 0), + max: Version{special: infiniteVersion}, includeMin: true, }, false}, {"2.0", newV(2, 0, 0), false}, @@ -267,14 +278,17 @@ func TestNewConstraint(t *testing.T) { includeMax: false, }, false}, {"!=1.4.0", rangeConstraint{ - excl: []*Version{ + min: Version{special: zeroVersion}, + max: Version{special: infiniteVersion}, + excl: []Version{ newV(1, 4, 0), }, }, false}, {">=1.1.0, !=1.4.0", rangeConstraint{ min: newV(1, 1, 0), + max: Version{special: infiniteVersion}, includeMin: true, - excl: []*Version{ + excl: []Version{ newV(1, 4, 0), }, }, false}, @@ -299,6 +313,45 @@ func TestNewConstraint(t *testing.T) { } } +func TestNewConstraintIC(t *testing.T) { + tests := []struct { + input string + c Constraint + err bool + }{ + {"=2.0", newV(2, 0, 0), false}, + {"= 2.0", newV(2, 0, 0), false}, + {"1.1.0", rangeConstraint{ + min: newV(1, 1, 0), + max: newV(2, 0, 0), + includeMin: true, + }, false}, + {"1.1", rangeConstraint{ + min: newV(1, 1, 0), + max: newV(2, 0, 0), + includeMin: true, + }, false}, + } + + for _, tc := range tests { + c, err := NewConstraintIC(tc.input) + if tc.err && err == nil { + t.Errorf("expected but did not get error for: %s", tc.input) + continue + } else if !tc.err && err != nil { + t.Errorf("unexpectederror for input %s: %s", tc.input, err) + continue + } + if tc.err { + continue + } + + if !constraintEq(tc.c, c) { + t.Errorf("%q produced constraint %q, but expected %q", tc.input, c, tc.c) + } + } +} + func TestConstraintsCheck(t *testing.T) { tests := []struct { constraint string @@ -306,9 +359,13 @@ func TestConstraintsCheck(t *testing.T) { check bool }{ {"*", "1.2.3", true}, - {"~0.0.0", "1.2.3", false}, // npm allows this weird thing, but we don't + {"~0.0.0", "1.2.3", false}, + {"0.x.x", "1.2.3", false}, + {"0.0.x", "1.2.3", false}, {"~0.0.0", "0.1.9", false}, {"~0.0.0", "0.0.9", true}, + {"^0.0.0", "0.0.9", true}, + {"^0.0.0", "0.1.9", false}, // caret behaves like tilde below 1.0.0 {"= 2.0", "1.2.3", false}, {"= 2.0", "2.0.0", true}, {"4.1", "4.1.0", true}, @@ -398,7 +455,6 @@ func TestBidirectionalSerialization(t *testing.T) { }{ {"*", true}, // any {"~0.0.0", false}, // tildes expand into ranges - {"^2.0", false}, // carets expand into ranges {"=2.0", false}, // abbreviated versions print as full {"4.1.x", false}, // wildcards expand into ranges {">= 1.1.0", false}, // does not produce spaces on ranges @@ -415,8 +471,8 @@ func TestBidirectionalSerialization(t *testing.T) { {">1.1.1, <1.2.0", true}, // no unary op on gt min {">1.1.7, <=2.0.0", true}, // no unary op on gt min and lte max {">1.1.7, <=2.0.0", true}, // no unary op on gt min and lte max - {">=0.1.7, <1.0.0", true}, // carat shifting below 1.0.0 - {">=0.1.7, <0.3.0", true}, // carat shifting width below 1.0.0 + {">=0.1.7, <1.0.0", true}, // caret shifting below 1.0.0 + {">=0.1.7, <0.3.0", true}, // caret shifting width below 1.0.0 } for _, fix := range tests { @@ -436,11 +492,38 @@ func TestBidirectionalSerialization(t *testing.T) { } } +func TestBidirectionalSerializationIC(t *testing.T) { + tests := []struct { + io string + eq bool + }{ + {"*", true}, // any + {"=2.0.0", true}, // versions retain leading = + {"2.0.0", true}, // (no) caret in, (no) caret out + } + + for _, fix := range tests { + c, err := NewConstraintIC(fix.io) + if err != nil { + t.Errorf("Valid constraint string produced unexpected error: %s", err) + } + + eq := fix.io == c.ImpliedCaretString() + if eq != fix.eq { + if eq { + t.Errorf("Constraint %q should not have reproduced input string %q, but did", c, fix.io) + } else { + t.Errorf("Constraint should have reproduced input string %q, but instead produced %q", fix.io, c) + } + } + } +} + func TestPreferUnaryOpForm(t *testing.T) { tests := []struct { in, out string }{ - {">=0.1.7, <0.2.0", "^0.1.7"}, // carat shifting below 1.0.0 + {">=0.1.7, <0.2.0", "^0.1.7"}, // caret shifting below 1.0.0 {">=1.1.0, <2.0.0", "^1.1.0"}, {">=1.1.0, <2.0.0, !=1.2.3", "^1.1.0, !=1.2.3"}, } @@ -530,10 +613,12 @@ func TestIsSuperset(t *testing.T) { max: newV(2, 1, 0), }, { + min: Version{special: zeroVersion}, max: newV(1, 10, 0), }, { min: newV(2, 0, 0), + max: Version{special: infiniteVersion}, }, { min: newV(1, 2, 0), @@ -604,7 +689,7 @@ func TestIsSuperset(t *testing.T) { // isSupersetOf ignores excludes, so even though this would make rc[1] not a // superset of rc[0] anymore, it should still say it is. - rc[1].excl = []*Version{ + rc[1].excl = []Version{ newV(1, 5, 0), } diff --git a/vendor/github.com/Masterminds/semver/error.go b/vendor/github.com/Masterminds/semver/error.go index 4fb73456e9..9eb33b39d1 100644 --- a/vendor/github.com/Masterminds/semver/error.go +++ b/vendor/github.com/Masterminds/semver/error.go @@ -11,6 +11,7 @@ var rangeErrs = [...]string{ "%s is greater than the maximum of %s", "%s is greater than or equal to the maximum of %s", "%s is specifically disallowed in %s", + "%s has prerelease data, so is omitted by the range %s", } const ( @@ -19,15 +20,21 @@ const ( rerrGT rerrGTE rerrNE + rerrPre ) +// MatchFailure is an interface for failures to find a Constraint match. type MatchFailure interface { error - Pair() (v *Version, c Constraint) + + // Pair returns the version and constraint that did not match prompting + // the error. + Pair() (v Version, c Constraint) } +// RangeMatchFailure occurs when a version is not within a constraint range. type RangeMatchFailure struct { - v *Version + v Version rc rangeConstraint typ int8 } @@ -36,22 +43,29 @@ func (rce RangeMatchFailure) Error() string { return fmt.Sprintf(rangeErrs[rce.typ], rce.v, rce.rc) } -func (rce RangeMatchFailure) Pair() (v *Version, r Constraint) { +// Pair returns the version and constraint that did not match. Part of the +// MatchFailure interface. +func (rce RangeMatchFailure) Pair() (v Version, r Constraint) { return rce.v, rce.rc } +// VersionMatchFailure occurs when two versions do not match each other. type VersionMatchFailure struct { - v, other *Version + v, other Version } func (vce VersionMatchFailure) Error() string { return fmt.Sprintf("%s is not equal to %s", vce.v, vce.other) } -func (vce VersionMatchFailure) Pair() (v *Version, r Constraint) { +// Pair returns the two versions that did not match. Part of the +// MatchFailure interface. +func (vce VersionMatchFailure) Pair() (v Version, r Constraint) { return vce.v, vce.other } +// MultiMatchFailure errors occur when there are multiple constraints a version +// is being checked against and there are failures. type MultiMatchFailure []MatchFailure func (mmf MultiMatchFailure) Error() string { diff --git a/vendor/github.com/Masterminds/semver/magic.go b/vendor/github.com/Masterminds/semver/magic.go index 9a8d353a85..7eee64f14a 100644 --- a/vendor/github.com/Masterminds/semver/magic.go +++ b/vendor/github.com/Masterminds/semver/magic.go @@ -2,7 +2,7 @@ package semver import "errors" -var noneErr = errors.New("The 'None' constraint admits no versions.") +var errNone = errors.New("The 'None' constraint admits no versions.") // Any is a constraint that is satisfied by any valid semantic version. type any struct{} @@ -16,9 +16,13 @@ func (any) String() string { return "*" } +func (any) ImpliedCaretString() string { + return "*" +} + // Matches checks that a version satisfies the constraint. As all versions // satisfy Any, this always returns nil. -func (any) Matches(v *Version) error { +func (any) Matches(v Version) error { return nil } @@ -59,10 +63,14 @@ func (none) String() string { return "" } +func (none) ImpliedCaretString() string { + return "" +} + // Matches checks that a version satisfies the constraint. As no version can // satisfy None, this always fails (returns an error). -func (none) Matches(v *Version) error { - return noneErr +func (none) Matches(v Version) error { + return errNone } // Intersect computes the intersection between two constraints. diff --git a/vendor/github.com/Masterminds/semver/parse.go b/vendor/github.com/Masterminds/semver/parse.go index a6e6a97d00..d6afa6c907 100644 --- a/vendor/github.com/Masterminds/semver/parse.go +++ b/vendor/github.com/Masterminds/semver/parse.go @@ -20,7 +20,7 @@ func rewriteRange(i string) string { return o } -func parseConstraint(c string) (Constraint, error) { +func parseConstraint(c string, cbd bool) (Constraint, error) { m := constraintRegex.FindStringSubmatch(c) if m == nil { return nil, fmt.Errorf("Malformed constraint: %s", c) @@ -49,6 +49,16 @@ func parseConstraint(c string) (Constraint, error) { return nil, errors.New("constraint Parser Error") } + // We never want to keep the "original" data in a constraint, and keeping it + // around can disrupt simple equality comparisons. So, strip it out. + v.original = "" + + // If caret-by-default flag is on and there's no operator, convert the + // operator to a caret. + if cbd && m[1] == "" { + m[1] = "^" + } + switch m[1] { case "^": // Caret always expands to a range @@ -81,11 +91,13 @@ func parseConstraint(c string) (Constraint, error) { } } -func expandCaret(v *Version) Constraint { - maxv := &Version{ - major: v.major + 1, - minor: 0, - patch: 0, +func expandCaret(v Version) Constraint { + var maxv Version + // Caret behaves like tilde below 1.0.0 + if v.major == 0 { + maxv.minor = v.minor + 1 + } else { + maxv.major = v.major + 1 } return rangeConstraint{ @@ -96,13 +108,13 @@ func expandCaret(v *Version) Constraint { } } -func expandTilde(v *Version, wildMinor bool) Constraint { +func expandTilde(v Version, wildMinor bool) Constraint { if wildMinor { // When minor is wild on a tilde, behavior is same as caret return expandCaret(v) } - maxv := &Version{ + maxv := Version{ major: v.major, minor: v.minor + 1, patch: 0, @@ -122,23 +134,26 @@ func expandTilde(v *Version, wildMinor bool) Constraint { // (which is how we represent a disjoint set). If there are no wildcards, it // will expand to a rangeConstraint with no min or max, but having the one // exception. -func expandNeq(v *Version, wildMinor, wildPatch bool) Constraint { +func expandNeq(v Version, wildMinor, wildPatch bool) Constraint { if !(wildMinor || wildPatch) { return rangeConstraint{ - excl: []*Version{v}, + min: Version{special: zeroVersion}, + max: Version{special: infiniteVersion}, + excl: []Version{v}, } } // Create the low range with no min, and the max as the floor admitted by // the wildcard lr := rangeConstraint{ + min: Version{special: zeroVersion}, max: v, includeMax: false, } // The high range uses the derived version (bumped depending on where the // wildcards were) as the min, and is inclusive - minv := &Version{ + minv := Version{ major: v.major, minor: v.minor, patch: v.patch, @@ -152,16 +167,17 @@ func expandNeq(v *Version, wildMinor, wildPatch bool) Constraint { hr := rangeConstraint{ min: minv, + max: Version{special: infiniteVersion}, includeMin: true, } return Union(lr, hr) } -func expandGreater(v *Version, wildMinor, wildPatch, eq bool) Constraint { +func expandGreater(v Version, wildMinor, wildPatch, eq bool) Constraint { if (wildMinor || wildPatch) && !eq { // wildcards negate the meaning of prerelease and other info - v = &Version{ + v = Version{ major: v.major, minor: v.minor, patch: v.patch, @@ -176,20 +192,22 @@ func expandGreater(v *Version, wildMinor, wildPatch, eq bool) Constraint { } return rangeConstraint{ min: v, + max: Version{special: infiniteVersion}, includeMin: true, } } return rangeConstraint{ min: v, + max: Version{special: infiniteVersion}, includeMin: eq, } } -func expandLess(v *Version, wildMinor, wildPatch, eq bool) Constraint { +func expandLess(v Version, wildMinor, wildPatch, eq bool) Constraint { if eq && (wildMinor || wildPatch) { // wildcards negate the meaning of prerelease and other info - v = &Version{ + v = Version{ major: v.major, minor: v.minor, patch: v.patch, @@ -200,12 +218,14 @@ func expandLess(v *Version, wildMinor, wildPatch, eq bool) Constraint { v.minor++ } return rangeConstraint{ + min: Version{special: zeroVersion}, max: v, includeMax: false, } } return rangeConstraint{ + min: Version{special: zeroVersion}, max: v, includeMax: eq, } diff --git a/vendor/github.com/Masterminds/semver/range.go b/vendor/github.com/Masterminds/semver/range.go index 5509711742..bcfdfcf9a4 100644 --- a/vendor/github.com/Masterminds/semver/range.go +++ b/vendor/github.com/Masterminds/semver/range.go @@ -7,13 +7,14 @@ import ( ) type rangeConstraint struct { - min, max *Version + min, max Version includeMin, includeMax bool - excl []*Version + excl []Version } -func (rc rangeConstraint) Matches(v *Version) error { +func (rc rangeConstraint) Matches(v Version) error { var fail bool + ispre := v.Prerelease() != "" rce := RangeMatchFailure{ v: v, @@ -21,8 +22,6 @@ func (rc rangeConstraint) Matches(v *Version) error { } if !rc.minIsZero() { - // TODO ensure sane handling of prerelease versions (which are strictly - // less than the normal version, but should be admitted in a geq range) cmp := rc.min.Compare(v) if rc.includeMin { rce.typ = rerrLT @@ -38,8 +37,6 @@ func (rc rangeConstraint) Matches(v *Version) error { } if !rc.maxIsInf() { - // TODO ensure sane handling of prerelease versions (which are strictly - // less than the normal version, but should be admitted in a geq range) cmp := rc.max.Compare(v) if rc.includeMax { rce.typ = rerrGT @@ -47,6 +44,7 @@ func (rc rangeConstraint) Matches(v *Version) error { } else { rce.typ = rerrGTE fail = cmp != 1 + } if fail { @@ -61,6 +59,14 @@ func (rc rangeConstraint) Matches(v *Version) error { } } + // If the incoming version has prerelease info, it's usually a match failure + // - unless all the numeric parts are equal between the incoming and the + // minimum. + if !fail && ispre && !numPartsEq(rc.min, v) { + rce.typ = rerrPre + return rce + } + return nil } @@ -70,8 +76,8 @@ func (rc rangeConstraint) dup() rangeConstraint { return rc } - var excl []*Version - excl = make([]*Version, len(rc.excl)) + var excl []Version + excl = make([]Version, len(rc.excl)) copy(excl, rc.excl) return rangeConstraint{ @@ -84,11 +90,11 @@ func (rc rangeConstraint) dup() rangeConstraint { } func (rc rangeConstraint) minIsZero() bool { - return rc.min == nil + return rc.min.special == zeroVersion } func (rc rangeConstraint) maxIsInf() bool { - return rc.max == nil + return rc.max.special == infiniteVersion } func (rc rangeConstraint) Intersect(c Constraint) Constraint { @@ -99,12 +105,11 @@ func (rc rangeConstraint) Intersect(c Constraint) Constraint { return None() case unionConstraint: return oc.Intersect(rc) - case *Version: + case Version: if err := rc.Matches(oc); err != nil { return None() - } else { - return c } + return c case rangeConstraint: nr := rangeConstraint{ min: rc.min, @@ -174,7 +179,7 @@ func (rc rangeConstraint) Union(c Constraint) Constraint { return rc case unionConstraint: return Union(rc, oc) - case *Version: + case Version: if err := rc.Matches(oc); err == nil { return rc } else if len(rc.excl) > 0 { // TODO (re)checking like this is wasteful @@ -182,7 +187,7 @@ func (rc rangeConstraint) Union(c Constraint) Constraint { // it and return that for k, e := range rc.excl { if e.Equal(oc) { - excl := make([]*Version, len(rc.excl)-1) + excl := make([]Version, len(rc.excl)-1) if k == len(rc.excl)-1 { copy(excl, rc.excl[:k]) @@ -204,12 +209,12 @@ func (rc rangeConstraint) Union(c Constraint) Constraint { if oc.LessThan(rc.min) { return unionConstraint{oc, rc.dup()} } - if areEq(oc, rc.min) { + if oc.Equal(rc.min) { ret := rc.dup() ret.includeMin = true return ret } - if areEq(oc, rc.max) { + if oc.Equal(rc.max) { ret := rc.dup() ret.includeMax = true return ret @@ -233,7 +238,10 @@ func (rc rangeConstraint) Union(c Constraint) Constraint { } // There's at least some dupes, which are all we need to include - nc := rangeConstraint{} + nc := rangeConstraint{ + min: Version{special: zeroVersion}, + max: Version{special: infiniteVersion}, + } for _, e1 := range rc.excl { for _, e2 := range oc.excl { if e1.Equal(e2) { @@ -264,7 +272,10 @@ func (rc rangeConstraint) Union(c Constraint) Constraint { } else if rc.MatchesAny(oc) { // Receiver and input overlap; form a new range accordingly. - nc := rangeConstraint{} + nc := rangeConstraint{ + min: Version{special: zeroVersion}, + max: Version{special: infiniteVersion}, + } // For efficiency, we simultaneously determine if either of the // ranges are supersets of the other, while also selecting the min @@ -370,6 +381,14 @@ func (rc rangeConstraint) isSupersetOf(rc2 rangeConstraint) bool { } func (rc rangeConstraint) String() string { + return rc.toString(false) +} + +func (rc rangeConstraint) ImpliedCaretString() string { + return rc.toString(true) +} + +func (rc rangeConstraint) toString(impliedCaret bool) string { var pieces []string // We need to trigger the standard verbose handling from various points, so @@ -393,7 +412,14 @@ func (rc rangeConstraint) String() string { } // Handle the possibility that we might be able to express the range - // with a carat or tilde, as we prefer those forms. + // with a caret or tilde, as we prefer those forms. + var caretstr string + if impliedCaret { + caretstr = "%s" + } else { + caretstr = "^%s" + } + switch { case rc.minIsZero() && rc.maxIsInf(): // This if is internal because it's useful to know for the other cases @@ -404,13 +430,13 @@ func (rc rangeConstraint) String() string { return "*" } case rc.minIsZero(), rc.includeMax, !rc.includeMin: - // tilde and carat could never apply here + // tilde and caret could never apply here noshort() - case !rc.maxIsInf() && rc.max.Minor() == 0 && rc.max.Patch() == 0: // basic carat + case !rc.maxIsInf() && rc.max.Minor() == 0 && rc.max.Patch() == 0: // basic caret if rc.min.Major() == rc.max.Major()-1 && rc.min.Major() != 0 { - pieces = append(pieces, fmt.Sprintf("^%s", rc.min)) + pieces = append(pieces, fmt.Sprintf(caretstr, rc.min)) } else { - // range is too wide for carat, need standard operators + // range is too wide for caret, need standard operators noshort() } case !rc.maxIsInf() && rc.max.Major() != 0 && rc.max.Patch() == 0: // basic tilde @@ -421,10 +447,10 @@ func (rc rangeConstraint) String() string { noshort() } case !rc.maxIsInf() && rc.max.Major() == 0 && rc.max.Patch() == 0 && rc.max.Minor() != 0: - // below 1.0.0, tilde is meaningless but carat is shifted to the + // below 1.0.0, tilde is meaningless but caret is shifted to the // right (so it basically behaves the same as tilde does above 1.0.0) if rc.min.Minor() == rc.max.Minor()-1 { - pieces = append(pieces, fmt.Sprintf("^%s", rc.min)) + pieces = append(pieces, fmt.Sprintf(caretstr, rc.min)) } else { noshort() } @@ -457,7 +483,7 @@ func areAdjacent(c1, c2 Constraint) bool { return false } - if !areEq(rc1.max, rc2.min) { + if !rc1.max.Equal(rc2.min) { return false } @@ -472,10 +498,10 @@ func (rc rangeConstraint) MatchesAny(c Constraint) bool { return true } -func dedupeExcls(ex1, ex2 []*Version) []*Version { +func dedupeExcls(ex1, ex2 []Version) []Version { // TODO stupid inefficient, but these are really only ever going to be // small, so not worth optimizing right now - var ret []*Version + var ret []Version oloop: for _, e1 := range ex1 { for _, e2 := range ex2 { @@ -491,14 +517,3 @@ oloop: func (rangeConstraint) _private() {} func (rangeConstraint) _real() {} - -func areEq(v1, v2 *Version) bool { - if v1 == nil && v2 == nil { - return true - } - - if v1 != nil && v2 != nil { - return v1.Equal(v2) - } - return false -} diff --git a/vendor/github.com/Masterminds/semver/set_ops_test.go b/vendor/github.com/Masterminds/semver/set_ops_test.go index 363e8484d1..c08f27618d 100644 --- a/vendor/github.com/Masterminds/semver/set_ops_test.go +++ b/vendor/github.com/Masterminds/semver/set_ops_test.go @@ -14,7 +14,7 @@ func TestIntersection(t *testing.T) { } if actual = Intersection(rc1); !constraintEq(actual, rc1) { - t.Errorf("Intersection of one item should always return that item; got %q") + t.Errorf("Intersection of one item should always return that item; got %q", actual) } if actual = Intersection(rc1, None()); !IsNone(actual) { @@ -83,7 +83,7 @@ func TestRangeIntersection(t *testing.T) { } // now exclude just that version - rc1.excl = []*Version{v1} + rc1.excl = []Version{v1} if actual = rc1.Intersect(v1); !IsNone(actual) { t.Errorf("Intersection of version with range having specific exclude for that version should produce None; got %q", actual) } @@ -133,8 +133,10 @@ func TestRangeIntersection(t *testing.T) { // Overlaps with nils rc1 = rangeConstraint{ min: newV(1, 0, 0), + max: Version{special: infiniteVersion}, } rc2 = rangeConstraint{ + min: Version{special: zeroVersion}, max: newV(2, 2, 0), } result = rangeConstraint{ @@ -257,7 +259,7 @@ func TestRangeIntersection(t *testing.T) { rc1 = rangeConstraint{ min: newV(1, 5, 0), max: newV(2, 0, 0), - excl: []*Version{ + excl: []Version{ newV(1, 6, 0), }, } @@ -281,7 +283,7 @@ func TestRangeIntersection(t *testing.T) { rc2 = rangeConstraint{ min: newV(1, 0, 0), max: newV(3, 0, 0), - excl: []*Version{ + excl: []Version{ newV(1, 1, 0), }, } @@ -296,9 +298,11 @@ func TestRangeIntersection(t *testing.T) { // Test min, and greater min rc1 = rangeConstraint{ min: newV(1, 0, 0), + max: Version{special: infiniteVersion}, } rc2 = rangeConstraint{ min: newV(1, 5, 0), + max: Version{special: infiniteVersion}, includeMin: true, } @@ -329,13 +333,17 @@ func TestRangeIntersection(t *testing.T) { // Ensure pure excludes come through as they should rc1 = rangeConstraint{ - excl: []*Version{ + min: Version{special: zeroVersion}, + max: Version{special: infiniteVersion}, + excl: []Version{ newV(1, 6, 0), }, } rc2 = rangeConstraint{ - excl: []*Version{ + min: Version{special: zeroVersion}, + max: Version{special: infiniteVersion}, + excl: []Version{ newV(1, 6, 0), newV(1, 7, 0), }, @@ -379,7 +387,7 @@ func TestRangeUnion(t *testing.T) { // now exclude just that version rc2 := rc1.dup() - rc2.excl = []*Version{v1} + rc2.excl = []Version{v1} if actual = rc2.Union(v1); !constraintEq(actual, rc1) { t.Errorf("Union of version with range having specific exclude for that version should produce the range without that exclude; got %q", actual) } @@ -454,8 +462,10 @@ func TestRangeUnion(t *testing.T) { // Overlaps with nils rc1 = rangeConstraint{ min: newV(1, 0, 0), + max: Version{special: infiniteVersion}, } rc2 = rangeConstraint{ + min: Version{special: zeroVersion}, max: newV(2, 2, 0), } @@ -469,6 +479,7 @@ func TestRangeUnion(t *testing.T) { // Just one nil in overlap rc1.max = newV(2, 0, 0) result = rangeConstraint{ + min: Version{special: zeroVersion}, max: newV(2, 2, 0), } @@ -479,10 +490,11 @@ func TestRangeUnion(t *testing.T) { t.Errorf("Got constraint %q, but expected %q", actual, result) } - rc1.max = nil + rc1.max = Version{special: infiniteVersion} rc2.min = newV(1, 5, 0) result = rangeConstraint{ min: newV(1, 0, 0), + max: Version{special: infiniteVersion}, } if actual = rc1.Union(rc2); !constraintEq(actual, result) { @@ -582,7 +594,7 @@ func TestRangeUnion(t *testing.T) { rc1 = rangeConstraint{ min: newV(1, 5, 0), max: newV(2, 0, 0), - excl: []*Version{ + excl: []Version{ newV(1, 6, 0), }, } @@ -606,7 +618,7 @@ func TestRangeUnion(t *testing.T) { rc2 = rangeConstraint{ min: newV(1, 0, 0), max: newV(3, 0, 0), - excl: []*Version{ + excl: []Version{ newV(1, 1, 0), }, } @@ -620,13 +632,17 @@ func TestRangeUnion(t *testing.T) { // Ensure pure excludes come through as they should rc1 = rangeConstraint{ - excl: []*Version{ + min: Version{special: zeroVersion}, + max: Version{special: infiniteVersion}, + excl: []Version{ newV(1, 6, 0), }, } rc2 = rangeConstraint{ - excl: []*Version{ + min: Version{special: zeroVersion}, + max: Version{special: infiniteVersion}, + excl: []Version{ newV(1, 6, 0), newV(1, 7, 0), }, @@ -640,7 +656,9 @@ func TestRangeUnion(t *testing.T) { } rc1 = rangeConstraint{ - excl: []*Version{ + min: Version{special: zeroVersion}, + max: Version{special: infiniteVersion}, + excl: []Version{ newV(1, 5, 0), }, } @@ -738,7 +756,7 @@ func TestUnionIntersection(t *testing.T) { } // Ensure excludes carry as they should - rc1.excl = []*Version{newV(1, 5, 5)} + rc1.excl = []Version{newV(1, 5, 5)} u1 = unionConstraint{rc1, rc2} ur = unionConstraint{rc1, rc4} diff --git a/vendor/github.com/Masterminds/semver/union.go b/vendor/github.com/Masterminds/semver/union.go index 26598281ee..bc794f88e0 100644 --- a/vendor/github.com/Masterminds/semver/union.go +++ b/vendor/github.com/Masterminds/semver/union.go @@ -4,14 +4,15 @@ import "strings" type unionConstraint []realConstraint -func (uc unionConstraint) Matches(v *Version) error { +func (uc unionConstraint) Matches(v Version) error { var uce MultiMatchFailure for _, c := range uc { - if err := c.Matches(v); err == nil { + err := c.Matches(v) + if err == nil { return nil - } else { - uce = append(uce, err.(MatchFailure)) } + uce = append(uce, err.(MatchFailure)) + } return uce @@ -25,7 +26,7 @@ func (uc unionConstraint) Intersect(c2 Constraint) Constraint { return None() case any: return uc - case *Version: + case Version: return c2 case rangeConstraint: other = append(other, tc2) @@ -70,6 +71,16 @@ func (uc unionConstraint) String() string { return strings.Join(pieces, " || ") } + +func (uc unionConstraint) ImpliedCaretString() string { + var pieces []string + for _, c := range uc { + pieces = append(pieces, c.ImpliedCaretString()) + } + + return strings.Join(pieces, " || ") +} + func (unionConstraint) _private() {} type constraintList []realConstraint @@ -86,12 +97,12 @@ func (cl constraintList) Less(i, j int) bool { ic, jc := cl[i], cl[j] switch tic := ic.(type) { - case *Version: + case Version: switch tjc := jc.(type) { - case *Version: + case Version: return tic.LessThan(tjc) case rangeConstraint: - if tjc.min == nil { + if tjc.minIsZero() { return false } @@ -104,8 +115,8 @@ func (cl constraintList) Less(i, j int) bool { } case rangeConstraint: switch tjc := jc.(type) { - case *Version: - if tic.min == nil { + case Version: + if tic.minIsZero() { return true } @@ -116,10 +127,10 @@ func (cl constraintList) Less(i, j int) bool { } return tic.min.LessThan(tjc) case rangeConstraint: - if tic.min == nil { + if tic.minIsZero() { return true } - if tjc.min == nil { + if tjc.minIsZero() { return false } return tic.min.LessThan(tjc.min) diff --git a/vendor/github.com/Masterminds/semver/version.go b/vendor/github.com/Masterminds/semver/version.go index f984825f8b..449b754040 100644 --- a/vendor/github.com/Masterminds/semver/version.go +++ b/vendor/github.com/Masterminds/semver/version.go @@ -29,13 +29,14 @@ func (b badVersionSegment) Error() string { return fmt.Sprintf("Error parsing version segment: %s", b.e) } -// Controls whether or not parsed constraints are cached +// CacheVersions controls whether or not parsed constraints are cached. Defaults +// to true. var CacheVersions = true var versionCache = make(map[string]vcache) var versionCacheLock sync.RWMutex type vcache struct { - v *Version + v Version err error } @@ -44,12 +45,21 @@ const SemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +type specialVersion uint8 + +const ( + notSpecial specialVersion = iota + zeroVersion + infiniteVersion +) + // Version represents a single semantic version. type Version struct { major, minor, patch uint64 pre string metadata string original string + special specialVersion } func init() { @@ -58,7 +68,7 @@ func init() { // NewVersion parses a given version and returns an instance of Version or // an error if unable to parse the version. -func NewVersion(v string) (*Version, error) { +func NewVersion(v string) (Version, error) { if CacheVersions { versionCacheLock.RLock() if sv, exists := versionCache[v]; exists { @@ -75,10 +85,10 @@ func NewVersion(v string) (*Version, error) { versionCache[v] = vcache{err: ErrInvalidSemVer} versionCacheLock.Unlock() } - return nil, ErrInvalidSemVer + return Version{}, ErrInvalidSemVer } - sv := &Version{ + sv := Version{ metadata: m[8], pre: m[5], original: v, @@ -94,7 +104,7 @@ func NewVersion(v string) (*Version, error) { versionCacheLock.Unlock() } - return nil, bvs + return Version{}, bvs } sv.major = temp @@ -108,7 +118,7 @@ func NewVersion(v string) (*Version, error) { versionCacheLock.Unlock() } - return nil, bvs + return Version{}, bvs } sv.minor = temp } else { @@ -125,7 +135,7 @@ func NewVersion(v string) (*Version, error) { versionCacheLock.Unlock() } - return nil, bvs + return Version{}, bvs } sv.patch = temp } else { @@ -146,10 +156,28 @@ func NewVersion(v string) (*Version, error) { // See the Original() method to retrieve the original value. Semantic Versions // don't contain a leading v per the spec. Instead it's optional on // impelementation. -func (v *Version) String() string { +func (v Version) String() string { + return v.toString(false) +} + +// ImpliedCaretString follows the same rules as String(), but in accordance with +// the Constraint interface will always print a leading "=", as all Versions, +// when acting as a Constraint, act as exact matches. +func (v Version) ImpliedCaretString() string { + return v.toString(true) +} + +func (v Version) toString(ic bool) string { var buf bytes.Buffer - fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) + var base string + if ic { + base = "=%d.%d.%d" + } else { + base = "%d.%d.%d" + } + + fmt.Fprintf(&buf, base, v.major, v.minor, v.patch) if v.pre != "" { fmt.Fprintf(&buf, "-%s", v.pre) } @@ -161,7 +189,7 @@ func (v *Version) String() string { } // Original returns the original value passed in to be parsed. -func (v *Version) Original() string { +func (v Version) Original() string { return v.original } @@ -181,44 +209,29 @@ func (v *Version) Patch() uint64 { } // Prerelease returns the pre-release version. -func (v *Version) Prerelease() string { +func (v Version) Prerelease() string { return v.pre } // Metadata returns the metadata on the version. -func (v *Version) Metadata() string { +func (v Version) Metadata() string { return v.metadata } // LessThan tests if one version is less than another one. -func (v *Version) LessThan(o *Version) bool { - // If a nil version was passed, fail and bail out early. - if o == nil { - return false - } - +func (v Version) LessThan(o Version) bool { return v.Compare(o) < 0 } // GreaterThan tests if one version is greater than another one. -func (v *Version) GreaterThan(o *Version) bool { - // If a nil version was passed, fail and bail out early. - if o == nil { - return false - } - +func (v Version) GreaterThan(o Version) bool { return v.Compare(o) > 0 } // Equal tests if two versions are equal to each other. // Note, versions can be equal with different metadata since metadata // is not considered part of the comparable version. -func (v *Version) Equal(o *Version) bool { - // If a nil version was passed, fail and bail out early. - if o == nil { - return false - } - +func (v Version) Equal(o Version) bool { return v.Compare(o) == 0 } @@ -227,7 +240,27 @@ func (v *Version) Equal(o *Version) bool { // // Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is // lower than the version without a prerelease. -func (v *Version) Compare(o *Version) int { +func (v Version) Compare(o Version) int { + // The special field supercedes all the other information. If it's not + // equal, we can skip out early + if v.special != o.special { + switch v.special { + case zeroVersion: + return -1 + case notSpecial: + if o.special == zeroVersion { + return 1 + } + return -1 + case infiniteVersion: + return 1 + } + } else if v.special != notSpecial { + // If special fields are equal and not notSpecial, then they're + // necessarily equal + return 0 + } + // Compare the major, minor, and patch version for differences. If a // difference is found return the comparison. if d := compareSegment(v.Major(), o.Major()); d != 0 { @@ -257,7 +290,10 @@ func (v *Version) Compare(o *Version) int { return comparePrerelease(ps, po) } -func (v *Version) Matches(v2 *Version) error { +// Matches checks that a verstions match. If they do not, +// an error is returned indcating the problem; if it does, the error is nil. +// This is part of the Constraint interface. +func (v Version) Matches(v2 Version) error { if v.Equal(v2) { return nil } @@ -265,18 +301,23 @@ func (v *Version) Matches(v2 *Version) error { return VersionMatchFailure{v: v, other: v2} } -func (v *Version) MatchesAny(c Constraint) bool { - if v2, ok := c.(*Version); ok { +// MatchesAny checks if an instance of a version matches a constraint which can +// include anything matching the Constraint interface. +func (v Version) MatchesAny(c Constraint) bool { + if v2, ok := c.(Version); ok { return v.Equal(v2) - } else { - // The other implementations all have specific handling for this; fall - // back on theirs. - return c.MatchesAny(v) } + + // The other implementations all have specific handling for this; fall + // back on theirs. + return c.MatchesAny(v) } -func (v *Version) Intersect(c Constraint) Constraint { - if v2, ok := c.(*Version); ok { +// Intersect computes the intersection between the receiving Constraint and +// passed Constraint, and returns a new Constraint representing the result. +// This is part of the Constraint interface. +func (v Version) Intersect(c Constraint) Constraint { + if v2, ok := c.(Version); ok { if v.Equal(v2) { return v } @@ -286,12 +327,15 @@ func (v *Version) Intersect(c Constraint) Constraint { return c.Intersect(v) } -func (v *Version) Union(c Constraint) Constraint { - if v2, ok := c.(*Version); ok && v.Equal(v2) { +// Union computes the union between the receiving Constraint and the passed +// Constraint, and returns a new Constraint representing the result. +// This is part of the Constraint interface. +func (v Version) Union(c Constraint) Constraint { + if v2, ok := c.(Version); ok && v.Equal(v2) { return v - } else { - return Union(v, c) } + + return Union(v, c) } func (Version) _private() {} @@ -327,7 +371,7 @@ func comparePrerelease(v, o string) int { // Iterate over each part of the prereleases to compare the differences. for i := 0; i < l; i++ { - // Since the lentgh of the parts can be different we need to create + // Since the length of the parts can be different we need to create // a placeholder. This is to avoid out of bounds issues. stemp := "" if i < slen { @@ -360,14 +404,14 @@ func comparePrePart(s, o string) int { // When s or o are empty we can use the other in an attempt to determine // the response. if o == "" { - _, n := strconv.ParseInt(s, 10, 64) + _, n := strconv.ParseUint(s, 10, 64) if n != nil { return -1 } return 1 } if s == "" { - _, n := strconv.ParseInt(o, 10, 64) + _, n := strconv.ParseUint(o, 10, 64) if n != nil { return 1 } @@ -379,3 +423,25 @@ func comparePrePart(s, o string) int { } return -1 } + +func numPartsEq(v1, v2 Version) bool { + if v1.special != v2.special { + return false + } + if v1.special != notSpecial { + // If special fields are equal and not notSpecial, then the versions are + // necessarily equal, so their numeric parts are too. + return true + } + + if v1.major != v2.major { + return false + } + if v1.minor != v2.minor { + return false + } + if v1.patch != v2.patch { + return false + } + return true +} diff --git a/vendor/github.com/Masterminds/semver/version_test.go b/vendor/github.com/Masterminds/semver/version_test.go index e8ad413a79..1fae87f526 100644 --- a/vendor/github.com/Masterminds/semver/version_test.go +++ b/vendor/github.com/Masterminds/semver/version_test.go @@ -180,6 +180,33 @@ func TestCompare(t *testing.T) { ) } } + + // One-off tests for special version comparisons + zero := Version{special: zeroVersion} + inf := Version{special: infiniteVersion} + + if zero.Compare(inf) != -1 { + t.Error("Zero version should always be less than infinite version") + } + if zero.Compare(zero) != 0 { + t.Error("Zero version should equal itself") + } + if inf.Compare(zero) != 1 { + t.Error("Infinite version should always be greater than zero version") + } + if inf.Compare(inf) != 0 { + t.Error("Infinite version should equal itself") + } + + // Need to work vs. a normal version, too. + v := Version{} + + if zero.Compare(v) != -1 { + t.Error("Zero version should always be less than any normal version") + } + if inf.Compare(v) != 1 { + t.Error("Infinite version should always be greater than any normal version") + } } func TestLessThan(t *testing.T) { diff --git a/vendor/github.com/Masterminds/vcs/git.go b/vendor/github.com/Masterminds/vcs/git.go index 6467136791..4094e0d03c 100644 --- a/vendor/github.com/Masterminds/vcs/git.go +++ b/vendor/github.com/Masterminds/vcs/git.go @@ -366,7 +366,7 @@ func (s *GitRepo) Ping() bool { // EscapePathSeparator escapes the path separator by replacing it with several. // Note: this is harmless on Unix, and needed on Windows. -func EscapePathSeparator(path string) string { +func EscapePathSeparator(path string) (string) { switch runtime.GOOS { case `windows`: // On Windows, triple all path separators. @@ -379,7 +379,7 @@ func EscapePathSeparator(path string) string { // used with --prefix, like this: --prefix=C:\foo\bar\ -> --prefix=C:\\\foo\\\bar\\\ return strings.Replace(path, string(os.PathSeparator), - string(os.PathSeparator)+string(os.PathSeparator)+string(os.PathSeparator), + string(os.PathSeparator) + string(os.PathSeparator) + string(os.PathSeparator), -1) default: return path @@ -404,7 +404,7 @@ func (s *GitRepo) ExportDir(dir string) error { return NewLocalError("Unable to create directory", err, "") } - path = EscapePathSeparator(dir) + path = EscapePathSeparator( dir ) out, err := s.RunFromDir("git", "checkout-index", "-f", "-a", "--prefix="+path) s.log(out) if err != nil { @@ -412,7 +412,7 @@ func (s *GitRepo) ExportDir(dir string) error { } // and now, the horror of submodules - path = EscapePathSeparator(dir + "$path" + string(os.PathSeparator)) + path = EscapePathSeparator( dir + "$path" + string(os.PathSeparator) ) out, err = s.RunFromDir("git", "submodule", "foreach", "--recursive", "git checkout-index -f -a --prefix="+path) s.log(out) if err != nil { diff --git a/vendor/github.com/Masterminds/vcs/git_test.go b/vendor/github.com/Masterminds/vcs/git_test.go index b7b9a24aae..b58c2c2efd 100644 --- a/vendor/github.com/Masterminds/vcs/git_test.go +++ b/vendor/github.com/Masterminds/vcs/git_test.go @@ -559,6 +559,7 @@ func TestGitSubmoduleHandling2(t *testing.T) { t.Errorf("Current failed to detect Git on tip of master. Got version: %s", v) } + tempDir2, err := ioutil.TempDir("", "go-vcs-git-tests-export") if err != nil { t.Fatalf("Error creating temp directory: %s", err) @@ -582,7 +583,7 @@ func TestGitSubmoduleHandling2(t *testing.T) { t.Errorf("Error checking exported file in Git: %s", err) } - _, err = os.Stat(filepath.Join(filepath.Join(exportDir, "definitions"), "README.md")) + _, err = os.Stat(filepath.Join( filepath.Join(exportDir, "definitions"), "README.md")) if err != nil { t.Errorf("Error checking exported file in Git: %s", err) }