diff --git a/analyzer.go b/analyzer.go
index cbc77f0382..aed9aa9305 100644
--- a/analyzer.go
+++ b/analyzer.go
@@ -8,7 +8,6 @@ import (
"os"
"path/filepath"
- "github.com/Masterminds/semver"
"github.com/sdboyer/gps"
)
@@ -37,7 +36,6 @@ func (a analyzer) DeriveManifestAndLock(path string, n gps.ProjectRoot) (gps.Man
return m, nil, nil
}
-func (a analyzer) Info() (string, *semver.Version) {
- v, _ := semver.NewVersion("v0.0.1")
- return "dep", v
+func (a analyzer) Info() (string, int) {
+ return "dep", 1
}
diff --git a/cmd/dep/ensure.go b/cmd/dep/ensure.go
index 0246df12bd..b16b4cbdf4 100644
--- a/cmd/dep/ensure.go
+++ b/cmd/dep/ensure.go
@@ -18,6 +18,7 @@ import (
"github.com/golang/dep"
"github.com/pkg/errors"
"github.com/sdboyer/gps"
+ "github.com/sdboyer/gps/pkgtree"
)
const ensureShortHelp = `Ensure a dependency is safely vendored in the project`
@@ -123,7 +124,7 @@ func (cmd *ensureCommand) Run(ctx *dep.Ctx, args []string) error {
params.Trace = true
params.TraceLogger = log.New(os.Stderr, "", 0)
}
- params.RootPackageTree, err = gps.ListPackages(p.AbsRoot, string(p.ImportRoot))
+ params.RootPackageTree, err = pkgtree.ListPackages(p.AbsRoot, string(p.ImportRoot))
if err != nil {
return errors.Wrap(err, "ensure ListPackage for project")
}
diff --git a/cmd/dep/hash_in.go b/cmd/dep/hash_in.go
index b76f8fe889..45e2da09f1 100644
--- a/cmd/dep/hash_in.go
+++ b/cmd/dep/hash_in.go
@@ -11,6 +11,7 @@ import (
"github.com/golang/dep"
"github.com/pkg/errors"
"github.com/sdboyer/gps"
+ "github.com/sdboyer/gps/pkgtree"
)
func (cmd *hashinCommand) Name() string { return "hash-inputs" }
@@ -42,7 +43,7 @@ func (hashinCommand) Run(ctx *dep.Ctx, args []string) error {
return errors.Wrap(err, "determineProjectRoot")
}
- params.RootPackageTree, err = gps.ListPackages(p.AbsRoot, cpr)
+ params.RootPackageTree, err = pkgtree.ListPackages(p.AbsRoot, cpr)
if err != nil {
return errors.Wrap(err, "gps.ListPackages")
}
diff --git a/cmd/dep/init.go b/cmd/dep/init.go
index 3e2e4069dd..8037845955 100644
--- a/cmd/dep/init.go
+++ b/cmd/dep/init.go
@@ -15,6 +15,7 @@ import (
"github.com/golang/dep"
"github.com/pkg/errors"
"github.com/sdboyer/gps"
+ "github.com/sdboyer/gps/pkgtree"
)
const initShortHelp = `Initialize a new project with manifest and lock files`
@@ -89,7 +90,7 @@ func (cmd *initCommand) Run(ctx *dep.Ctx, args []string) error {
return errors.Wrap(err, "determineProjectRoot")
}
vlogf("Finding dependencies for %q...", cpr)
- pkgT, err := gps.ListPackages(root, cpr)
+ pkgT, err := pkgtree.ListPackages(root, cpr)
if err != nil {
return errors.Wrap(err, "gps.ListPackages")
}
@@ -214,7 +215,7 @@ type projectData struct {
ondisk map[gps.ProjectRoot]gps.Version // projects that were found on disk
}
-func getProjectData(ctx *dep.Ctx, pkgT gps.PackageTree, cpr string, sm *gps.SourceMgr) (projectData, error) {
+func getProjectData(ctx *dep.Ctx, pkgT pkgtree.PackageTree, cpr string, sm *gps.SourceMgr) (projectData, error) {
constraints := make(gps.ProjectConstraints)
dependencies := make(map[gps.ProjectRoot][]string)
packages := make(map[string]bool)
@@ -285,7 +286,7 @@ func getProjectData(ctx *dep.Ctx, pkgT gps.PackageTree, cpr string, sm *gps.Sour
)
// cache of PackageTrees, so we don't parse projects more than once
- ptrees := make(map[gps.ProjectRoot]gps.PackageTree)
+ ptrees := make(map[gps.ProjectRoot]pkgtree.PackageTree)
// depth-first traverser
var dft func(string) error
@@ -339,7 +340,7 @@ func getProjectData(ctx *dep.Ctx, pkgT gps.PackageTree, cpr string, sm *gps.Sour
ondisk[pr] = v
}
- ptree, err = gps.ListPackages(r, string(pr))
+ ptree, err = pkgtree.ListPackages(r, string(pr))
if err != nil {
// Any error here other than an a nonexistent dir (which
// can't happen because we covered that case above) is
diff --git a/cmd/dep/remove.go b/cmd/dep/remove.go
index 7a9c6ff5fb..87615608d7 100644
--- a/cmd/dep/remove.go
+++ b/cmd/dep/remove.go
@@ -14,6 +14,7 @@ import (
"github.com/golang/dep"
"github.com/pkg/errors"
"github.com/sdboyer/gps"
+ "github.com/sdboyer/gps/pkgtree"
)
const removeShortHelp = `Remove a dependency from the project`
@@ -61,7 +62,7 @@ func (cmd *removeCommand) Run(ctx *dep.Ctx, args []string) error {
return errors.Wrap(err, "determineProjectRoot")
}
- pkgT, err := gps.ListPackages(p.AbsRoot, cpr)
+ pkgT, err := pkgtree.ListPackages(p.AbsRoot, cpr)
if err != nil {
return errors.Wrap(err, "gps.ListPackages")
}
diff --git a/cmd/dep/status.go b/cmd/dep/status.go
index f1e55858b3..3e683af612 100644
--- a/cmd/dep/status.go
+++ b/cmd/dep/status.go
@@ -17,6 +17,7 @@ import (
"github.com/golang/dep"
"github.com/sdboyer/gps"
+ "github.com/sdboyer/gps/pkgtree"
)
const statusShortHelp = `Report the status of the project's dependencies`
@@ -203,7 +204,7 @@ func runStatusAll(out outputter, p *dep.Project, sm *gps.SourceMgr) error {
// While the network churns on ListVersions() requests, statically analyze
// code from the current project.
- ptree, err := gps.ListPackages(p.AbsRoot, string(p.ImportRoot))
+ ptree, err := pkgtree.ListPackages(p.AbsRoot, string(p.ImportRoot))
if err != nil {
return fmt.Errorf("analysis of local packages failed: %v", err)
}
@@ -368,7 +369,7 @@ func formatVersion(v gps.Version) string {
return v.String()
}
-func collectConstraints(ptree gps.PackageTree, p *dep.Project, sm *gps.SourceMgr) map[string][]gps.Constraint {
+func collectConstraints(ptree pkgtree.PackageTree, p *dep.Project, sm *gps.SourceMgr) map[string][]gps.Constraint {
// TODO
return map[string][]gps.Constraint{}
}
diff --git a/cmd/dep/testdata/harness_tests/ensure/empty/case1/final/lock.json b/cmd/dep/testdata/harness_tests/ensure/empty/case1/final/lock.json
index bab94e010b..4af31ffe93 100644
--- a/cmd/dep/testdata/harness_tests/ensure/empty/case1/final/lock.json
+++ b/cmd/dep/testdata/harness_tests/ensure/empty/case1/final/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "63510efb9632ec69c1164ce396d7ebea4ad3884b4fa508373da17226d5a39739",
+ "memo": "4b36ae008ef4be09dee7e2ae00606d44fd75f4310fd0d0ef6e744690290569de",
"projects": [
{
"name": "github.com/sdboyer/deptest",
diff --git a/cmd/dep/testdata/harness_tests/ensure/empty/case2/final/lock.json b/cmd/dep/testdata/harness_tests/ensure/empty/case2/final/lock.json
index 7836faf3c7..21f628ed00 100644
--- a/cmd/dep/testdata/harness_tests/ensure/empty/case2/final/lock.json
+++ b/cmd/dep/testdata/harness_tests/ensure/empty/case2/final/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "1a99b419931283cb086167ddfb2e8322df12e2648e139eb27a42904360e962ad",
+ "memo": "e7725ea56516a42a641aaaf5d48754258d9f3c59949cb8a0e8a21b1ab6e07179",
"projects": [
{
"name": "github.com/sdboyer/deptest",
diff --git a/cmd/dep/testdata/harness_tests/ensure/override/case1/final/lock.json b/cmd/dep/testdata/harness_tests/ensure/override/case1/final/lock.json
index 9f0acd1845..71cd0988aa 100644
--- a/cmd/dep/testdata/harness_tests/ensure/override/case1/final/lock.json
+++ b/cmd/dep/testdata/harness_tests/ensure/override/case1/final/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "70b47774699956441e395f458714b8e5800b54bebc73b046678245b9e1cfdc3b",
+ "memo": "8bca9526e654e56e05d9075d1f33fa5b649bf6d58aa7d71ca39e7fbea8468e07",
"projects": [
{
"name": "github.com/sdboyer/deptest",
diff --git a/cmd/dep/testdata/harness_tests/ensure/update/case1/final/lock.json b/cmd/dep/testdata/harness_tests/ensure/update/case1/final/lock.json
index c36607c20e..f54aca1056 100644
--- a/cmd/dep/testdata/harness_tests/ensure/update/case1/final/lock.json
+++ b/cmd/dep/testdata/harness_tests/ensure/update/case1/final/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "3ee7126505b016d4b9140dc3521b931380fd9d61fd1d1e6612d6b5b56b21baad",
+ "memo": "1b381263a360eafafe3ef7f9be626672668d17250a3c9a8debd169d1b5e2eebb",
"projects": [
{
"name": "github.com/sdboyer/deptest",
diff --git a/cmd/dep/testdata/harness_tests/ensure/update/case2/testcase.json b/cmd/dep/testdata/harness_tests/ensure/update/case2/testcase.json
index 5be759213e..dd86dd72fc 100644
--- a/cmd/dep/testdata/harness_tests/ensure/update/case2/testcase.json
+++ b/cmd/dep/testdata/harness_tests/ensure/update/case2/testcase.json
@@ -2,5 +2,6 @@
"commands": [
["init"],
["ensure", "-n", "-update", "github.com/sdboyer/deptest"]
- ]
+ ],
+ "vendor-final": []
}
diff --git a/cmd/dep/testdata/harness_tests/init/case2/final/lock.json b/cmd/dep/testdata/harness_tests/init/case2/final/lock.json
index 85a2364c75..876df85036 100644
--- a/cmd/dep/testdata/harness_tests/init/case2/final/lock.json
+++ b/cmd/dep/testdata/harness_tests/init/case2/final/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "1792d407a795640a2b821b350f481bc48852535ed17c98cae2cbe2912a9c3e36",
+ "memo": "88d2718cda70cce45158f953d2c6ead79c1db38e67e9704aff72be8fddb096e7",
"projects": [
{
"name": "github.com/sdboyer/deptest",
diff --git a/cmd/dep/testdata/harness_tests/init/skip-hidden/final/lock.json b/cmd/dep/testdata/harness_tests/init/skip-hidden/final/lock.json
index bab94e010b..4af31ffe93 100644
--- a/cmd/dep/testdata/harness_tests/init/skip-hidden/final/lock.json
+++ b/cmd/dep/testdata/harness_tests/init/skip-hidden/final/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "63510efb9632ec69c1164ce396d7ebea4ad3884b4fa508373da17226d5a39739",
+ "memo": "4b36ae008ef4be09dee7e2ae00606d44fd75f4310fd0d0ef6e744690290569de",
"projects": [
{
"name": "github.com/sdboyer/deptest",
diff --git a/cmd/dep/testdata/harness_tests/remove/force/case1/final/lock.json b/cmd/dep/testdata/harness_tests/remove/force/case1/final/lock.json
index d5c096f360..309f43cbe6 100644
--- a/cmd/dep/testdata/harness_tests/remove/force/case1/final/lock.json
+++ b/cmd/dep/testdata/harness_tests/remove/force/case1/final/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "1792d407a795640a2b821b350f481bc48852535ed17c98cae2cbe2912a9c3e36",
+ "memo": "88d2718cda70cce45158f953d2c6ead79c1db38e67e9704aff72be8fddb096e7",
"projects": [
{
"name": "github.com/sdboyer/deptest",
diff --git a/cmd/dep/testdata/harness_tests/remove/specific/case1/final/lock.json b/cmd/dep/testdata/harness_tests/remove/specific/case1/final/lock.json
index c5e7e1919a..8563f21501 100644
--- a/cmd/dep/testdata/harness_tests/remove/specific/case1/final/lock.json
+++ b/cmd/dep/testdata/harness_tests/remove/specific/case1/final/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "1a90a1bc14e6c5302e5c936186412f7e61e380a3b82afc54ea387f3a237843f8",
+ "memo": "d414dbf5fc668c1085effa68372d02e54b23d058cc66f9fd19ba094c6a946d9b",
"projects": [
{
"name": "github.com/sdboyer/deptest",
diff --git a/cmd/dep/testdata/harness_tests/remove/specific/case2/final/lock.json b/cmd/dep/testdata/harness_tests/remove/specific/case2/final/lock.json
index 37ee11680e..1764a031d8 100644
--- a/cmd/dep/testdata/harness_tests/remove/specific/case2/final/lock.json
+++ b/cmd/dep/testdata/harness_tests/remove/specific/case2/final/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "ffb96eabfbb48ff1ae4f1ad2145a9e765f1e6aef7a3fbfd36a84ad875fcb3585",
+ "memo": "38d8431865759ee3bf28fbdfc464f98ee8b56319394ec717df45e9969544cfca",
"projects": [
{
"name": "github.com/sdboyer/deptest",
diff --git a/cmd/dep/testdata/harness_tests/remove/unused/case1/final/lock.json b/cmd/dep/testdata/harness_tests/remove/unused/case1/final/lock.json
index c5e7e1919a..8563f21501 100644
--- a/cmd/dep/testdata/harness_tests/remove/unused/case1/final/lock.json
+++ b/cmd/dep/testdata/harness_tests/remove/unused/case1/final/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "1a90a1bc14e6c5302e5c936186412f7e61e380a3b82afc54ea387f3a237843f8",
+ "memo": "d414dbf5fc668c1085effa68372d02e54b23d058cc66f9fd19ba094c6a946d9b",
"projects": [
{
"name": "github.com/sdboyer/deptest",
diff --git a/lock.json b/lock.json
index f27282a743..070f270f20 100644
--- a/lock.json
+++ b/lock.json
@@ -1,5 +1,5 @@
{
- "memo": "fc012dfb266db9deec4121dd38069e2556ba66a5514939662da94fac1251996e",
+ "memo": "31a7162c06758e4619ed89b91e1f48bf94ad14f394bbee79299ed0bb5150e409",
"projects": [
{
"name": "github.com/Masterminds/semver",
@@ -11,8 +11,8 @@
},
{
"name": "github.com/Masterminds/vcs",
- "version": "v1.8.0",
- "revision": "fbe9fb6ad5b5f35b3e82a7c21123cfc526cbf895",
+ "version": "v1.11.0",
+ "revision": "795e20f901c3d561de52811fb3488a2cb2c8588b",
"packages": [
"."
]
@@ -35,10 +35,13 @@
},
{
"name": "github.com/sdboyer/gps",
- "version": "v0.14.1",
- "revision": "287edec9f4ca516577cc3ac9744068a34c4c7b08",
+ "version": "v0.15.0",
+ "revision": "b0f646b744e74543c094023d05339ffb82458e35",
"packages": [
- "."
+ ".",
+ "internal",
+ "internal/fs",
+ "pkgtree"
]
}
]
diff --git a/manifest.json b/manifest.json
index 2c5403aa3c..fdbed6a4d1 100644
--- a/manifest.json
+++ b/manifest.json
@@ -10,7 +10,7 @@
"version": ">=0.8.0, <1.0.0"
},
"github.com/sdboyer/gps": {
- "version": ">=0.14.0, <1.0.0"
+ "version": ">=0.15.0, <1.0.0"
}
}
}
diff --git a/vendor/github.com/Masterminds/vcs/.travis.yml b/vendor/github.com/Masterminds/vcs/.travis.yml
index 5c50c4a1cf..47bd9491e9 100644
--- a/vendor/github.com/Masterminds/vcs/.travis.yml
+++ b/vendor/github.com/Masterminds/vcs/.travis.yml
@@ -1,10 +1,9 @@
language: go
go:
- - 1.3
- - 1.4
- - 1.5
- 1.6
+ - 1.7
+ - 1.8
- tip
before_script:
@@ -17,6 +16,10 @@ before_script:
# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
sudo: false
+script:
+ - make setup
+ - make test
+
notifications:
webhooks:
urls:
diff --git a/vendor/github.com/Masterminds/vcs/CHANGELOG.md b/vendor/github.com/Masterminds/vcs/CHANGELOG.md
index 6362674264..4ac3e69202 100644
--- a/vendor/github.com/Masterminds/vcs/CHANGELOG.md
+++ b/vendor/github.com/Masterminds/vcs/CHANGELOG.md
@@ -1,3 +1,43 @@
+# 1.11.0 (2017-03-23)
+
+## Added
+- #65: Exposed CmdFromDir function (thanks @erizocosmico)
+
+## Changed
+- #69: Updated testing for Go 1.8
+
+## Fixed
+- #64: Testing fatal error if bzr not installed (thanks @kevinburke)
+
+# 1.10.2 (2017-01-24)
+
+## Fixed
+- #63: Remove extra quotes in submodule export (thanks @dt)
+
+# 1.10.1 (2017-01-18)
+
+## Fixed
+- #62: Added windows testing via appveyor and fixed issues under windows.
+
+# 1.10.0 (2017-01-09)
+
+## Added
+- #60: Handle Git submodules (thanks @sdboyer)
+- #61: Add gometalinter to testing
+
+# 1.9.0 (2016-11-18)
+
+## Added
+- #50: Auto-detect remotes with file:// prefix.
+- #59: Testing against Go 1.7
+
+## Changed
+- Removed auto-detection for Google Code as the service is deprecated
+- Added auto-detection of git.openstack.org
+
+## Fixed
+- #53: Git not fetching tags off branch
+
# 1.8.0 (2016-06-29)
## Added
diff --git a/vendor/github.com/Masterminds/vcs/Makefile b/vendor/github.com/Masterminds/vcs/Makefile
new file mode 100644
index 0000000000..5d722c2f4b
--- /dev/null
+++ b/vendor/github.com/Masterminds/vcs/Makefile
@@ -0,0 +1,41 @@
+.PHONY: setup
+setup:
+ go get -u gopkg.in/alecthomas/gometalinter.v1
+ gometalinter.v1 --install
+
+.PHONY: test
+test: validate lint
+ @echo "==> Running tests"
+ go test -v
+
+.PHONY: validate
+validate:
+# misspell finds the work adresář (used in bzr.go) as a mispelling of
+# address. It finds adres. An issue has been filed at
+# https://github.com/client9/misspell/issues/99. In the meantime adding
+# adres to the ignore list.
+ @echo "==> Running static validations"
+ @gometalinter.v1 \
+ --disable-all \
+ --linter "misspell:misspell -i adres -j 1 {path}/*.go:PATH:LINE:COL:MESSAGE" \
+ --enable deadcode \
+ --severity deadcode:error \
+ --enable gofmt \
+ --enable gosimple \
+ --enable ineffassign \
+ --enable misspell \
+ --enable vet \
+ --tests \
+ --vendor \
+ --deadline 60s \
+ ./... || exit_code=1
+
+.PHONY: lint
+lint:
+ @echo "==> Running linters"
+ @gometalinter.v1 \
+ --disable-all \
+ --enable golint \
+ --vendor \
+ --deadline 60s \
+ ./... || :
diff --git a/vendor/github.com/Masterminds/vcs/README.md b/vendor/github.com/Masterminds/vcs/README.md
index cdb981fd28..a11268513b 100644
--- a/vendor/github.com/Masterminds/vcs/README.md
+++ b/vendor/github.com/Masterminds/vcs/README.md
@@ -4,6 +4,8 @@ Manage repos in varying version control systems with ease through a common
interface.
[](https://travis-ci.org/Masterminds/vcs) [](https://godoc.org/github.com/Masterminds/vcs) [](https://goreportcard.com/report/github.com/Masterminds/vcs)
+[](https://ci.appveyor.com/project/mattfarina/vcs)
+
## Quick Usage
diff --git a/vendor/github.com/Masterminds/vcs/appveyor.yml b/vendor/github.com/Masterminds/vcs/appveyor.yml
new file mode 100644
index 0000000000..c0c9170fa7
--- /dev/null
+++ b/vendor/github.com/Masterminds/vcs/appveyor.yml
@@ -0,0 +1,26 @@
+
+version: build-{build}.{branch}
+
+clone_folder: C:\gopath\src\github.com\Masterminds\vcs
+shallow_clone: true
+
+environment:
+ GOPATH: C:\gopath
+
+platform:
+ - x64
+
+install:
+ - go version
+ - go env
+ - choco install -y bzr
+ - set PATH=C:\Program Files (x86)\Bazaar;%PATH%
+ - bzr --version
+
+build_script:
+ - go install -v ./...
+
+test_script:
+ - go test -v
+
+deploy: off
diff --git a/vendor/github.com/Masterminds/vcs/bzr.go b/vendor/github.com/Masterminds/vcs/bzr.go
index e8f55b67c1..8343d3ce70 100644
--- a/vendor/github.com/Masterminds/vcs/bzr.go
+++ b/vendor/github.com/Masterminds/vcs/bzr.go
@@ -39,7 +39,7 @@ func NewBzrRepo(remote, local string) (*BzrRepo, error) {
// http://bazaar.launchpad.net/~mattfarina/govcstestbzrrepo/trunk/. Notice
// the change from https to http and the path chance.
// Here we set the remote to be the local one if none is passed in.
- if err == nil && r.CheckLocal() == true && remote == "" {
+ if err == nil && r.CheckLocal() && remote == "" {
c := exec.Command("bzr", "info")
c.Dir = local
c.Env = envForDir(c.Dir)
@@ -226,11 +226,7 @@ func (s *BzrRepo) Tags() ([]string, error) {
// commit id or tag.
func (s *BzrRepo) IsReference(r string) bool {
_, err := s.RunFromDir("bzr", "revno", "-r", r)
- if err == nil {
- return true
- }
-
- return false
+ return err == nil
}
// IsDirty returns if the checkout has been modified from the checked
@@ -308,21 +304,14 @@ func (s *BzrRepo) Ping() bool {
// an error is returned. Launchpad returns a 404 for a codebase that
// does not exist. Otherwise it returns a JSON object describing it.
_, er := get("https://api.launchpad.net/1.0/" + try)
- if er == nil {
- return true
- }
- return false
+ return er == nil
}
}
// This is the same command that Go itself uses but it's not fast (or fast
// enough by my standards). A faster method would be useful.
_, err = s.run("bzr", "info", s.Remote())
- if err != nil {
- return false
- }
-
- return true
+ return err == nil
}
// ExportDir exports the current revision to the passed in directory.
@@ -340,6 +329,7 @@ func (s *BzrRepo) ExportDir(dir string) error {
// https://bazaar.launchpad.net/~bzr-pqm/bzr/bzr.dev/files/head:/po/
func (s *BzrRepo) isUnableToCreateDir(err error) bool {
msg := err.Error()
+
if strings.HasPrefix(msg, fmt.Sprintf("Parent directory of %s does not exist.", s.LocalPath())) ||
strings.HasPrefix(msg, fmt.Sprintf("Nadřazený adresář %s neexistuje.", s.LocalPath())) ||
strings.HasPrefix(msg, fmt.Sprintf("El directorio padre de %s no existe.", s.LocalPath())) ||
diff --git a/vendor/github.com/Masterminds/vcs/bzr_test.go b/vendor/github.com/Masterminds/vcs/bzr_test.go
index e12c6d30b2..4b2e50ec60 100644
--- a/vendor/github.com/Masterminds/vcs/bzr_test.go
+++ b/vendor/github.com/Masterminds/vcs/bzr_test.go
@@ -31,7 +31,7 @@ func TestBzr(t *testing.T) {
repo, err := NewBzrRepo("https://launchpad.net/govcstestbzrrepo", tempDir+"/govcstestbzrrepo")
if err != nil {
- t.Error(err)
+ t.Fatal(err)
}
if repo.Vcs() != Bzr {
@@ -55,7 +55,7 @@ func TestBzr(t *testing.T) {
}
// Verify Bzr repo is a Bzr repo
- if repo.CheckLocal() == false {
+ if !repo.CheckLocal() {
t.Error("Problem checking out repo or Bzr CheckLocal is not working")
}
@@ -75,7 +75,7 @@ func TestBzr(t *testing.T) {
t.Error(nrerr)
}
// Verify the right oject is returned. It will check the local repo type.
- if nrepo.CheckLocal() == false {
+ if !nrepo.CheckLocal() {
t.Error("Wrong version returned from NewRepo")
}
@@ -164,15 +164,15 @@ func TestBzr(t *testing.T) {
t.Error("Bzr is incorrectly returning branches")
}
- if repo.IsReference("1.0.0") != true {
+ if !repo.IsReference("1.0.0") {
t.Error("Bzr is reporting a reference is not one")
}
- if repo.IsReference("foo") == true {
- t.Error("Bzr is reporting a non-existant reference is one")
+ if repo.IsReference("foo") {
+ t.Error("Bzr is reporting a non-existent reference is one")
}
- if repo.IsDirty() == true {
+ if repo.IsDirty() {
t.Error("Bzr incorrectly reporting dirty")
}
@@ -227,7 +227,7 @@ func TestBzr(t *testing.T) {
_, err = os.Stat(filepath.Join(exportDir, string(repo.Vcs())))
if err != nil {
- if found := os.IsNotExist(err); found == false {
+ if found := os.IsNotExist(err); !found {
t.Errorf("Error checking exported metadata in Bzr: %s", err)
}
} else {
@@ -250,7 +250,7 @@ func TestBzrCheckLocal(t *testing.T) {
}()
repo, _ := NewBzrRepo("", tempDir)
- if repo.CheckLocal() == true {
+ if repo.CheckLocal() {
t.Error("Bzr CheckLocal does not identify non-Bzr location")
}
diff --git a/vendor/github.com/Masterminds/vcs/errors.go b/vendor/github.com/Masterminds/vcs/errors.go
index ea8c5fc30d..be7097040d 100644
--- a/vendor/github.com/Masterminds/vcs/errors.go
+++ b/vendor/github.com/Masterminds/vcs/errors.go
@@ -5,7 +5,7 @@ import "errors"
// The vcs package provides ways to work with errors that hide the underlying
// implementation details but make them accessible if needed. For basic errors
// that do not have underlying implementation specific details or the underlying
-// details are likely not necessairy there are errors for comparison.
+// details are not necessary there are errors for comparison.
//
// For example:
//
diff --git a/vendor/github.com/Masterminds/vcs/git.go b/vendor/github.com/Masterminds/vcs/git.go
index eb4b86e9e1..c9e17ca750 100644
--- a/vendor/github.com/Masterminds/vcs/git.go
+++ b/vendor/github.com/Masterminds/vcs/git.go
@@ -33,7 +33,7 @@ func NewGitRepo(remote, local string) (*GitRepo, error) {
// Make sure the local Git repo is configured the same as the remote when
// A remote value was passed in.
- if err == nil && r.CheckLocal() == true {
+ if err == nil && r.CheckLocal() {
c := exec.Command("git", "config", "--get", "remote.origin.url")
c.Dir = local
c.Env = envForDir(c.Dir)
@@ -70,7 +70,7 @@ func (s GitRepo) Vcs() Type {
// Get is used to perform an initial clone of a repository.
func (s *GitRepo) Get() error {
- out, err := s.run("git", "clone", s.Remote(), s.LocalPath())
+ out, err := s.run("git", "clone", "--recursive", s.Remote(), s.LocalPath())
// There are some windows cases where Git cannot create the parent directory,
// if it does not already exist, to the location it's trying to create the
@@ -131,7 +131,7 @@ func (s *GitRepo) Init() error {
// Update performs an Git fetch and pull to an existing checkout.
func (s *GitRepo) Update() error {
// Perform a fetch to make sure everything is up to date.
- out, err := s.RunFromDir("git", "fetch", s.RemoteLocation)
+ out, err := s.RunFromDir("git", "fetch", "--tags", s.RemoteLocation)
if err != nil {
return NewRemoteError("Unable to update repository", err, string(out))
}
@@ -143,7 +143,7 @@ func (s *GitRepo) Update() error {
return NewLocalError("Unable to update repository", err, "")
}
- if detached == true {
+ if detached {
return nil
}
@@ -151,7 +151,8 @@ func (s *GitRepo) Update() error {
if err != nil {
return NewRemoteError("Unable to update repository", err, string(out))
}
- return nil
+
+ return s.defendAgainstSubmodules()
}
// UpdateVersion sets the version of a package currently checked out via Git.
@@ -160,6 +161,30 @@ func (s *GitRepo) UpdateVersion(version string) error {
if err != nil {
return NewLocalError("Unable to update checked out version", err, string(out))
}
+
+ return s.defendAgainstSubmodules()
+}
+
+// defendAgainstSubmodules tries to keep repo state sane in the event of
+// submodules. Or nested submodules. What a great idea, submodules.
+func (s *GitRepo) defendAgainstSubmodules() error {
+ // First, update them to whatever they should be, if there should happen to be any.
+ out, err := s.RunFromDir("git", "submodule", "update", "--init", "--recursive")
+ if err != nil {
+ return NewLocalError("Unexpected error while defensively updating submodules", err, string(out))
+ }
+ // Now, do a special extra-aggressive clean in case changing versions caused
+ // one or more submodules to go away.
+ out, err = s.RunFromDir("git", "clean", "-x", "-d", "-f", "-f")
+ if err != nil {
+ return NewLocalError("Unexpected error while defensively cleaning up after possible derelict submodule directories", err, string(out))
+ }
+ // Then, repeat just in case there are any nested submodules that went away.
+ out, err = s.RunFromDir("git", "submodule", "foreach", "--recursive", "git", "clean", "-x", "-d", "-f", "-f")
+ if err != nil {
+ return NewLocalError("Unexpected error while defensively cleaning up after possible derelict nested submodule directories", err, string(out))
+ }
+
return nil
}
@@ -255,11 +280,7 @@ func (s *GitRepo) IsReference(r string) bool {
// not been checked out yet. This next step should pickup the other
// possible references.
_, err = s.RunFromDir("git", "show-ref", r)
- if err == nil {
- return true
- }
-
- return false
+ return err == nil
}
// IsDirty returns if the checkout has been modified from the checked
@@ -339,11 +360,7 @@ func (s *GitRepo) Ping() bool {
// remote needs to be different.
c.Env = mergeEnvLists([]string{"GIT_TERMINAL_PROMPT=0"}, os.Environ())
_, err := c.CombinedOutput()
- if err != nil {
- return false
- }
-
- return true
+ return err == nil
}
// ExportDir exports the current revision to the passed in directory.
@@ -354,11 +371,25 @@ func (s *GitRepo) ExportDir(dir string) error {
dir = dir + string(os.PathSeparator)
}
+ // checkout-index on some systems, such as some Windows cases, does not
+ // create the parent directory to export into if it does not exist. Explicitly
+ // creating it.
+ err := os.MkdirAll(dir, 0755)
+ if err != nil {
+ return NewLocalError("Unable to create directory", err, "")
+ }
+
out, err := s.RunFromDir("git", "checkout-index", "-f", "-a", "--prefix="+dir)
s.log(out)
if err != nil {
return NewLocalError("Unable to export source", err, string(out))
}
+ // and now, the horror of submodules
+ out, err = s.RunFromDir("git", "submodule", "foreach", "--recursive", "git checkout-index -f -a --prefix=\""+filepath.Join(dir, "$path")+string(filepath.Separator)+"\"")
+ s.log(out)
+ if err != nil {
+ return NewLocalError("Error while exporting submodule sources", err, string(out))
+ }
return nil
}
diff --git a/vendor/github.com/Masterminds/vcs/git_test.go b/vendor/github.com/Masterminds/vcs/git_test.go
index 80eae55ae2..7c6e093399 100644
--- a/vendor/github.com/Masterminds/vcs/git_test.go
+++ b/vendor/github.com/Masterminds/vcs/git_test.go
@@ -1,6 +1,7 @@
package vcs
import (
+ "fmt"
"io/ioutil"
"path/filepath"
"time"
@@ -53,7 +54,7 @@ func TestGit(t *testing.T) {
}
// Verify Git repo is a Git repo
- if repo.CheckLocal() == false {
+ if !repo.CheckLocal() {
t.Error("Problem checking out repo or Git CheckLocal is not working")
}
@@ -73,7 +74,7 @@ func TestGit(t *testing.T) {
t.Error(nrerr)
}
// Verify the right oject is returned. It will check the local repo type.
- if nrepo.CheckLocal() == false {
+ if !nrepo.CheckLocal() {
t.Error("Wrong version returned from NewRepo")
}
@@ -153,8 +154,23 @@ func TestGit(t *testing.T) {
if err != nil {
t.Error(err)
}
- if tags[0] != "1.0.0" {
- t.Error("Git tags is not reporting the correct version")
+
+ var hasRelTag bool
+ var hasOffMasterTag bool
+
+ for _, tv := range tags {
+ if tv == "1.0.0" {
+ hasRelTag = true
+ } else if tv == "off-master-tag" {
+ hasOffMasterTag = true
+ }
+ }
+
+ if !hasRelTag {
+ t.Error("Git tags unable to find release tag on master")
+ }
+ if !hasOffMasterTag {
+ t.Error("Git tags did not fetch tags not on master")
}
tags, err = repo.TagsFromCommit("74dd547545b7df4aa285bcec1b54e2b76f726395")
@@ -177,20 +193,20 @@ func TestGit(t *testing.T) {
if err != nil {
t.Error(err)
}
- // The branches should be HEAD, master, and test.
- if branches[2] != "test" {
+ // The branches should be HEAD, master, other, and test.
+ if branches[3] != "test" {
t.Error("Git is incorrectly returning branches")
}
- if repo.IsReference("1.0.0") != true {
+ if !repo.IsReference("1.0.0") {
t.Error("Git is reporting a reference is not one")
}
- if repo.IsReference("foo") == true {
- t.Error("Git is reporting a non-existant reference is one")
+ if repo.IsReference("foo") {
+ t.Error("Git is reporting a non-existent reference is one")
}
- if repo.IsDirty() == true {
+ if repo.IsDirty() {
t.Error("Git incorrectly reporting dirty")
}
@@ -245,7 +261,7 @@ func TestGit(t *testing.T) {
_, err = os.Stat(filepath.Join(exportDir, string(repo.Vcs())))
if err != nil {
- if found := os.IsNotExist(err); found == false {
+ if found := os.IsNotExist(err); !found {
t.Errorf("Error checking exported metadata in Git: %s", err)
}
} else {
@@ -268,7 +284,7 @@ func TestGitCheckLocal(t *testing.T) {
}()
repo, _ := NewGitRepo("", tempDir)
- if repo.CheckLocal() == true {
+ if repo.CheckLocal() {
t.Error("Git CheckLocal does not identify non-Git location")
}
@@ -341,3 +357,128 @@ func TestGitInit(t *testing.T) {
t.Error(err)
}
}
+
+func TestGitSubmoduleHandling(t *testing.T) {
+ tempDir, err := ioutil.TempDir("", "go-vcs-git-submodule-tests")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer func() {
+ err = os.RemoveAll(tempDir)
+ if err != nil {
+ t.Error(err)
+ }
+ }()
+
+ dumplocal := func(err error) string {
+ if terr, ok := err.(*LocalError); ok {
+ return fmt.Sprintf("msg: %s\norig: %s\nout: %s", terr.Error(), terr.Original(), terr.Out())
+ }
+ return err.Error()
+ }
+
+ subdirExists := func(dir ...string) bool {
+ _, err := os.Stat(filepath.Join(append([]string{tempDir}, dir...)...))
+ return err == nil
+ }
+
+ // Initial clone should get version with two submodules, each of which have
+ // their own submodule
+ repo, err := NewGitRepo("https://github.com/sdboyer/subm", tempDir)
+ if err != nil {
+ t.Fatal(dumplocal(err))
+ }
+ err = repo.Get()
+ if err != nil {
+ t.Fatalf("unable to clone Git repo. Err was %s", dumplocal(err))
+ }
+
+ // Verify we are on the right version.
+ v, err := repo.Version()
+ if v != "18e3a5f6fc7f6d577e732e7a5ab2caf990efbf8f" {
+ t.Fatalf("did not start from expected rev, tests could fail - bailing out (got %s)", v)
+ }
+ if err != nil {
+ t.Fatal(dumplocal(err))
+ }
+
+ if !subdirExists("subm1", ".git") {
+ t.Fatal("subm1 submodule does not exist on initial clone/checkout")
+ }
+ if !subdirExists("subm1", "dep-test", ".git") {
+ t.Fatal("dep-test submodule nested under subm1 does not exist on initial clone/checkout")
+ }
+
+ if !subdirExists("subm-again", ".git") {
+ t.Fatal("subm-again submodule does not exist on initial clone/checkout")
+ }
+ if !subdirExists("subm-again", "dep-test", ".git") {
+ t.Fatal("dep-test submodule nested under subm-again does not exist on initial clone/checkout")
+ }
+
+ // Now switch to version with no submodules, make sure they all go away
+ err = repo.UpdateVersion("e677f82015f72ac1c8fafa66b5463163b3597af2")
+ if err != nil {
+ t.Fatalf("checking out needed version failed with err: %s", dumplocal(err))
+ }
+
+ if subdirExists("subm1") {
+ t.Fatal("checking out version without submodule did not clean up immediate submodules")
+ }
+ if subdirExists("subm1", "dep-test") {
+ t.Fatal("checking out version without submodule did not clean up nested submodules")
+ }
+ if subdirExists("subm-again") {
+ t.Fatal("checking out version without submodule did not clean up immediate submodules")
+ }
+ if subdirExists("subm-again", "dep-test") {
+ t.Fatal("checking out version without submodule did not clean up nested submodules")
+ }
+
+ err = repo.UpdateVersion("aaf7aa1bc4c3c682cc530eca8f80417088ee8540")
+ if err != nil {
+ t.Fatalf("checking out needed version failed with err: %s", dumplocal(err))
+ }
+
+ if !subdirExists("subm1", ".git") {
+ t.Fatal("checking out version with immediate submodule did not set up git subrepo")
+ }
+
+ err = repo.UpdateVersion("6cc4669af468f3b4f16e7e96275ad01ade5b522f")
+ if err != nil {
+ t.Fatalf("checking out needed version failed with err: %s", dumplocal(err))
+ }
+
+ if !subdirExists("subm1", "dep-test", ".git") {
+ t.Fatal("checking out version with nested submodule did not set up nested git subrepo")
+ }
+
+ err = repo.UpdateVersion("aaf7aa1bc4c3c682cc530eca8f80417088ee8540")
+ if err != nil {
+ t.Fatalf("checking out needed version failed with err: %s", dumplocal(err))
+ }
+
+ if subdirExists("subm1", "dep-test") {
+ t.Fatal("rolling back to version without nested submodule did not clean up the nested submodule")
+ }
+
+ err = repo.UpdateVersion("18e3a5f6fc7f6d577e732e7a5ab2caf990efbf8f")
+ if err != nil {
+ t.Fatalf("checking out needed version failed with err: %s", dumplocal(err))
+ }
+
+ if !subdirExists("subm1", ".git") {
+ t.Fatal("subm1 submodule does not exist after switch from other commit")
+ }
+ if !subdirExists("subm1", "dep-test", ".git") {
+ t.Fatal("dep-test submodule nested under subm1 does not exist after switch from other commit")
+ }
+
+ if !subdirExists("subm-again", ".git") {
+ t.Fatal("subm-again submodule does not exist after switch from other commit")
+ }
+ if !subdirExists("subm-again", "dep-test", ".git") {
+ t.Fatal("dep-test submodule nested under subm-again does not exist after switch from other commit")
+ }
+
+}
diff --git a/vendor/github.com/Masterminds/vcs/hg.go b/vendor/github.com/Masterminds/vcs/hg.go
index df41cd6259..5000a6d9da 100644
--- a/vendor/github.com/Masterminds/vcs/hg.go
+++ b/vendor/github.com/Masterminds/vcs/hg.go
@@ -32,7 +32,7 @@ func NewHgRepo(remote, local string) (*HgRepo, error) {
// Make sure the local Hg repo is configured the same as the remote when
// A remote value was passed in.
- if err == nil && r.CheckLocal() == true {
+ if err == nil && r.CheckLocal() {
// An Hg repo was found so test that the URL there matches
// the repo passed in here.
c := exec.Command("hg", "paths")
@@ -207,11 +207,7 @@ func (s *HgRepo) Tags() ([]string, error) {
// commit id, branch, or tag.
func (s *HgRepo) IsReference(r string) bool {
_, err := s.RunFromDir("hg", "log", "-r", r)
- if err == nil {
- return true
- }
-
- return false
+ return err == nil
}
// IsDirty returns if the checkout has been modified from the checked
@@ -305,11 +301,7 @@ func (s *HgRepo) TagsFromCommit(id string) ([]string, error) {
// Ping returns if remote location is accessible.
func (s *HgRepo) Ping() bool {
_, err := s.run("hg", "identify", s.Remote())
- if err != nil {
- return false
- }
-
- return true
+ return err == nil
}
// ExportDir exports the current revision to the passed in directory.
diff --git a/vendor/github.com/Masterminds/vcs/hg_test.go b/vendor/github.com/Masterminds/vcs/hg_test.go
index b8aa39a114..6b19f72809 100644
--- a/vendor/github.com/Masterminds/vcs/hg_test.go
+++ b/vendor/github.com/Masterminds/vcs/hg_test.go
@@ -55,7 +55,7 @@ func TestHg(t *testing.T) {
}
// Verify Hg repo is a Hg repo
- if repo.CheckLocal() == false {
+ if !repo.CheckLocal() {
t.Error("Problem checking out repo or Hg CheckLocal is not working")
}
@@ -75,7 +75,7 @@ func TestHg(t *testing.T) {
t.Error(nrerr)
}
// Verify the right oject is returned. It will check the local repo type.
- if nrepo.CheckLocal() == false {
+ if !nrepo.CheckLocal() {
t.Error("Wrong version returned from NewRepo")
}
@@ -166,19 +166,19 @@ func TestHg(t *testing.T) {
t.Error("Hg is incorrectly returning branches")
}
- if repo.IsReference("1.0.0") != true {
+ if !repo.IsReference("1.0.0") {
t.Error("Hg is reporting a reference is not one")
}
- if repo.IsReference("test") != true {
+ if !repo.IsReference("test") {
t.Error("Hg is reporting a reference is not one")
}
- if repo.IsReference("foo") == true {
- t.Error("Hg is reporting a non-existant reference is one")
+ if repo.IsReference("foo") {
+ t.Error("Hg is reporting a non-existent reference is one")
}
- if repo.IsDirty() == true {
+ if repo.IsDirty() {
t.Error("Hg incorrectly reporting dirty")
}
@@ -231,7 +231,7 @@ func TestHg(t *testing.T) {
_, err = os.Stat(filepath.Join(exportDir, string(repo.Vcs())))
if err != nil {
- if found := os.IsNotExist(err); found == false {
+ if found := os.IsNotExist(err); !found {
t.Errorf("Error checking exported metadata in Hg: %s", err)
}
} else {
@@ -254,7 +254,7 @@ func TestHgCheckLocal(t *testing.T) {
}()
repo, _ := NewHgRepo("", tempDir)
- if repo.CheckLocal() == true {
+ if repo.CheckLocal() {
t.Error("Hg CheckLocal does not identify non-Hg location")
}
diff --git a/vendor/github.com/Masterminds/vcs/repo.go b/vendor/github.com/Masterminds/vcs/repo.go
index 1298a5f927..356dad6f9f 100644
--- a/vendor/github.com/Masterminds/vcs/repo.go
+++ b/vendor/github.com/Masterminds/vcs/repo.go
@@ -130,6 +130,10 @@ type Repo interface {
// RunFromDir executes a command from repo's directory.
RunFromDir(cmd string, args ...string) ([]byte, error)
+ // CmdFromDir creates a new command that will be executed from repo's
+ // directory.
+ CmdFromDir(cmd string, args ...string) *exec.Cmd
+
// ExportDir exports the current revision to the passed in directory.
ExportDir(string) error
}
@@ -220,10 +224,15 @@ func (b base) run(cmd string, args ...string) ([]byte, error) {
return out, err
}
-func (b *base) RunFromDir(cmd string, args ...string) ([]byte, error) {
+func (b *base) CmdFromDir(cmd string, args ...string) *exec.Cmd {
c := exec.Command(cmd, args...)
c.Dir = b.local
c.Env = envForDir(c.Dir)
+ return c
+}
+
+func (b *base) RunFromDir(cmd string, args ...string) ([]byte, error) {
+ c := b.CmdFromDir(cmd, args...)
out, err := c.CombinedOutput()
return out, err
}
diff --git a/vendor/github.com/Masterminds/vcs/repo_test.go b/vendor/github.com/Masterminds/vcs/repo_test.go
index d61f6cbea9..8c083b3fc4 100644
--- a/vendor/github.com/Masterminds/vcs/repo_test.go
+++ b/vendor/github.com/Masterminds/vcs/repo_test.go
@@ -46,7 +46,7 @@ func TestTypeSwitch(t *testing.T) {
}
}()
- repo, err := NewSvnRepo("https://github.com/Masterminds/VCSTestRepo/trunk", tempDir+"/VCSTestRepo")
+ repo, err := NewSvnRepo("https://github.com/Masterminds/VCSTestRepo/trunk", tempDir+string(os.PathSeparator)+"VCSTestRepo")
if err != nil {
t.Error(err)
}
@@ -55,7 +55,7 @@ func TestTypeSwitch(t *testing.T) {
t.Errorf("Unable to checkout SVN repo for repo switching tests. Err was %s", err)
}
- _, err = NewRepo("https://github.com/Masterminds/VCSTestRepo", tempDir+"/VCSTestRepo")
+ _, err = NewRepo("https://github.com/Masterminds/VCSTestRepo", tempDir+string(os.PathSeparator)+"VCSTestRepo")
if err != ErrWrongVCS {
t.Errorf("Not detecting repo switch from SVN to Git")
}
@@ -63,12 +63,12 @@ func TestTypeSwitch(t *testing.T) {
func TestDepInstalled(t *testing.T) {
i := depInstalled("git")
- if i != true {
+ if !i {
t.Error("depInstalled not finding installed dep.")
}
i = depInstalled("thisreallyisntinstalled")
- if i != false {
+ if i {
t.Error("depInstalled finding not installed dep.")
}
}
diff --git a/vendor/github.com/Masterminds/vcs/svn.go b/vendor/github.com/Masterminds/vcs/svn.go
index 888ae09553..913f90a8f0 100644
--- a/vendor/github.com/Masterminds/vcs/svn.go
+++ b/vendor/github.com/Masterminds/vcs/svn.go
@@ -6,6 +6,7 @@ import (
"os"
"os/exec"
"path/filepath"
+ "runtime"
"strings"
"time"
)
@@ -33,7 +34,7 @@ func NewSvnRepo(remote, local string) (*SvnRepo, error) {
// Make sure the local SVN repo is configured the same as the remote when
// A remote value was passed in.
- if err == nil && r.CheckLocal() == true {
+ if err == nil && r.CheckLocal() {
// An SVN repo was found so test that the URL there matches
// the repo passed in here.
out, err := exec.Command("svn", "info", local).CombinedOutput()
@@ -76,6 +77,8 @@ func (s *SvnRepo) Get() error {
remote := s.Remote()
if strings.HasPrefix(remote, "/") {
remote = "file://" + remote
+ } else if runtime.GOOS == "windows" && filepath.VolumeName(remote) != "" {
+ remote = "file:///" + remote
}
out, err := s.run("svn", "checkout", remote, s.LocalPath())
if err != nil {
@@ -139,6 +142,9 @@ func (s *SvnRepo) Version() (string, error) {
}
out, err := s.RunFromDir("svn", "info", "--xml")
+ if err != nil {
+ return "", NewLocalError("Unable to retrieve checked out version", err, string(out))
+ }
s.log(out)
infos := &Info{}
err = xml.Unmarshal(out, &infos)
@@ -180,8 +186,8 @@ func (s *SvnRepo) Date() (time.Time, error) {
if err != nil {
return time.Time{}, NewLocalError("Unable to retrieve revision date", err, string(out))
}
- const longForm = "2006-01-02T15:04:05.000000Z\n"
- t, err := time.Parse(longForm, string(out))
+ const longForm = "2006-01-02T15:04:05.000000Z"
+ t, err := time.Parse(longForm, strings.TrimSpace(string(out)))
if err != nil {
return time.Time{}, NewLocalError("Unable to retrieve revision date", err, string(out))
}
@@ -190,14 +196,24 @@ func (s *SvnRepo) Date() (time.Time, error) {
// CheckLocal verifies the local location is an SVN repo.
func (s *SvnRepo) CheckLocal() bool {
- sep := fmt.Sprintf("%c", os.PathSeparator)
- psplit := strings.Split(s.LocalPath(), sep)
- for i := 0; i < len(psplit); i++ {
- path := fmt.Sprintf("%s%s", sep, filepath.Join(psplit[0:(len(psplit)-(i))]...))
- if _, err := os.Stat(filepath.Join(path, ".svn")); err == nil {
+ pth, err := filepath.Abs(s.LocalPath())
+ if err != nil {
+ s.log(err.Error())
+ return false
+ }
+
+ if _, err := os.Stat(filepath.Join(pth, ".svn")); err == nil {
+ return true
+ }
+
+ oldpth := pth
+ for oldpth != pth {
+ pth = filepath.Dir(pth)
+ if _, err := os.Stat(filepath.Join(pth, ".svn")); err == nil {
return true
}
}
+
return false
}
@@ -261,6 +277,9 @@ func (s *SvnRepo) CommitInfo(id string) (*CommitInfo, error) {
}
out, err := s.RunFromDir("svn", "info", "-r", id, "--xml")
+ if err != nil {
+ return nil, NewLocalError("Unable to retrieve commit information", err, string(out))
+ }
infos := &Info{}
err = xml.Unmarshal(out, &infos)
if err != nil {
@@ -323,11 +342,7 @@ func (s *SvnRepo) TagsFromCommit(id string) ([]string, error) {
// Ping returns if remote location is accessible.
func (s *SvnRepo) Ping() bool {
_, err := s.run("svn", "--non-interactive", "info", s.Remote())
- if err != nil {
- return false
- }
-
- return true
+ return err == nil
}
// ExportDir exports the current revision to the passed in directory.
@@ -346,11 +361,7 @@ func (s *SvnRepo) ExportDir(dir string) error {
// where the parent directory of the VCS local path doesn't exist.
func (s *SvnRepo) isUnableToCreateDir(err error) bool {
msg := err.Error()
- if strings.HasPrefix(msg, "E000002") {
- return true
- }
-
- return false
+ return strings.HasPrefix(msg, "E000002")
}
// detectRemoteFromInfoCommand finds the remote url from the `svn info`
diff --git a/vendor/github.com/Masterminds/vcs/svn_test.go b/vendor/github.com/Masterminds/vcs/svn_test.go
index d242f3eedd..93fc139ab9 100644
--- a/vendor/github.com/Masterminds/vcs/svn_test.go
+++ b/vendor/github.com/Masterminds/vcs/svn_test.go
@@ -28,7 +28,7 @@ func TestSvn(t *testing.T) {
}
}()
- repo, err := NewSvnRepo("https://github.com/Masterminds/VCSTestRepo/trunk", tempDir+"/VCSTestRepo")
+ repo, err := NewSvnRepo("https://github.com/Masterminds/VCSTestRepo/trunk", tempDir+string(os.PathSeparator)+"VCSTestRepo")
if err != nil {
t.Error(err)
}
@@ -41,7 +41,7 @@ func TestSvn(t *testing.T) {
if repo.Remote() != "https://github.com/Masterminds/VCSTestRepo/trunk" {
t.Error("Remote not set properly")
}
- if repo.LocalPath() != tempDir+"/VCSTestRepo" {
+ if repo.LocalPath() != tempDir+string(os.PathSeparator)+"VCSTestRepo" {
t.Error("Local disk location not set properly")
}
@@ -54,7 +54,7 @@ func TestSvn(t *testing.T) {
}
// Verify SVN repo is a SVN repo
- if repo.CheckLocal() == false {
+ if !repo.CheckLocal() {
t.Error("Problem checking out repo or SVN CheckLocal is not working")
}
@@ -167,15 +167,15 @@ func TestSvn(t *testing.T) {
t.Error("Svn is incorrectly returning branches")
}
- if repo.IsReference("r4") != true {
+ if !repo.IsReference("r4") {
t.Error("Svn is reporting a reference is not one")
}
- if repo.IsReference("55") == true {
- t.Error("Svn is reporting a non-existant reference is one")
+ if repo.IsReference("55") {
+ t.Error("Svn is reporting a non-existent reference is one")
}
- if repo.IsDirty() == true {
+ if repo.IsDirty() {
t.Error("Svn incorrectly reporting dirty")
}
@@ -230,7 +230,7 @@ func TestSvn(t *testing.T) {
_, err = os.Stat(filepath.Join(exportDir, string(repo.Vcs())))
if err != nil {
- if found := os.IsNotExist(err); found == false {
+ if found := os.IsNotExist(err); !found {
t.Errorf("Error checking exported metadata in Svn: %s", err)
}
} else {
@@ -253,7 +253,7 @@ func TestSvnCheckLocal(t *testing.T) {
}()
repo, _ := NewSvnRepo("", tempDir)
- if repo.CheckLocal() == true {
+ if repo.CheckLocal() {
t.Error("SVN CheckLocal does not identify non-SVN location")
}
@@ -300,8 +300,8 @@ func TestSvnPing(t *testing.T) {
func TestSvnInit(t *testing.T) {
tempDir, err := ioutil.TempDir("", "go-vcs-svn-tests")
- remoteDir := tempDir + "/remoteDir"
- localDir := tempDir + "/localDir"
+ remoteDir := tempDir + string(os.PathSeparator) + "remoteDir"
+ localDir := tempDir + string(os.PathSeparator) + "localDir"
if err != nil {
t.Error(err)
}
diff --git a/vendor/github.com/Masterminds/vcs/vcs_local_lookup.go b/vendor/github.com/Masterminds/vcs/vcs_local_lookup.go
index f965132b03..09f6e22ebe 100644
--- a/vendor/github.com/Masterminds/vcs/vcs_local_lookup.go
+++ b/vendor/github.com/Masterminds/vcs/vcs_local_lookup.go
@@ -2,12 +2,20 @@ package vcs
import (
"os"
+ "runtime"
+ "strings"
)
// DetectVcsFromFS detects the type from the local path.
// Is there a better way to do this?
func DetectVcsFromFS(vcsPath string) (Type, error) {
+ // There are cases under windows that a path could start with a / and it needs
+ // to be stripped. For example, a path such as /C:\foio\bar.
+ if runtime.GOOS == "windows" && strings.HasPrefix(vcsPath, "/") {
+ vcsPath = strings.TrimPrefix(vcsPath, "/")
+ }
+
// When the local directory to the package doesn't exist
// it's not yet downloaded so we can't detect the type
// locally.
@@ -15,20 +23,20 @@ func DetectVcsFromFS(vcsPath string) (Type, error) {
return "", ErrCannotDetectVCS
}
- seperator := string(os.PathSeparator)
+ separator := string(os.PathSeparator)
// Walk through each of the different VCS types to see if
// one can be detected. Do this is order of guessed popularity.
- if _, err := os.Stat(vcsPath + seperator + ".git"); err == nil {
+ if _, err := os.Stat(vcsPath + separator + ".git"); err == nil {
return Git, nil
}
- if _, err := os.Stat(vcsPath + seperator + ".svn"); err == nil {
+ if _, err := os.Stat(vcsPath + separator + ".svn"); err == nil {
return Svn, nil
}
- if _, err := os.Stat(vcsPath + seperator + ".hg"); err == nil {
+ if _, err := os.Stat(vcsPath + separator + ".hg"); err == nil {
return Hg, nil
}
- if _, err := os.Stat(vcsPath + seperator + ".bzr"); err == nil {
+ if _, err := os.Stat(vcsPath + separator + ".bzr"); err == nil {
return Bzr, nil
}
diff --git a/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go b/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go
index 0567af8b19..6689f957f1 100644
--- a/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go
+++ b/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go
@@ -55,16 +55,10 @@ var vcsList = []*vcsInfo{
vcs: Git,
pattern: `^(go\.googlesource\.com/[A-Za-z0-9_.\-]+/?)$`,
},
- // TODO: Once Google Code becomes fully deprecated this can be removed.
{
- host: "code.google.com",
- addCheck: checkGoogle,
- pattern: `^(code\.google\.com/[pr]/(?P[a-z0-9\-]+)(\.(?P[a-z0-9\-]+))?)(/[A-Za-z0-9_.\-]+)*$`,
- },
- // Alternative Google setup. This is the previous structure but it still works... until Google Code goes away.
- {
- addCheck: checkURL,
- pattern: `^([a-z0-9_\-.]+)\.googlecode\.com/(?Pgit|hg|svn)(/.*)?$`,
+ host: "git.openstack.org",
+ vcs: Git,
+ pattern: `^(git\.openstack\.org/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+)$`,
},
// If none of the previous detect the type they will fall to this looking for the type in a generic sense
// by the extension to the path.
@@ -158,6 +152,11 @@ func detectVcsFromURL(vcsURL string) (Type, error) {
}
}
+ // Detect file schemes
+ if u.Scheme == "file" {
+ return DetectVcsFromFS(u.Path)
+ }
+
if u.Host == "" {
return "", ErrCannotDetectVCS
}
@@ -267,37 +266,6 @@ func checkBitbucket(i map[string]string, ul *url.URL) (Type, error) {
}
-// Google supports Git, Hg, and Svn. The SVN style is only
-// supported through their legacy setup at .googlecode.com.
-// I wonder if anyone is actually using SVN support.
-func checkGoogle(i map[string]string, u *url.URL) (Type, error) {
-
- // To figure out which of the VCS types is used in Google Code you need
- // to parse a web page and find it. Ugh. I mean... ugh.
- var hack = regexp.MustCompile(`id="checkoutcmd">(hg|git|svn)`)
-
- d, err := get(expand(i, "https://code.google.com/p/{project}/source/checkout?repo={repo}"))
- if err != nil {
- return "", err
- }
-
- if m := hack.FindSubmatch(d); m != nil {
- if vcs := string(m[1]); vcs != "" {
- if vcs == "svn" {
- // While Google supports SVN it can only be used with the legacy
- // urls of .googlecode.com. I considered creating a new
- // error for this problem but Google Code is going away and there
- // is support for the legacy structure.
- return "", ErrCannotDetectVCS
- }
-
- return Type(vcs), nil
- }
- }
-
- return "", ErrCannotDetectVCS
-}
-
// Expect a type key on i with the exact type detected from the regex.
func checkURL(i map[string]string, u *url.URL) (Type, error) {
return Type(i["type"]), nil
diff --git a/vendor/github.com/Masterminds/vcs/vcs_remote_lookup_test.go b/vendor/github.com/Masterminds/vcs/vcs_remote_lookup_test.go
index e97bba8297..938cb0ebc5 100644
--- a/vendor/github.com/Masterminds/vcs/vcs_remote_lookup_test.go
+++ b/vendor/github.com/Masterminds/vcs/vcs_remote_lookup_test.go
@@ -1,6 +1,10 @@
package vcs
import (
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "runtime"
"strings"
"testing"
)
@@ -24,8 +28,6 @@ func TestVCSLookup(t *testing.T) {
"https://hub.jazz.net/git/user1/pkgname": {work: true, t: Git},
"https://hub.jazz.net/git/user1/pkgname/subpkg/subpkg/subpkg": {work: true, t: Git},
"https://hubs.jazz.net/git/user1/pkgname": {work: false, t: Git},
- "http://farbtastic.googlecode.com/svn/": {work: true, t: Svn},
- "http://farbtastic.googlecode.com/svn/trunk": {work: true, t: Svn},
"https://example.com/foo/bar.git": {work: true, t: Git},
"https://example.com/foo/bar.svn": {work: true, t: Svn},
"https://example.com/foo/bar/baz.bzr": {work: true, t: Bzr},
@@ -33,6 +35,7 @@ func TestVCSLookup(t *testing.T) {
"https://gopkg.in/tomb.v1": {work: true, t: Git},
"https://golang.org/x/net": {work: true, t: Git},
"https://speter.net/go/exp/math/dec/inf": {work: true, t: Git},
+ "https://git.openstack.org/foo/bar": {work: true, t: Git},
"git@github.com:Masterminds/vcs.git": {work: true, t: Git},
"git@example.com:foo.git": {work: true, t: Git},
"ssh://hg@bitbucket.org/mattfarina/testhgrepo": {work: true, t: Hg},
@@ -47,15 +50,15 @@ func TestVCSLookup(t *testing.T) {
for u, c := range urlList {
ty, _, err := detectVcsFromRemote(u)
- if err == nil && c.work == false {
+ if err == nil && !c.work {
t.Errorf("Error detecting VCS from URL(%s)", u)
}
- if err == ErrCannotDetectVCS && c.work == true {
+ if err == ErrCannotDetectVCS && c.work {
t.Errorf("Error detecting VCS from URL(%s)", u)
}
- if err != nil && c.work == true {
+ if err != nil && c.work {
t.Errorf("Error detecting VCS from URL(%s): %s", u, err)
}
@@ -63,16 +66,52 @@ func TestVCSLookup(t *testing.T) {
err != ErrCannotDetectVCS &&
!strings.HasSuffix(err.Error(), "Not Found") &&
!strings.HasSuffix(err.Error(), "Access Denied") &&
- c.work == false {
+ !c.work {
t.Errorf("Unexpected error returned (%s): %s", u, err)
}
- if c.work == true && ty != c.t {
+ if c.work && ty != c.t {
t.Errorf("Incorrect VCS type returned(%s)", u)
}
}
}
+func TestVCSFileLookup(t *testing.T) {
+ tempDir, err := ioutil.TempDir("", "go-vcs-file-lookup-tests")
+ if err != nil {
+ t.Error(err)
+ }
+ defer func() {
+ err = os.RemoveAll(tempDir)
+ if err != nil {
+ t.Error(err)
+ }
+ }()
+
+ _, err = exec.Command("git", "init", tempDir).CombinedOutput()
+ if err != nil {
+ t.Error(err)
+ }
+
+ // On Windows it should be file:// followed by /C:\for\bar. That / before
+ // the drive needs to be included in testing.
+ var pth string
+ if runtime.GOOS == "windows" {
+ pth = "file:///" + tempDir
+ } else {
+ pth = "file://" + tempDir
+ }
+ ty, _, err := detectVcsFromRemote(pth)
+
+ if err != nil {
+ t.Errorf("Unable to detect file:// path: %s", err)
+ }
+
+ if ty != Git {
+ t.Errorf("Detected wrong type from file:// path. Found type %v", ty)
+ }
+}
+
func TestNotFound(t *testing.T) {
_, _, err := detectVcsFromRemote("https://mattfarina.com/notfound")
if err == nil || !strings.HasSuffix(err.Error(), " Not Found") {
diff --git a/vendor/github.com/sdboyer/gps/CONTRIBUTING.md b/vendor/github.com/sdboyer/gps/CONTRIBUTING.md
index 3ff03b36eb..0ed6f9e28a 100644
--- a/vendor/github.com/sdboyer/gps/CONTRIBUTING.md
+++ b/vendor/github.com/sdboyer/gps/CONTRIBUTING.md
@@ -56,3 +56,12 @@ The changes themselves should generally conform to the following guidelines:
* New or changed logic should be accompanied by tests.
* Maintainable, table-based tests are strongly preferred, even if it means
writing a new testing harness to execute them.
+
+## Setting up your development environment
+
+In order to run `gps`'s tests, you'll need to inflate `gps`'s dependencies using
+`glide`. Install `[glide](https://github.com/Masterminds/glide)`, and then download
+and install `gps`'s dependencies by running `glide install` from the repo base.
+
+Also, you'll need to have working copies of `git`, `hg`, and `bzr` to run all of
+`gps`'s tests.
diff --git a/vendor/github.com/sdboyer/gps/README.md b/vendor/github.com/sdboyer/gps/README.md
index ea287cc29e..0f956b2c1f 100644
--- a/vendor/github.com/sdboyer/gps/README.md
+++ b/vendor/github.com/sdboyer/gps/README.md
@@ -10,7 +10,7 @@
---
+---
`gps` is the Go Packaging Solver. It is an engine for tackling dependency
management problems in Go. It is trivial - [about 35 lines of
@@ -28,8 +28,10 @@ way. It is a distillation of the ideas behind language package managers like
[cargo](https://crates.io/) (and others) into a library, artisanally
handcrafted with ❤️ for Go's specific requirements.
-`gps` is [on track](https://github.com/Masterminds/glide/issues/565) to become
-the engine behind [glide](https://glide.sh). It also powers the [experimental, eventually-official Go tooling](https://github.com/golang/dep).
+`gps` was [on track](https://github.com/Masterminds/glide/issues/565) to become
+the engine behind [glide](https://glide.sh); however, those efforts have been
+discontinued in favor of gps powering the [experimental, eventually-official
+Go tooling](https://github.com/golang/dep).
The wiki has a [general introduction to the `gps`
approach](https://github.com/sdboyer/gps/wiki/Introduction-to-gps), as well
diff --git a/vendor/github.com/sdboyer/gps/appveyor.yml b/vendor/github.com/sdboyer/gps/appveyor.yml
index 8c6b1fd60d..5605fb8e14 100644
--- a/vendor/github.com/sdboyer/gps/appveyor.yml
+++ b/vendor/github.com/sdboyer/gps/appveyor.yml
@@ -19,7 +19,7 @@ build_script:
- C:\gopath\bin\glide install
test_script:
- - go test
+ - go test . ./internal/... ./pkgtree/...
- go build example.go
deploy: off
diff --git a/vendor/github.com/sdboyer/gps/bridge.go b/vendor/github.com/sdboyer/gps/bridge.go
index 222b372039..ded26eee2e 100644
--- a/vendor/github.com/sdboyer/gps/bridge.go
+++ b/vendor/github.com/sdboyer/gps/bridge.go
@@ -6,7 +6,7 @@ import (
"path/filepath"
"sync/atomic"
- "github.com/Masterminds/semver"
+ "github.com/sdboyer/gps/pkgtree"
)
// sourceBridges provide an adapter to SourceManagers that tailor operations
@@ -45,7 +45,7 @@ type bridge struct {
// Simple, local cache of the root's PackageTree
crp *struct {
- ptree PackageTree
+ ptree pkgtree.PackageTree
err error
}
@@ -81,7 +81,7 @@ func (b *bridge) GetManifestAndLock(id ProjectIdentifier, v Version) (Manifest,
return m, l, e
}
-func (b *bridge) AnalyzerInfo() (string, *semver.Version) {
+func (b *bridge) AnalyzerInfo() (string, int) {
return b.sm.AnalyzerInfo()
}
@@ -282,7 +282,7 @@ func (b *bridge) vtu(id ProjectIdentifier, v Version) versionTypeUnion {
//
// The root project is handled separately, as the source manager isn't
// responsible for that code.
-func (b *bridge) ListPackages(id ProjectIdentifier, v Version) (PackageTree, error) {
+func (b *bridge) ListPackages(id ProjectIdentifier, v Version) (pkgtree.PackageTree, error) {
if b.s.rd.isRoot(id.ProjectRoot) {
return b.s.rd.rpt, nil
}
diff --git a/vendor/github.com/sdboyer/gps/circle.yml b/vendor/github.com/sdboyer/gps/circle.yml
index 8be1609360..70ed51535b 100644
--- a/vendor/github.com/sdboyer/gps/circle.yml
+++ b/vendor/github.com/sdboyer/gps/circle.yml
@@ -7,7 +7,9 @@ dependencies:
pre:
- wget https://github.com/Masterminds/glide/releases/download/0.10.1/glide-0.10.1-linux-amd64.tar.gz
- tar -vxz -C $HOME/bin --strip=1 -f glide-0.10.1-linux-amd64.tar.gz
+ - sudo apt-get install bzr subversion
override:
+ - mkdir -p $HOME/.go_workspace/src
- glide --home $HOME/.glide -y glide.yaml install --cache
- mkdir -p $RD
- rsync -azC --delete ./ $RD
@@ -18,6 +20,11 @@ test:
pre:
- go vet
override:
- - cd $RD && go test -v -coverprofile=coverage.txt -covermode=atomic
+ - |
+ cd $RD && \
+ echo 'mode: atomic' > coverage.txt && \
+ go list ./... | grep -v "/vendor/" | \
+ xargs -n1 -I% sh -c 'set -e; go test -covermode=atomic -coverprofile=coverage.out % ; tail -n +2 coverage.out >> coverage.txt' && \
+ rm coverage.out
- cd $RD && go build example.go
- cd $RD && bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/github.com/sdboyer/gps/cmd.go b/vendor/github.com/sdboyer/gps/cmd.go
index 995c866397..eabda0f994 100644
--- a/vendor/github.com/sdboyer/gps/cmd.go
+++ b/vendor/github.com/sdboyer/gps/cmd.go
@@ -4,7 +4,10 @@ import (
"bytes"
"fmt"
"os/exec"
+ "sync"
"time"
+
+ "github.com/Masterminds/vcs"
)
// monitoredCmd wraps a cmd and will keep monitoring the process until it
@@ -38,8 +41,13 @@ func (c *monitoredCmd) run() error {
select {
case <-ticker.C:
if c.hasTimedOut() {
- if err := c.cmd.Process.Kill(); err != nil {
- return &killCmdError{err}
+ // On windows it is apparently (?) possible for the process
+ // pointer to become nil without Run() having returned (and
+ // thus, passing through the done channel). Guard against this.
+ if c.cmd.Process != nil {
+ if err := c.cmd.Process.Kill(); err != nil {
+ return &killCmdError{err}
+ }
}
return &timeoutError{c.timeout}
@@ -52,8 +60,8 @@ func (c *monitoredCmd) run() error {
func (c *monitoredCmd) hasTimedOut() bool {
t := time.Now().Add(-c.timeout)
- return c.stderr.lastActivity.Before(t) &&
- c.stdout.lastActivity.Before(t)
+ return c.stderr.lastActivity().Before(t) &&
+ c.stdout.lastActivity().Before(t)
}
func (c *monitoredCmd) combinedOutput() ([]byte, error) {
@@ -67,8 +75,9 @@ func (c *monitoredCmd) combinedOutput() ([]byte, error) {
// activityBuffer is a buffer that keeps track of the last time a Write
// operation was performed on it.
type activityBuffer struct {
- buf *bytes.Buffer
- lastActivity time.Time
+ sync.Mutex
+ buf *bytes.Buffer
+ lastActivityStamp time.Time
}
func newActivityBuffer() *activityBuffer {
@@ -78,10 +87,18 @@ func newActivityBuffer() *activityBuffer {
}
func (b *activityBuffer) Write(p []byte) (int, error) {
- b.lastActivity = time.Now()
+ b.Lock()
+ b.lastActivityStamp = time.Now()
+ defer b.Unlock()
return b.buf.Write(p)
}
+func (b *activityBuffer) lastActivity() time.Time {
+ b.Lock()
+ defer b.Unlock()
+ return b.lastActivityStamp
+}
+
type timeoutError struct {
timeout time.Duration
}
@@ -97,3 +114,13 @@ type killCmdError struct {
func (e killCmdError) Error() string {
return fmt.Sprintf("error killing command after timeout: %s", e.err)
}
+
+func runFromCwd(cmd string, args ...string) ([]byte, error) {
+ c := newMonitoredCmd(exec.Command(cmd, args...), 2*time.Minute)
+ return c.combinedOutput()
+}
+
+func runFromRepoDir(repo vcs.Repo, cmd string, args ...string) ([]byte, error) {
+ c := newMonitoredCmd(repo.CmdFromDir(cmd, args...), 2*time.Minute)
+ return c.combinedOutput()
+}
diff --git a/vendor/github.com/sdboyer/gps/deduce.go b/vendor/github.com/sdboyer/gps/deduce.go
index 1ae97a2395..b14b16f77d 100644
--- a/vendor/github.com/sdboyer/gps/deduce.go
+++ b/vendor/github.com/sdboyer/gps/deduce.go
@@ -48,10 +48,9 @@ func validateVCSScheme(scheme, typ string) bool {
// Regexes for the different known import path flavors
var (
- // This regex allowed some usernames that github currently disallows. They
- // may have allowed them in the past; keeping it in case we need to revert.
- //ghRegex = regexp.MustCompile(`^(?Pgithub\.com/([A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`)
- ghRegex = regexp.MustCompile(`^(?Pgithub\.com(/[A-Za-z0-9][-A-Za-z0-9]*[A-Za-z0-9]/[A-Za-z0-9_.\-]+))((?:/[A-Za-z0-9_.\-]+)*)$`)
+ // This regex allows some usernames that github currently disallows. They
+ // have allowed them in the past.
+ ghRegex = regexp.MustCompile(`^(?Pgithub\.com(/[A-Za-z0-9][-A-Za-z0-9]*/[A-Za-z0-9_.\-]+))((?:/[A-Za-z0-9_.\-]+)*)$`)
gpinNewRegex = regexp.MustCompile(`^(?Pgopkg\.in(?:(/[a-zA-Z0-9][-a-zA-Z0-9]+)?)(/[a-zA-Z][-.a-zA-Z0-9]*)\.((?:v0|v[1-9][0-9]*)(?:\.0|\.[1-9][0-9]*){0,2}(?:-unstable)?)(?:\.git)?)((?:/[a-zA-Z0-9][-.a-zA-Z0-9]*)*)$`)
//gpinOldRegex = regexp.MustCompile(`^(?Pgopkg\.in/(?:([a-z0-9][-a-z0-9]+)/)?((?:v0|v[1-9][0-9]*)(?:\.0|\.[1-9][0-9]*){0,2}(-unstable)?)/([a-zA-Z][-a-zA-Z0-9]*)(?:\.git)?)((?:/[a-zA-Z][-a-zA-Z0-9]*)*)$`)
bbRegex = regexp.MustCompile(`^(?Pbitbucket\.org(?P/[A-Za-z0-9_.\-]+/[A-Za-z0-9_.\-]+))((?:/[A-Za-z0-9_.\-]+)*)$`)
@@ -655,7 +654,7 @@ func (sm *SourceMgr) deduceFromPath(path string) (deductionFuture, error) {
defer close(c)
// make sure the metadata future is finished (without errors), thus
// guaranteeing that ru and vcs will be populated
- _, err := root()
+ _, err = root()
if err != nil {
return
}
@@ -683,7 +682,6 @@ func (sm *SourceMgr) deduceFromPath(path string) (deductionFuture, error) {
return src, ident, err
}
}
-
return deductionFuture{
rslow: true,
root: root,
diff --git a/vendor/github.com/sdboyer/gps/deduce_test.go b/vendor/github.com/sdboyer/gps/deduce_test.go
index ead3a82969..5044538400 100644
--- a/vendor/github.com/sdboyer/gps/deduce_test.go
+++ b/vendor/github.com/sdboyer/gps/deduce_test.go
@@ -77,15 +77,31 @@ var pathDeductionFixtures = map[string][]pathDeductionFixture{
root: "github.com/sdboyer/gps",
mb: maybeGitSource{url: mkurl("https://github.com/sdboyer/gps")},
},
+ {
+ in: "github.com/sdboyer-/gps/foo",
+ root: "github.com/sdboyer-/gps",
+ mb: maybeSources{
+ maybeGitSource{url: mkurl("https://github.com/sdboyer-/gps")},
+ maybeGitSource{url: mkurl("ssh://git@github.com/sdboyer-/gps")},
+ maybeGitSource{url: mkurl("git://github.com/sdboyer-/gps")},
+ maybeGitSource{url: mkurl("http://github.com/sdboyer-/gps")},
+ },
+ },
+ {
+ in: "github.com/a/gps/foo",
+ root: "github.com/a/gps",
+ mb: maybeSources{
+ maybeGitSource{url: mkurl("https://github.com/a/gps")},
+ maybeGitSource{url: mkurl("ssh://git@github.com/a/gps")},
+ maybeGitSource{url: mkurl("git://github.com/a/gps")},
+ maybeGitSource{url: mkurl("http://github.com/a/gps")},
+ },
+ },
// some invalid github username patterns
{
in: "github.com/-sdboyer/gps/foo",
rerr: errors.New("github.com/-sdboyer/gps/foo is not a valid path for a source on github.com"),
},
- {
- in: "github.com/sdboyer-/gps/foo",
- rerr: errors.New("github.com/sdboyer-/gps/foo is not a valid path for a source on github.com"),
- },
{
in: "github.com/sdbo.yer/gps/foo",
rerr: errors.New("github.com/sdbo.yer/gps/foo is not a valid path for a source on github.com"),
@@ -467,98 +483,102 @@ var pathDeductionFixtures = map[string][]pathDeductionFixture{
func TestDeduceFromPath(t *testing.T) {
for typ, fixtures := range pathDeductionFixtures {
- var deducer pathDeducer
- switch typ {
- case "github":
- deducer = githubDeducer{regexp: ghRegex}
- case "gopkg.in":
- deducer = gopkginDeducer{regexp: gpinNewRegex}
- case "jazz":
- deducer = jazzDeducer{regexp: jazzRegex}
- case "bitbucket":
- deducer = bitbucketDeducer{regexp: bbRegex}
- case "launchpad":
- deducer = launchpadDeducer{regexp: lpRegex}
- case "git.launchpad":
- deducer = launchpadGitDeducer{regexp: glpRegex}
- case "apache":
- deducer = apacheDeducer{regexp: apacheRegex}
- case "vcsext":
- deducer = vcsExtensionDeducer{regexp: vcsExtensionRegex}
- default:
- // Should just be the vanity imports, which we do elsewhere
- continue
- }
-
- var printmb func(mb maybeSource) string
- printmb = func(mb maybeSource) string {
- switch tmb := mb.(type) {
- case maybeSources:
- var buf bytes.Buffer
- fmt.Fprintf(&buf, "%v maybeSources:", len(tmb))
- for _, elem := range tmb {
- fmt.Fprintf(&buf, "\n\t\t%s", printmb(elem))
- }
- return buf.String()
- case maybeGitSource:
- return fmt.Sprintf("%T: %s", tmb, ufmt(tmb.url))
- case maybeBzrSource:
- return fmt.Sprintf("%T: %s", tmb, ufmt(tmb.url))
- case maybeHgSource:
- return fmt.Sprintf("%T: %s", tmb, ufmt(tmb.url))
- case maybeGopkginSource:
- return fmt.Sprintf("%T: %s (v%v) %s ", tmb, tmb.opath, tmb.major, ufmt(tmb.url))
+ t.Run(typ, func(t *testing.T) {
+ var deducer pathDeducer
+ switch typ {
+ case "github":
+ deducer = githubDeducer{regexp: ghRegex}
+ case "gopkg.in":
+ deducer = gopkginDeducer{regexp: gpinNewRegex}
+ case "jazz":
+ deducer = jazzDeducer{regexp: jazzRegex}
+ case "bitbucket":
+ deducer = bitbucketDeducer{regexp: bbRegex}
+ case "launchpad":
+ deducer = launchpadDeducer{regexp: lpRegex}
+ case "git.launchpad":
+ deducer = launchpadGitDeducer{regexp: glpRegex}
+ case "apache":
+ deducer = apacheDeducer{regexp: apacheRegex}
+ case "vcsext":
+ deducer = vcsExtensionDeducer{regexp: vcsExtensionRegex}
default:
- t.Errorf("Unknown maybeSource type: %T", mb)
- t.FailNow()
+ // Should just be the vanity imports, which we do elsewhere
+ t.Log("skipping")
+ t.SkipNow()
}
- return ""
- }
- for _, fix := range fixtures {
- u, in, uerr := normalizeURI(fix.in)
- if uerr != nil {
- if fix.rerr == nil {
- t.Errorf("(in: %s) bad input URI %s", fix.in, uerr)
+ var printmb func(mb maybeSource, t *testing.T) string
+ printmb = func(mb maybeSource, t *testing.T) string {
+ switch tmb := mb.(type) {
+ case maybeSources:
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "%v maybeSources:", len(tmb))
+ for _, elem := range tmb {
+ fmt.Fprintf(&buf, "\n\t\t%s", printmb(elem, t))
+ }
+ return buf.String()
+ case maybeGitSource:
+ return fmt.Sprintf("%T: %s", tmb, ufmt(tmb.url))
+ case maybeBzrSource:
+ return fmt.Sprintf("%T: %s", tmb, ufmt(tmb.url))
+ case maybeHgSource:
+ return fmt.Sprintf("%T: %s", tmb, ufmt(tmb.url))
+ case maybeGopkginSource:
+ return fmt.Sprintf("%T: %s (v%v) %s ", tmb, tmb.opath, tmb.major, ufmt(tmb.url))
+ default:
+ t.Errorf("Unknown maybeSource type: %T", mb)
}
- continue
+ return ""
}
- root, rerr := deducer.deduceRoot(in)
- if fix.rerr != nil {
- if rerr == nil {
- t.Errorf("(in: %s, %T) Expected error on deducing root, got none:\n\t(WNT) %s", in, deducer, fix.rerr)
- } else if fix.rerr.Error() != rerr.Error() {
- t.Errorf("(in: %s, %T) Got unexpected error on deducing root:\n\t(GOT) %s\n\t(WNT) %s", in, deducer, rerr, fix.rerr)
- }
- } else if rerr != nil {
- t.Errorf("(in: %s, %T) Got unexpected error on deducing root:\n\t(GOT) %s", in, deducer, rerr)
- } else if root != fix.root {
- t.Errorf("(in: %s, %T) Deducer did not return expected root:\n\t(GOT) %s\n\t(WNT) %s", in, deducer, root, fix.root)
- }
+ for _, fix := range fixtures {
+ t.Run(fix.in, func(t *testing.T) {
+ u, in, uerr := normalizeURI(fix.in)
+ if uerr != nil {
+ if fix.rerr == nil {
+ t.Errorf("bad input URI %s", uerr)
+ }
+ t.SkipNow()
+ }
- mb, mberr := deducer.deduceSource(in, u)
- if fix.srcerr != nil {
- if mberr == nil {
- t.Errorf("(in: %s, %T) Expected error on deducing source, got none:\n\t(WNT) %s", in, deducer, fix.srcerr)
- } else if fix.srcerr.Error() != mberr.Error() {
- t.Errorf("(in: %s, %T) Got unexpected error on deducing source:\n\t(GOT) %s\n\t(WNT) %s", in, deducer, mberr, fix.srcerr)
- }
- } else if mberr != nil {
- // don't complain the fix already expected an rerr
- if fix.rerr == nil {
- t.Errorf("(in: %s, %T) Got unexpected error on deducing source:\n\t(GOT) %s", in, deducer, mberr)
- }
- } else if !reflect.DeepEqual(mb, fix.mb) {
- if mb == nil {
- t.Errorf("(in: %s, %T) Deducer returned source maybes, but none expected:\n\t(GOT) (none)\n\t(WNT) %s", in, deducer, printmb(fix.mb))
- } else if fix.mb == nil {
- t.Errorf("(in: %s, %T) Deducer returned source maybes, but none expected:\n\t(GOT) %s\n\t(WNT) (none)", in, deducer, printmb(mb))
- } else {
- t.Errorf("(in: %s, %T) Deducer did not return expected source:\n\t(GOT) %s\n\t(WNT) %s", in, deducer, printmb(mb), printmb(fix.mb))
- }
+ root, rerr := deducer.deduceRoot(in)
+ if fix.rerr != nil {
+ if rerr == nil {
+ t.Errorf("Expected error on deducing root, got none:\n\t(WNT) %s", fix.rerr)
+ } else if fix.rerr.Error() != rerr.Error() {
+ t.Errorf("Got unexpected error on deducing root:\n\t(GOT) %s\n\t(WNT) %s", rerr, fix.rerr)
+ }
+ } else if rerr != nil {
+ t.Errorf("Got unexpected error on deducing root:\n\t(GOT) %s", rerr)
+ } else if root != fix.root {
+ t.Errorf("Deducer did not return expected root:\n\t(GOT) %s\n\t(WNT) %s", root, fix.root)
+ }
+
+ mb, mberr := deducer.deduceSource(in, u)
+ if fix.srcerr != nil {
+ if mberr == nil {
+ t.Errorf("Expected error on deducing source, got none:\n\t(WNT) %s", fix.srcerr)
+ } else if fix.srcerr.Error() != mberr.Error() {
+ t.Errorf("Got unexpected error on deducing source:\n\t(GOT) %s\n\t(WNT) %s", mberr, fix.srcerr)
+ }
+ } else if mberr != nil {
+ // don't complain the fix already expected an rerr
+ if fix.rerr == nil {
+ t.Errorf("Got unexpected error on deducing source:\n\t(GOT) %s", mberr)
+ }
+ } else if !reflect.DeepEqual(mb, fix.mb) {
+ if mb == nil {
+ t.Errorf("Deducer returned source maybes, but none expected:\n\t(GOT) (none)\n\t(WNT) %s", printmb(fix.mb, t))
+ } else if fix.mb == nil {
+ t.Errorf("Deducer returned source maybes, but none expected:\n\t(GOT) %s\n\t(WNT) (none)", printmb(mb, t))
+ } else {
+ t.Errorf("Deducer did not return expected source:\n\t(GOT) %s\n\t(WNT) %s", printmb(mb, t), printmb(fix.mb, t))
+ }
+ }
+ })
}
- }
+ })
}
}
@@ -577,30 +597,32 @@ func TestVanityDeduction(t *testing.T) {
for _, fix := range vanities {
go func(fix pathDeductionFixture) {
defer wg.Done()
- pr, err := sm.DeduceProjectRoot(fix.in)
- if err != nil {
- t.Errorf("(in: %s) Unexpected err on deducing project root: %s", fix.in, err)
- return
- } else if string(pr) != fix.root {
- t.Errorf("(in: %s) Deducer did not return expected root:\n\t(GOT) %s\n\t(WNT) %s", fix.in, pr, fix.root)
- }
+ t.Run(fmt.Sprintf("%s", fix.in), func(t *testing.T) {
+ pr, err := sm.DeduceProjectRoot(fix.in)
+ if err != nil {
+ t.Errorf("Unexpected err on deducing project root: %s", err)
+ return
+ } else if string(pr) != fix.root {
+ t.Errorf("Deducer did not return expected root:\n\t(GOT) %s\n\t(WNT) %s", pr, fix.root)
+ }
- ft, err := sm.deducePathAndProcess(fix.in)
- if err != nil {
- t.Errorf("(in: %s) Unexpected err on deducing source: %s", fix.in, err)
- return
- }
+ ft, err := sm.deducePathAndProcess(fix.in)
+ if err != nil {
+ t.Errorf("Unexpected err on deducing source: %s", err)
+ return
+ }
- _, ident, err := ft.srcf()
- if err != nil {
- t.Errorf("(in: %s) Unexpected err on executing source future: %s", fix.in, err)
- return
- }
+ _, ident, err := ft.srcf()
+ if err != nil {
+ t.Errorf("Unexpected err on executing source future: %s", err)
+ return
+ }
- ustr := fix.mb.(maybeGitSource).url.String()
- if ident != ustr {
- t.Errorf("(in: %s) Deduced repo ident does not match fixture:\n\t(GOT) %s\n\t(WNT) %s", fix.in, ident, ustr)
- }
+ ustr := fix.mb.(maybeGitSource).url.String()
+ if ident != ustr {
+ t.Errorf("Deduced repo ident does not match fixture:\n\t(GOT) %s\n\t(WNT) %s", ident, ustr)
+ }
+ })
}(fix)
}
@@ -620,27 +642,3 @@ func ufmt(u *url.URL) string {
return fmt.Sprintf("host=%q, path=%q, opaque=%q, scheme=%q, user=%#v, pass=%#v, rawpath=%q, rawq=%q, frag=%q",
u.Host, u.Path, u.Opaque, u.Scheme, user, pass, u.RawPath, u.RawQuery, u.Fragment)
}
-
-func TestIsStdLib(t *testing.T) {
- fix := []struct {
- ip string
- is bool
- }{
- {"appengine", true},
- {"net/http", true},
- {"github.com/anything", false},
- {"foo", true},
- }
-
- for _, f := range fix {
- r := doIsStdLib(f.ip)
- if r != f.is {
- if r {
- t.Errorf("%s was marked stdlib but should not have been", f.ip)
- } else {
- t.Errorf("%s was not marked stdlib but should have been", f.ip)
-
- }
- }
- }
-}
diff --git a/vendor/github.com/sdboyer/gps/example.go b/vendor/github.com/sdboyer/gps/example.go
index 61dcdb7885..dd1225454b 100644
--- a/vendor/github.com/sdboyer/gps/example.go
+++ b/vendor/github.com/sdboyer/gps/example.go
@@ -10,8 +10,8 @@ import (
"path/filepath"
"strings"
- "github.com/Masterminds/semver"
"github.com/sdboyer/gps"
+ "github.com/sdboyer/gps/pkgtree"
)
// This is probably the simplest possible implementation of gps. It does the
@@ -36,7 +36,7 @@ func main() {
TraceLogger: log.New(os.Stdout, "", 0),
}
// Perform static analysis on the current project to find all of its imports.
- params.RootPackageTree, _ = gps.ListPackages(root, importroot)
+ params.RootPackageTree, _ = pkgtree.ListPackages(root, importroot)
// Set up a SourceManager. This manages interaction with sources (repositories).
tempdir, _ := ioutil.TempDir("", "gps-repocache")
@@ -66,7 +66,6 @@ func (a NaiveAnalyzer) DeriveManifestAndLock(path string, n gps.ProjectRoot) (gp
// Reports the name and version of the analyzer. This is used internally as part
// of gps' hashing memoization scheme.
-func (a NaiveAnalyzer) Info() (name string, version *semver.Version) {
- v, _ := semver.NewVersion("v0.0.1")
- return "example-analyzer", v
+func (a NaiveAnalyzer) Info() (name string, version int) {
+ return "example-analyzer", 1
}
diff --git a/vendor/github.com/sdboyer/gps/glide.lock b/vendor/github.com/sdboyer/gps/glide.lock
index 282a4e9cd4..8d45a7837f 100644
--- a/vendor/github.com/sdboyer/gps/glide.lock
+++ b/vendor/github.com/sdboyer/gps/glide.lock
@@ -1,19 +1,10 @@
-hash: 2252a285ab27944a4d7adcba8dbd03980f59ba652f12db39fa93b927c345593e
-updated: 2016-06-06T22:10:37.696580463-04:00
+hash: ca4079cea0bcb746c052c89611d05eb5649440191bcad12afde0ac4c4a00fb97
+updated: 2017-03-09T21:12:59.686448539+01:00
imports:
- name: github.com/armon/go-radix
version: 4239b77079c7b5d1243b7b4736304ce8ddb6f0f2
-- name: github.com/hashicorp/go-immutable-radix
- version: 8e8ed81f8f0bf1bdd829593fdd5c29922c1ea990
-- name: github.com/hashicorp/golang-lru
- version: a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4
- name: github.com/Masterminds/semver
version: 94ad6eaf8457cf85a68c9b53fa42e9b1b8683783
- vcs: git
- name: github.com/Masterminds/vcs
version: abd1ea7037d3652ef9833a164b627f49225e1131
- vcs: git
-- name: github.com/termie/go-shutil
- version: bcacb06fecaeec8dc42af03c87c6949f4a05c74c
- vcs: git
-devImports: []
+testImports: []
diff --git a/vendor/github.com/sdboyer/gps/glide.yaml b/vendor/github.com/sdboyer/gps/glide.yaml
index 5e379faf04..7f9f8799cd 100644
--- a/vendor/github.com/sdboyer/gps/glide.yaml
+++ b/vendor/github.com/sdboyer/gps/glide.yaml
@@ -3,6 +3,8 @@ owners:
- name: Sam Boyer
email: tech@samboyer.org
dependencies:
+- package: github.com/Masterminds/vcs
+ version: abd1ea7037d3652ef9833a164b627f49225e1131
- package: github.com/Masterminds/semver
branch: 2.x
- package: github.com/termie/go-shutil
diff --git a/vendor/github.com/sdboyer/gps/hash.go b/vendor/github.com/sdboyer/gps/hash.go
index 1cedb260f8..f6e5d07e23 100644
--- a/vendor/github.com/sdboyer/gps/hash.go
+++ b/vendor/github.com/sdboyer/gps/hash.go
@@ -5,7 +5,10 @@ import (
"crypto/sha256"
"io"
"sort"
+ "strconv"
"strings"
+
+ "github.com/sdboyer/gps/pkgtree"
)
// string headers used to demarcate sections in hash input creation
@@ -103,7 +106,7 @@ func (s *solver) writeHashingInputs(w io.Writer) {
writeString(hhAnalyzer)
an, av := s.b.AnalyzerInfo()
writeString(an)
- writeString(av.String())
+ writeString(strconv.Itoa(av))
}
// bytes.Buffer wrapper that injects newlines after each call to Write().
@@ -127,7 +130,7 @@ func HashingInputsAsString(s Solver) string {
return (*bytes.Buffer)(buf).String()
}
-type sortPackageOrErr []PackageOrErr
+type sortPackageOrErr []pkgtree.PackageOrErr
func (s sortPackageOrErr) Len() int { return len(s) }
func (s sortPackageOrErr) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
diff --git a/vendor/github.com/sdboyer/gps/hash_test.go b/vendor/github.com/sdboyer/gps/hash_test.go
index 5ff324ed88..84f3618df1 100644
--- a/vendor/github.com/sdboyer/gps/hash_test.go
+++ b/vendor/github.com/sdboyer/gps/hash_test.go
@@ -40,7 +40,7 @@ func TestHashInputs(t *testing.T) {
hhOverrides,
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
}
for _, v := range elems {
h.Write([]byte(v))
@@ -93,7 +93,7 @@ func TestHashInputsReqsIgs(t *testing.T) {
hhOverrides,
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
}
for _, v := range elems {
h.Write([]byte(v))
@@ -138,7 +138,7 @@ func TestHashInputsReqsIgs(t *testing.T) {
hhOverrides,
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
}
for _, v := range elems {
h.Write([]byte(v))
@@ -177,7 +177,7 @@ func TestHashInputsReqsIgs(t *testing.T) {
hhOverrides,
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
}
for _, v := range elems {
h.Write([]byte(v))
@@ -232,7 +232,7 @@ func TestHashInputsOverrides(t *testing.T) {
"car",
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
},
},
{
@@ -263,7 +263,7 @@ func TestHashInputsOverrides(t *testing.T) {
"car",
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
},
},
{
@@ -293,7 +293,7 @@ func TestHashInputsOverrides(t *testing.T) {
"car",
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
},
},
{
@@ -321,7 +321,7 @@ func TestHashInputsOverrides(t *testing.T) {
"car",
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
},
},
{
@@ -353,7 +353,7 @@ func TestHashInputsOverrides(t *testing.T) {
"b-foobranch",
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
},
},
{
@@ -381,7 +381,7 @@ func TestHashInputsOverrides(t *testing.T) {
"b-foobranch",
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
},
},
{
@@ -411,7 +411,7 @@ func TestHashInputsOverrides(t *testing.T) {
"b-foobranch",
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
},
},
{
@@ -442,7 +442,7 @@ func TestHashInputsOverrides(t *testing.T) {
"b-foobranch",
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
},
},
{
@@ -474,7 +474,7 @@ func TestHashInputsOverrides(t *testing.T) {
"b-foobranch",
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
},
},
{
@@ -508,7 +508,7 @@ func TestHashInputsOverrides(t *testing.T) {
"b-foobranch",
hhAnalyzer,
"depspec-sm-builtin",
- "1.0.0",
+ "1",
},
},
}
diff --git a/vendor/github.com/sdboyer/gps/types.go b/vendor/github.com/sdboyer/gps/identifier.go
similarity index 92%
rename from vendor/github.com/sdboyer/gps/types.go
rename to vendor/github.com/sdboyer/gps/identifier.go
index 7b0478e6de..7406ce96d2 100644
--- a/vendor/github.com/sdboyer/gps/types.go
+++ b/vendor/github.com/sdboyer/gps/identifier.go
@@ -163,16 +163,6 @@ type ProjectProperties struct {
Constraint Constraint
}
-// Package represents a Go package. It contains a subset of the information
-// go/build.Package does.
-type Package struct {
- Name string // Package name, as declared in the package statement
- ImportPath string // Full import path, including the prefix provided to ListPackages()
- CommentPath string // Import path given in the comment on the package statement
- Imports []string // Imports from all go and cgo files
- TestImports []string // Imports from all go test files (in go/build parlance: both TestImports and XTestImports)
-}
-
// bimodalIdentifiers are used to track work to be done in the unselected queue.
type bimodalIdentifier struct {
id ProjectIdentifier
diff --git a/vendor/github.com/sdboyer/gps/util.go b/vendor/github.com/sdboyer/gps/internal/fs/fs.go
similarity index 79%
rename from vendor/github.com/sdboyer/gps/util.go
rename to vendor/github.com/sdboyer/gps/internal/fs/fs.go
index 45d3dff708..cec090d72c 100644
--- a/vendor/github.com/sdboyer/gps/util.go
+++ b/vendor/github.com/sdboyer/gps/internal/fs/fs.go
@@ -1,7 +1,7 @@
-package gps
+package fs
import (
- "fmt"
+ "errors"
"io"
"io/ioutil"
"os"
@@ -10,10 +10,10 @@ import (
"syscall"
)
-// renameWithFallback attempts to rename a file or directory, but falls back to
+// RenameWithFallback attempts to rename a file or directory, but falls back to
// copying in the event of a cross-link device error. If the fallback copy
// succeeds, src is still removed, emulating normal rename behavior.
-func renameWithFallback(src, dest string) error {
+func RenameWithFallback(src, dest string) error {
fi, err := os.Stat(src)
if err != nil {
return err
@@ -36,9 +36,9 @@ func renameWithFallback(src, dest string) error {
var cerr error
if terr.Err == syscall.EXDEV {
if fi.IsDir() {
- cerr = copyDir(src, dest)
+ cerr = CopyDir(src, dest)
} else {
- cerr = copyFile(src, dest)
+ cerr = CopyFile(src, dest)
}
} else if runtime.GOOS == "windows" {
// In windows it can drop down to an operating system call that
@@ -49,9 +49,9 @@ func renameWithFallback(src, dest string) error {
// See https://msdn.microsoft.com/en-us/library/cc231199.aspx
if ok && noerr == 0x11 {
if fi.IsDir() {
- cerr = copyDir(src, dest)
+ cerr = CopyDir(src, dest)
} else {
- cerr = copyFile(src, dest)
+ cerr = CopyFile(src, dest)
}
}
} else {
@@ -65,10 +65,15 @@ func renameWithFallback(src, dest string) error {
return os.RemoveAll(src)
}
-// copyDir recursively copies a directory tree, attempting to preserve permissions.
+var (
+ errSrcNotDir = errors.New("source is not a directory")
+ errDestExist = errors.New("destination already exists")
+)
+
+// CopyDir recursively copies a directory tree, attempting to preserve permissions.
// Source directory must exist, destination directory must *not* exist.
// Symlinks are ignored and skipped.
-func copyDir(src string, dst string) (err error) {
+func CopyDir(src string, dst string) (err error) {
src = filepath.Clean(src)
dst = filepath.Clean(dst)
@@ -77,7 +82,7 @@ func copyDir(src string, dst string) (err error) {
return err
}
if !si.IsDir() {
- return fmt.Errorf("source is not a directory")
+ return errSrcNotDir
}
_, err = os.Stat(dst)
@@ -85,7 +90,7 @@ func copyDir(src string, dst string) (err error) {
return
}
if err == nil {
- return fmt.Errorf("destination already exists")
+ return errDestExist
}
err = os.MkdirAll(dst, si.Mode())
@@ -103,14 +108,14 @@ func copyDir(src string, dst string) (err error) {
dstPath := filepath.Join(dst, entry.Name())
if entry.IsDir() {
- err = copyDir(srcPath, dstPath)
+ err = CopyDir(srcPath, dstPath)
if err != nil {
return
}
} else {
// This will include symlinks, which is what we want in all cases
// where gps is copying things.
- err = copyFile(srcPath, dstPath)
+ err = CopyFile(srcPath, dstPath)
if err != nil {
return
}
@@ -120,12 +125,12 @@ func copyDir(src string, dst string) (err error) {
return
}
-// copyFile copies the contents of the file named src to the file named
+// CopyFile copies the contents of the file named src to the file named
// by dst. The file will be created if it does not already exist. If the
// destination file exists, all it's contents will be replaced by the contents
// of the source file. The file mode will be copied from the source and
// the copied data is synced/flushed to stable storage.
-func copyFile(src, dst string) (err error) {
+func CopyFile(src, dst string) (err error) {
in, err := os.Open(src)
if err != nil {
return
@@ -163,3 +168,4 @@ func copyFile(src, dst string) (err error) {
return
}
+
diff --git a/vendor/github.com/sdboyer/gps/util_test.go b/vendor/github.com/sdboyer/gps/internal/fs/fs_test.go
similarity index 95%
rename from vendor/github.com/sdboyer/gps/util_test.go
rename to vendor/github.com/sdboyer/gps/internal/fs/fs_test.go
index 036edbf742..04f3204754 100644
--- a/vendor/github.com/sdboyer/gps/util_test.go
+++ b/vendor/github.com/sdboyer/gps/internal/fs/fs_test.go
@@ -1,4 +1,4 @@
-package gps
+package fs
import (
"fmt"
@@ -46,7 +46,7 @@ func TestCopyDir(t *testing.T) {
srcf.Close()
destdir := filepath.Join(dir, "dest")
- if err := copyDir(srcdir, destdir); err != nil {
+ if err := CopyDir(srcdir, destdir); err != nil {
t.Fatal(err)
}
@@ -102,7 +102,7 @@ func TestCopyFile(t *testing.T) {
srcf.Close()
destf := filepath.Join(dir, "destf")
- if err := copyFile(srcf.Name(), destf); err != nil {
+ if err := CopyFile(srcf.Name(), destf); err != nil {
t.Fatal(err)
}
diff --git a/vendor/github.com/sdboyer/gps/internal/internal.go b/vendor/github.com/sdboyer/gps/internal/internal.go
new file mode 100644
index 0000000000..fd141d5a67
--- /dev/null
+++ b/vendor/github.com/sdboyer/gps/internal/internal.go
@@ -0,0 +1,19 @@
+// Package internal provides support for gps own packages.
+package internal
+
+import "strings"
+
+// IsStdLib is a reference to internal implementation.
+// It is stored as a var so that tests can swap it out. Ugh globals, ugh.
+var IsStdLib = doIsStdLib
+
+// This was lovingly lifted from src/cmd/go/pkg.go in Go's code
+// (isStandardImportPath).
+func doIsStdLib(path string) bool {
+ i := strings.Index(path, "/")
+ if i < 0 {
+ i = len(path)
+ }
+
+ return !strings.Contains(path[:i], ".")
+}
diff --git a/vendor/github.com/sdboyer/gps/internal/internal_test.go b/vendor/github.com/sdboyer/gps/internal/internal_test.go
new file mode 100644
index 0000000000..c13ad3b7da
--- /dev/null
+++ b/vendor/github.com/sdboyer/gps/internal/internal_test.go
@@ -0,0 +1,28 @@
+package internal
+
+import "testing"
+
+func TestIsStdLib(t *testing.T) {
+ fix := []struct {
+ ip string
+ is bool
+ }{
+ {"appengine", true},
+ {"net/http", true},
+ {"github.com/anything", false},
+ {"foo", true},
+ }
+
+ for _, f := range fix {
+ r := doIsStdLib(f.ip)
+ if r != f.is {
+ if r {
+ t.Errorf("%s was marked stdlib but should not have been", f.ip)
+ } else {
+ t.Errorf("%s was not marked stdlib but should have been", f.ip)
+
+ }
+ }
+ }
+}
+
diff --git a/vendor/github.com/sdboyer/gps/lock_test.go b/vendor/github.com/sdboyer/gps/lock_test.go
index a65179be89..d49fccf22a 100644
--- a/vendor/github.com/sdboyer/gps/lock_test.go
+++ b/vendor/github.com/sdboyer/gps/lock_test.go
@@ -37,40 +37,42 @@ func TestLockedProjectsEq(t *testing.T) {
NewLockedProject(mkPI("github.com/sdboyer/gps"), Revision("278a227dfc3d595a33a77ff3f841fd8ca1bc8cd0"), []string{"gps"}),
}
- fix := []struct {
+ fix := map[string]struct {
l1, l2 int
shouldeq bool
err string
}{
- {0, 0, true, "lp does not eq self"},
- {0, 5, false, "should not eq with different rev"},
- {0, 6, false, "should not eq with different version"},
- {5, 5, true, "should eq with same rev"},
- {0, 1, false, "should not eq when other pkg list is empty"},
- {0, 2, false, "should not eq when other pkg list is longer"},
- {2, 4, false, "should not eq when pkg lists are out of order"},
- {0, 3, false, "should not eq totally different lp"},
- {7, 7, true, "should eq with only rev"},
- {5, 7, false, "should not eq when only rev matches"},
+ "with self": {0, 0, true, "lp does not eq self"},
+ "with different revision": {0, 5, false, "should not eq with different rev"},
+ "with different versions": {0, 6, false, "should not eq with different version"},
+ "with same revsion": {5, 5, true, "should eq with same rev"},
+ "with empty pkg": {0, 1, false, "should not eq when other pkg list is empty"},
+ "with long pkg list": {0, 2, false, "should not eq when other pkg list is longer"},
+ "with different orders": {2, 4, false, "should not eq when pkg lists are out of order"},
+ "with different lp": {0, 3, false, "should not eq totally different lp"},
+ "with only rev": {7, 7, true, "should eq with only rev"},
+ "when only rev matches": {5, 7, false, "should not eq when only rev matches"},
}
- for _, f := range fix {
- if f.shouldeq {
- if !lps[f.l1].Eq(lps[f.l2]) {
- t.Error(f.err)
- }
- if !lps[f.l2].Eq(lps[f.l1]) {
- t.Error(f.err + (" (reversed)"))
- }
- } else {
- if lps[f.l1].Eq(lps[f.l2]) {
- t.Error(f.err)
- }
- if lps[f.l2].Eq(lps[f.l1]) {
- t.Error(f.err + (" (reversed)"))
- }
+ for k, f := range fix {
+ t.Run(k, func(t *testing.T) {
+ if f.shouldeq {
+ if !lps[f.l1].Eq(lps[f.l2]) {
+ t.Error(f.err)
+ }
+ if !lps[f.l2].Eq(lps[f.l1]) {
+ t.Error(f.err + (" (reversed)"))
+ }
+ } else {
+ if lps[f.l1].Eq(lps[f.l2]) {
+ t.Error(f.err)
+ }
+ if lps[f.l2].Eq(lps[f.l1]) {
+ t.Error(f.err + (" (reversed)"))
+ }
- }
+ }
+ })
}
}
diff --git a/vendor/github.com/sdboyer/gps/manager_test.go b/vendor/github.com/sdboyer/gps/manager_test.go
index 57027e6802..db566620ca 100644
--- a/vendor/github.com/sdboyer/gps/manager_test.go
+++ b/vendor/github.com/sdboyer/gps/manager_test.go
@@ -26,8 +26,8 @@ func (naiveAnalyzer) DeriveManifestAndLock(string, ProjectRoot) (Manifest, Lock,
return nil, nil, nil
}
-func (a naiveAnalyzer) Info() (name string, version *semver.Version) {
- return "naive-analyzer", sv("v0.0.1")
+func (a naiveAnalyzer) Info() (name string, version int) {
+ return "naive-analyzer", 1
}
func sv(s string) *semver.Version {
@@ -350,6 +350,7 @@ func TestGetSources(t *testing.T) {
if testing.Short() {
t.Skip("Skipping source setup test in short mode")
}
+ requiresBins(t, "git", "hg", "bzr")
sm, clean := mkNaiveSM(t)
@@ -363,6 +364,8 @@ func TestGetSources(t *testing.T) {
wg.Add(3)
for _, pi := range pil {
go func(lpi ProjectIdentifier) {
+ defer wg.Done()
+
nn := lpi.normalizedSource()
src, err := sm.getSourceFor(lpi)
if err != nil {
@@ -395,8 +398,6 @@ func TestGetSources(t *testing.T) {
} else if src == src4 {
t.Errorf("(src %q) explicit http source should create a new src", nn)
}
-
- wg.Done()
}(pi)
}
@@ -850,3 +851,17 @@ func TestSignalHandling(t *testing.T) {
}
clean()
}
+
+func TestUnreachableSource(t *testing.T) {
+ // If a git remote is unreachable (maybe the server is only accessible behind a VPN, or
+ // something), we should return a clear error, not a panic.
+
+ sm, clean := mkNaiveSM(t)
+ defer clean()
+
+ id := mkPI("golang.org/notareal/repo").normalize()
+ _, err := sm.ListVersions(id)
+ if err == nil {
+ t.Error("expected err when listing versions of a bogus source, but got nil")
+ }
+}
diff --git a/vendor/github.com/sdboyer/gps/maybe_source.go b/vendor/github.com/sdboyer/gps/maybe_source.go
index d59962aedc..5e74ce95c0 100644
--- a/vendor/github.com/sdboyer/gps/maybe_source.go
+++ b/vendor/github.com/sdboyer/gps/maybe_source.go
@@ -50,9 +50,9 @@ type sourceFailures []sourceSetupFailure
func (sf sourceFailures) Error() string {
var buf bytes.Buffer
- fmt.Fprintf(&buf, "No valid source could be created:\n")
+ fmt.Fprintf(&buf, "no valid source could be created:")
for _, e := range sf {
- fmt.Fprintf(&buf, "\t%s", e.Error())
+ fmt.Fprintf(&buf, "\n\t%s", e.Error())
}
return buf.String()
@@ -67,7 +67,7 @@ func (m maybeGitSource) try(cachedir string, an ProjectAnalyzer) (source, string
path := filepath.Join(cachedir, "sources", sanitizer.Replace(ustr))
r, err := vcs.NewGitRepo(ustr, path)
if err != nil {
- return nil, "", err
+ return nil, ustr, unwrapVcsErr(err)
}
src := &gitSource{
@@ -75,7 +75,7 @@ func (m maybeGitSource) try(cachedir string, an ProjectAnalyzer) (source, string
an: an,
dc: newMetaCache(),
crepo: &repo{
- r: r,
+ r: &gitRepo{r},
rpath: path,
},
},
@@ -85,7 +85,7 @@ func (m maybeGitSource) try(cachedir string, an ProjectAnalyzer) (source, string
if !r.CheckLocal() {
_, err = src.listVersions()
if err != nil {
- return nil, "", err
+ return nil, ustr, unwrapVcsErr(err)
}
}
@@ -112,7 +112,7 @@ func (m maybeGopkginSource) try(cachedir string, an ProjectAnalyzer) (source, st
ustr := m.url.String()
r, err := vcs.NewGitRepo(ustr, path)
if err != nil {
- return nil, "", err
+ return nil, ustr, unwrapVcsErr(err)
}
src := &gopkginSource{
@@ -121,7 +121,7 @@ func (m maybeGopkginSource) try(cachedir string, an ProjectAnalyzer) (source, st
an: an,
dc: newMetaCache(),
crepo: &repo{
- r: r,
+ r: &gitRepo{r},
rpath: path,
},
},
@@ -133,7 +133,7 @@ func (m maybeGopkginSource) try(cachedir string, an ProjectAnalyzer) (source, st
if !r.CheckLocal() {
_, err = src.listVersions()
if err != nil {
- return nil, "", err
+ return nil, ustr, unwrapVcsErr(err)
}
}
@@ -149,10 +149,10 @@ func (m maybeBzrSource) try(cachedir string, an ProjectAnalyzer) (source, string
path := filepath.Join(cachedir, "sources", sanitizer.Replace(ustr))
r, err := vcs.NewBzrRepo(ustr, path)
if err != nil {
- return nil, "", err
+ return nil, ustr, unwrapVcsErr(err)
}
if !r.Ping() {
- return nil, "", fmt.Errorf("Remote repository at %s does not exist, or is inaccessible", ustr)
+ return nil, ustr, fmt.Errorf("remote repository at %s does not exist, or is inaccessible", ustr)
}
src := &bzrSource{
@@ -164,7 +164,7 @@ func (m maybeBzrSource) try(cachedir string, an ProjectAnalyzer) (source, string
f: existsUpstream,
},
crepo: &repo{
- r: r,
+ r: &bzrRepo{r},
rpath: path,
},
},
@@ -183,10 +183,10 @@ func (m maybeHgSource) try(cachedir string, an ProjectAnalyzer) (source, string,
path := filepath.Join(cachedir, "sources", sanitizer.Replace(ustr))
r, err := vcs.NewHgRepo(ustr, path)
if err != nil {
- return nil, "", err
+ return nil, ustr, unwrapVcsErr(err)
}
if !r.Ping() {
- return nil, "", fmt.Errorf("Remote repository at %s does not exist, or is inaccessible", ustr)
+ return nil, ustr, fmt.Errorf("remote repository at %s does not exist, or is inaccessible", ustr)
}
src := &hgSource{
@@ -198,7 +198,7 @@ func (m maybeHgSource) try(cachedir string, an ProjectAnalyzer) (source, string,
f: existsUpstream,
},
crepo: &repo{
- r: r,
+ r: &hgRepo{r},
rpath: path,
},
},
diff --git a/vendor/github.com/sdboyer/gps/metrics.go b/vendor/github.com/sdboyer/gps/metrics.go
index bd5629ea35..ee4c0ab9e4 100644
--- a/vendor/github.com/sdboyer/gps/metrics.go
+++ b/vendor/github.com/sdboyer/gps/metrics.go
@@ -62,11 +62,10 @@ func (m *metrics) dump(l *log.Logger) {
fmt.Fprintf(w, "\t%s:\t%v\t\n", nd.n, nd.d)
}
fmt.Fprintf(w, "\n\tTOTAL:\t%v\t\n", tot)
-
- l.Println("\nSolver wall times by segment:")
w.Flush()
- fmt.Println((&buf).String())
+ l.Println("\nSolver wall times by segment:")
+ l.Println((&buf).String())
}
type ndpair struct {
diff --git a/vendor/github.com/sdboyer/gps/analysis.go b/vendor/github.com/sdboyer/gps/pkgtree/pkgtree.go
similarity index 88%
rename from vendor/github.com/sdboyer/gps/analysis.go
rename to vendor/github.com/sdboyer/gps/pkgtree/pkgtree.go
index e5f0fe3cec..5717f0b267 100644
--- a/vendor/github.com/sdboyer/gps/analysis.go
+++ b/vendor/github.com/sdboyer/gps/pkgtree/pkgtree.go
@@ -1,4 +1,4 @@
-package gps
+package pkgtree
import (
"fmt"
@@ -14,35 +14,14 @@ import (
"unicode"
)
-var (
- osList []string
- archList []string
- ignoreTags = []string{} //[]string{"appengine", "ignore"} //TODO: appengine is a special case for now: https://github.com/tools/godep/issues/353
-)
-
-func init() {
- // The supported systems are listed in
- // https://github.com/golang/go/blob/master/src/go/build/syslist.go
- // The lists are not exported, so we need to duplicate them here.
- osListString := "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows"
- osList = strings.Split(osListString, " ")
-
- archListString := "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc s390 s390x sparc sparc64"
- archList = strings.Split(archListString, " ")
-}
-
-// Stored as a var so that tests can swap it out. Ugh globals, ugh.
-var isStdLib = doIsStdLib
-
-// This was lovingly lifted from src/cmd/go/pkg.go in Go's code
-// (isStandardImportPath).
-func doIsStdLib(path string) bool {
- i := strings.Index(path, "/")
- if i < 0 {
- i = len(path)
- }
-
- return !strings.Contains(path[:i], ".")
+// Package represents a Go package. It contains a subset of the information
+// go/build.Package does.
+type Package struct {
+ Name string // Package name, as declared in the package statement
+ ImportPath string // Full import path, including the prefix provided to ListPackages()
+ CommentPath string // Import path given in the comment on the package statement
+ Imports []string // Imports from all go and cgo files
+ TestImports []string // Imports from all go test files (in go/build parlance: both TestImports and XTestImports)
}
// ListPackages reports Go package information about all directories in the tree
@@ -112,13 +91,15 @@ func ListPackages(fileRoot, importRoot string) (PackageTree, error) {
// would have an err with the same path as is called this time, as only
// then will filepath.Walk have attempted to descend into the directory
// and encountered an error.
- _, err = os.Open(wp)
+ var f *os.File
+ f, err = os.Open(wp)
if err != nil {
if os.IsPermission(err) {
return filepath.SkipDir
}
return err
}
+ f.Close()
// Compute the import path. Run the result through ToSlash(), so that
// windows file paths are normalized to slashes, as is expected of
@@ -304,45 +285,6 @@ func (e *LocalImportsError) Error() string {
}
}
-// A PackageTree represents the results of recursively parsing a tree of
-// packages, starting at the ImportRoot. The results of parsing the files in the
-// directory identified by each import path - a Package or an error - are stored
-// in the Packages map, keyed by that import path.
-type PackageTree struct {
- ImportRoot string
- Packages map[string]PackageOrErr
-}
-
-// dup copies the PackageTree.
-//
-// This is really only useful as a defensive measure to prevent external state
-// mutations.
-func (t PackageTree) dup() PackageTree {
- t2 := PackageTree{
- ImportRoot: t.ImportRoot,
- Packages: map[string]PackageOrErr{},
- }
-
- for path, poe := range t.Packages {
- poe2 := PackageOrErr{
- Err: poe.Err,
- P: poe.P,
- }
- if len(poe.P.Imports) > 0 {
- poe2.P.Imports = make([]string, len(poe.P.Imports))
- copy(poe2.P.Imports, poe.P.Imports)
- }
- if len(poe.P.TestImports) > 0 {
- poe2.P.TestImports = make([]string, len(poe.P.TestImports))
- copy(poe2.P.TestImports, poe.P.TestImports)
- }
-
- t2.Packages[path] = poe2
- }
-
- return t2
-}
-
type wm struct {
err error
ex map[string]bool
@@ -356,15 +298,6 @@ type PackageOrErr struct {
Err error
}
-// ReachMap maps a set of import paths (keys) to the sets of transitively
-// reachable tree-internal packages, and all the tree-external packages
-// reachable through those internal packages.
-//
-// See PackageTree.ToReachMap() for more information.
-type ReachMap map[string]struct {
- Internal, External []string
-}
-
// ProblemImportError describes the reason that a particular import path is
// not safely importable.
type ProblemImportError struct {
@@ -393,6 +326,20 @@ func (e *ProblemImportError) Error() string {
}
}
+// Helper func to create an error when a package is missing.
+func missingPkgErr(pkg string) error {
+ return fmt.Errorf("no package exists at %q", pkg)
+}
+
+// A PackageTree represents the results of recursively parsing a tree of
+// packages, starting at the ImportRoot. The results of parsing the files in the
+// directory identified by each import path - a Package or an error - are stored
+// in the Packages map, keyed by that import path.
+type PackageTree struct {
+ ImportRoot string
+ Packages map[string]PackageOrErr
+}
+
// ToReachMap looks through a PackageTree and computes the list of external
// import statements (that is, import statements pointing to packages that are
// not logical children of PackageTree.ImportRoot) that are transitively
@@ -525,9 +472,34 @@ func (t PackageTree) ToReachMap(main, tests, backprop bool, ignore map[string]bo
return wmToReach(workmap, backprop)
}
-// Helper func to create an error when a package is missing.
-func missingPkgErr(pkg string) error {
- return fmt.Errorf("no package exists at %q", pkg)
+// Copy copies the PackageTree.
+//
+// This is really only useful as a defensive measure to prevent external state
+// mutations.
+func (t PackageTree) Copy() PackageTree {
+ t2 := PackageTree{
+ ImportRoot: t.ImportRoot,
+ Packages: map[string]PackageOrErr{},
+ }
+
+ for path, poe := range t.Packages {
+ poe2 := PackageOrErr{
+ Err: poe.Err,
+ P: poe.P,
+ }
+ if len(poe.P.Imports) > 0 {
+ poe2.P.Imports = make([]string, len(poe.P.Imports))
+ copy(poe2.P.Imports, poe.P.Imports)
+ }
+ if len(poe.P.TestImports) > 0 {
+ poe2.P.TestImports = make([]string, len(poe.P.TestImports))
+ copy(poe2.P.TestImports, poe.P.TestImports)
+ }
+
+ t2.Packages[path] = poe2
+ }
+
+ return t2
}
// wmToReach takes an internal "workmap" constructed by
@@ -857,64 +829,6 @@ func wmToReach(workmap map[string]wm, backprop bool) (ReachMap, map[string]*Prob
return rm, errmap
}
-// FlattenAll flattens a reachmap into a sorted, deduplicated list of all the
-// external imports named by its contained packages.
-//
-// If stdlib is true, then stdlib imports are excluded from the result.
-func (rm ReachMap) FlattenAll(stdlib bool) []string {
- return rm.flatten(func(pkg string) bool { return true }, stdlib)
-}
-
-// Flatten flattens a reachmap into a sorted, deduplicated list of all the
-// external imports named by its contained packages, but excludes imports coming
-// from packages with disallowed patterns in their names: any path element with
-// a leading dot, a leading underscore, with the name "testdata".
-//
-// If stdlib is true, then stdlib imports are excluded from the result.
-func (rm ReachMap) Flatten(stdlib bool) []string {
- f := func(pkg string) bool {
- // Eliminate import paths with any elements having leading dots, leading
- // underscores, or testdata. If these are internally reachable (which is
- // a no-no, but possible), any external imports will have already been
- // pulled up through ExternalReach. The key here is that we don't want
- // to treat such packages as themselves being sources.
- for _, elem := range strings.Split(pkg, "/") {
- if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
- return false
- }
- }
- return true
- }
-
- return rm.flatten(f, stdlib)
-}
-
-func (rm ReachMap) flatten(filter func(string) bool, stdlib bool) []string {
- exm := make(map[string]struct{})
- for pkg, ie := range rm {
- if filter(pkg) {
- for _, ex := range ie.External {
- if !stdlib && isStdLib(ex) {
- continue
- }
- exm[ex] = struct{}{}
- }
- }
- }
-
- if len(exm) == 0 {
- return []string{}
- }
-
- ex := make([]string, 0, len(exm))
- for p := range exm {
- ex = append(ex, p)
- }
-
- sort.Strings(ex)
- return ex
-}
-
// eqOrSlashedPrefix checks to see if the prefix is either equal to the string,
// or that it is a prefix and the next char in the string is "/".
func eqOrSlashedPrefix(s, prefix string) bool {
diff --git a/vendor/github.com/sdboyer/gps/analysis_test.go b/vendor/github.com/sdboyer/gps/pkgtree/pkgtree_test.go
similarity index 92%
rename from vendor/github.com/sdboyer/gps/analysis_test.go
rename to vendor/github.com/sdboyer/gps/pkgtree/pkgtree_test.go
index 47adb6a745..2dce984286 100644
--- a/vendor/github.com/sdboyer/gps/analysis_test.go
+++ b/vendor/github.com/sdboyer/gps/pkgtree/pkgtree_test.go
@@ -1,4 +1,4 @@
-package gps
+package pkgtree
import (
"fmt"
@@ -12,8 +12,26 @@ import (
"runtime"
"strings"
"testing"
+
+ "github.com/sdboyer/gps/internal"
+ "github.com/sdboyer/gps/internal/fs"
)
+// Stores a reference to original IsStdLib, so we could restore overridden version.
+var doIsStdLib = internal.IsStdLib
+
+func init() {
+ overrideIsStdLib()
+}
+
+// sets the IsStdLib func to always return false, otherwise it would identify
+// pretty much all of our fixtures as being stdlib and skip everything.
+func overrideIsStdLib() {
+ internal.IsStdLib = func(path string) bool {
+ return false
+ }
+}
+
// PackageTree.ToReachMap() uses an easily separable algorithm, wmToReach(),
// to turn a discovered set of packages and their imports into a proper pair of
// internal and external reach maps.
@@ -434,24 +452,26 @@ func TestWorkmapToReach(t *testing.T) {
for name, fix := range table {
// Avoid erroneous errors by initializing the fixture's error map if
// needed
- if fix.em == nil {
- fix.em = make(map[string]*ProblemImportError)
- }
+ t.Run(name, func(t *testing.T) {
+ if fix.em == nil {
+ fix.em = make(map[string]*ProblemImportError)
+ }
- rm, em := wmToReach(fix.workmap, fix.backprop)
- if !reflect.DeepEqual(rm, fix.rm) {
- //t.Error(pretty.Sprintf("wmToReach(%q): Did not get expected reach map:\n\t(GOT): %s\n\t(WNT): %s", name, rm, fix.rm))
- t.Errorf("wmToReach(%q): Did not get expected reach map:\n\t(GOT): %s\n\t(WNT): %s", name, rm, fix.rm)
- }
- if !reflect.DeepEqual(em, fix.em) {
- //t.Error(pretty.Sprintf("wmToReach(%q): Did not get expected error map:\n\t(GOT): %# v\n\t(WNT): %# v", name, em, fix.em))
- t.Errorf("wmToReach(%q): Did not get expected error map:\n\t(GOT): %v\n\t(WNT): %v", name, em, fix.em)
- }
+ rm, em := wmToReach(fix.workmap, fix.backprop)
+ if !reflect.DeepEqual(rm, fix.rm) {
+ //t.Error(pretty.Sprintf("wmToReach(%q): Did not get expected reach map:\n\t(GOT): %s\n\t(WNT): %s", name, rm, fix.rm))
+ t.Errorf("Did not get expected reach map:\n\t(GOT): %s\n\t(WNT): %s", rm, fix.rm)
+ }
+ if !reflect.DeepEqual(em, fix.em) {
+ //t.Error(pretty.Sprintf("wmToReach(%q): Did not get expected error map:\n\t(GOT): %# v\n\t(WNT): %# v", name, em, fix.em))
+ t.Errorf("Did not get expected error map:\n\t(GOT): %v\n\t(WNT): %v", em, fix.em)
+ }
+ })
}
}
func TestListPackagesNoDir(t *testing.T) {
- out, err := ListPackages(filepath.Join(getwd(t), "_testdata", "notexist"), "notexist")
+ out, err := ListPackages(filepath.Join(getTestdataRootDir(t), "notexist"), "notexist")
if err == nil {
t.Error("ListPackages should have errored on pointing to a nonexistent dir")
}
@@ -461,7 +481,7 @@ func TestListPackagesNoDir(t *testing.T) {
}
func TestListPackages(t *testing.T) {
- srcdir := filepath.Join(getwd(t), "_testdata", "src")
+ srcdir := filepath.Join(getTestdataRootDir(t), "src")
j := func(s ...string) string {
return filepath.Join(srcdir, filepath.Join(s...))
}
@@ -1236,59 +1256,60 @@ func TestListPackages(t *testing.T) {
}
for name, fix := range table {
- if _, err := os.Stat(fix.fileRoot); err != nil {
- t.Errorf("listPackages(%q): error on fileRoot %s: %s", name, fix.fileRoot, err)
- continue
- }
-
- out, err := ListPackages(fix.fileRoot, fix.importRoot)
-
- if err != nil && fix.err == nil {
- t.Errorf("listPackages(%q): Received error but none expected: %s", name, err)
- } else if fix.err != nil && err == nil {
- t.Errorf("listPackages(%q): Error expected but none received", name)
- } else if fix.err != nil && err != nil {
- if !reflect.DeepEqual(fix.err, err) {
- t.Errorf("listPackages(%q): Did not receive expected error:\n\t(GOT): %s\n\t(WNT): %s", name, err, fix.err)
+ t.Run(name, func(t *testing.T) {
+ if _, err := os.Stat(fix.fileRoot); err != nil {
+ t.Errorf("error on fileRoot %s: %s", fix.fileRoot, err)
}
- }
- if fix.out.ImportRoot != "" && fix.out.Packages != nil {
- if !reflect.DeepEqual(out, fix.out) {
- if fix.out.ImportRoot != out.ImportRoot {
- t.Errorf("listPackages(%q): Expected ImportRoot %s, got %s", name, fix.out.ImportRoot, out.ImportRoot)
- }
+ out, err := ListPackages(fix.fileRoot, fix.importRoot)
- // overwrite the out one to see if we still have a real problem
- out.ImportRoot = fix.out.ImportRoot
+ if err != nil && fix.err == nil {
+ t.Errorf("Received error but none expected: %s", err)
+ } else if fix.err != nil && err == nil {
+ t.Errorf("Error expected but none received")
+ } else if fix.err != nil && err != nil {
+ if !reflect.DeepEqual(fix.err, err) {
+ t.Errorf("Did not receive expected error:\n\t(GOT): %s\n\t(WNT): %s", err, fix.err)
+ }
+ }
+ if fix.out.ImportRoot != "" && fix.out.Packages != nil {
if !reflect.DeepEqual(out, fix.out) {
- if len(fix.out.Packages) < 2 {
- t.Errorf("listPackages(%q): Did not get expected PackageOrErrs:\n\t(GOT): %#v\n\t(WNT): %#v", name, out, fix.out)
- } else {
- seen := make(map[string]bool)
- for path, perr := range fix.out.Packages {
- seen[path] = true
- if operr, exists := out.Packages[path]; !exists {
- t.Errorf("listPackages(%q): Expected PackageOrErr for path %s was missing from output:\n\t%s", name, path, perr)
- } else {
- if !reflect.DeepEqual(perr, operr) {
- t.Errorf("listPackages(%q): PkgOrErr for path %s was not as expected:\n\t(GOT): %#v\n\t(WNT): %#v", name, path, operr, perr)
+ if fix.out.ImportRoot != out.ImportRoot {
+ t.Errorf("Expected ImportRoot %s, got %s", fix.out.ImportRoot, out.ImportRoot)
+ }
+
+ // overwrite the out one to see if we still have a real problem
+ out.ImportRoot = fix.out.ImportRoot
+
+ if !reflect.DeepEqual(out, fix.out) {
+ if len(fix.out.Packages) < 2 {
+ t.Errorf("Did not get expected PackageOrErrs:\n\t(GOT): %#v\n\t(WNT): %#v", out, fix.out)
+ } else {
+ seen := make(map[string]bool)
+ for path, perr := range fix.out.Packages {
+ seen[path] = true
+ if operr, exists := out.Packages[path]; !exists {
+ t.Errorf("Expected PackageOrErr for path %s was missing from output:\n\t%s", path, perr)
+ } else {
+ if !reflect.DeepEqual(perr, operr) {
+ t.Errorf("PkgOrErr for path %s was not as expected:\n\t(GOT): %#v\n\t(WNT): %#v", path, operr, perr)
+ }
}
}
- }
- for path, operr := range out.Packages {
- if seen[path] {
- continue
- }
+ for path, operr := range out.Packages {
+ if seen[path] {
+ continue
+ }
- t.Errorf("listPackages(%q): Got PackageOrErr for path %s, but none was expected:\n\t%s", name, path, operr)
+ t.Errorf("Got PackageOrErr for path %s, but none was expected:\n\t%s", path, operr)
+ }
}
}
}
}
- }
+ })
}
}
@@ -1313,9 +1334,9 @@ func TestListPackagesNoPerms(t *testing.T) {
}
defer os.RemoveAll(tmp)
- srcdir := filepath.Join(getwd(t), "_testdata", "src", "ren")
+ srcdir := filepath.Join(getTestdataRootDir(t), "src", "ren")
workdir := filepath.Join(tmp, "ren")
- copyDir(srcdir, workdir)
+ fs.CopyDir(srcdir, workdir)
// chmod the simple dir and m1p/b.go file so they can't be read
err = os.Chmod(filepath.Join(workdir, "simple"), 0)
@@ -1382,186 +1403,9 @@ func TestListPackagesNoPerms(t *testing.T) {
}
}
-func TestFlattenReachMap(t *testing.T) {
- // There's enough in the 'varied' test case to test most of what matters
- vptree, err := ListPackages(filepath.Join(getwd(t), "_testdata", "src", "github.com", "example", "varied"), "github.com/example/varied")
- if err != nil {
- t.Fatalf("listPackages failed on varied test case: %s", err)
- }
-
- var expect []string
- var name string
- var ignore map[string]bool
- var stdlib, main, tests bool
-
- validate := func() {
- rm, em := vptree.ToReachMap(main, tests, true, ignore)
- if len(em) != 0 {
- t.Errorf("Should not have any error pkgs from ToReachMap, got %s", em)
- }
- result := rm.Flatten(stdlib)
- if !reflect.DeepEqual(expect, result) {
- t.Errorf("Wrong imports in %q case:\n\t(GOT): %s\n\t(WNT): %s", name, result, expect)
- }
- }
-
- all := []string{
- "encoding/binary",
- "github.com/Masterminds/semver",
- "github.com/sdboyer/gps",
- "go/parser",
- "hash",
- "net/http",
- "os",
- "sort",
- }
-
- // helper to rewrite expect, except for a couple packages
- //
- // this makes it easier to see what we're taking out on each test
- except := func(not ...string) {
- expect = make([]string, len(all)-len(not))
-
- drop := make(map[string]bool)
- for _, npath := range not {
- drop[npath] = true
- }
-
- k := 0
- for _, path := range all {
- if !drop[path] {
- expect[k] = path
- k++
- }
- }
- }
-
- // everything on
- name = "simple"
- except()
- stdlib, main, tests = true, true, true
- validate()
-
- // turning off stdlib should cut most things, but we need to override the
- // function
- isStdLib = doIsStdLib
- name = "no stdlib"
- stdlib = false
- except("encoding/binary", "go/parser", "hash", "net/http", "os", "sort")
- validate()
- // Restore stdlib func override
- overrideIsStdLib()
-
- // stdlib back in; now exclude tests, which should just cut one
- name = "no tests"
- stdlib, tests = true, false
- except("encoding/binary")
- validate()
-
- // Now skip main, which still just cuts out one
- name = "no main"
- main, tests = false, true
- except("net/http")
- validate()
-
- // No test and no main, which should be additive
- name = "no test, no main"
- main, tests = false, false
- except("net/http", "encoding/binary")
- validate()
-
- // now, the ignore tests. turn main and tests back on
- main, tests = true, true
-
- // start with non-matching
- name = "non-matching ignore"
- ignore = map[string]bool{
- "nomatch": true,
- }
- except()
- validate()
-
- // should have the same effect as ignoring main
- name = "ignore the root"
- ignore = map[string]bool{
- "github.com/example/varied": true,
- }
- except("net/http")
- validate()
-
- // now drop a more interesting one
- name = "ignore simple"
- ignore = map[string]bool{
- "github.com/example/varied/simple": true,
- }
- // we get github.com/sdboyer/gps from m1p, too, so it should still be there
- except("go/parser")
- validate()
-
- // now drop two
- name = "ignore simple and namemismatch"
- ignore = map[string]bool{
- "github.com/example/varied/simple": true,
- "github.com/example/varied/namemismatch": true,
- }
- except("go/parser", "github.com/Masterminds/semver")
- validate()
-
- // make sure tests and main play nice with ignore
- name = "ignore simple and namemismatch, and no tests"
- tests = false
- except("go/parser", "github.com/Masterminds/semver", "encoding/binary")
- validate()
- name = "ignore simple and namemismatch, and no main"
- main, tests = false, true
- except("go/parser", "github.com/Masterminds/semver", "net/http")
- validate()
- name = "ignore simple and namemismatch, and no main or tests"
- main, tests = false, false
- except("go/parser", "github.com/Masterminds/semver", "net/http", "encoding/binary")
- validate()
-
- main, tests = true, true
-
- // ignore two that should knock out gps
- name = "ignore both importers"
- ignore = map[string]bool{
- "github.com/example/varied/simple": true,
- "github.com/example/varied/m1p": true,
- }
- except("sort", "github.com/sdboyer/gps", "go/parser")
- validate()
-
- // finally, directly ignore some external packages
- name = "ignore external"
- ignore = map[string]bool{
- "github.com/sdboyer/gps": true,
- "go/parser": true,
- "sort": true,
- }
- except("sort", "github.com/sdboyer/gps", "go/parser")
- validate()
-
- // The only thing varied *doesn't* cover is disallowed path patterns
- ptree, err := ListPackages(filepath.Join(getwd(t), "_testdata", "src", "disallow"), "disallow")
- if err != nil {
- t.Fatalf("ListPackages failed on disallow test case: %s", err)
- }
-
- rm, em := ptree.ToReachMap(false, false, true, nil)
- if len(em) != 0 {
- t.Errorf("Should not have any error packages from ToReachMap, got %s", em)
- }
- result := rm.Flatten(true)
- expect = []string{"github.com/sdboyer/gps", "hash", "sort"}
- if !reflect.DeepEqual(expect, result) {
- t.Errorf("Wrong imports in %q case:\n\t(GOT): %s\n\t(WNT): %s", name, result, expect)
- }
-}
-
func TestToReachMap(t *testing.T) {
// There's enough in the 'varied' test case to test most of what matters
- vptree, err := ListPackages(filepath.Join(getwd(t), "_testdata", "src", "github.com", "example", "varied"), "github.com/example/varied")
+ vptree, err := ListPackages(filepath.Join(getTestdataRootDir(t), "src", "github.com", "example", "varied"), "github.com/example/varied")
if err != nil {
t.Fatalf("ListPackages failed on varied test case: %s", err)
}
@@ -1823,9 +1667,186 @@ func TestToReachMap(t *testing.T) {
validate()
}
+func TestFlattenReachMap(t *testing.T) {
+ // There's enough in the 'varied' test case to test most of what matters
+ vptree, err := ListPackages(filepath.Join(getTestdataRootDir(t), "src", "github.com", "example", "varied"), "github.com/example/varied")
+ if err != nil {
+ t.Fatalf("listPackages failed on varied test case: %s", err)
+ }
+
+ var expect []string
+ var name string
+ var ignore map[string]bool
+ var stdlib, main, tests bool
+
+ validate := func() {
+ rm, em := vptree.ToReachMap(main, tests, true, ignore)
+ if len(em) != 0 {
+ t.Errorf("Should not have any error pkgs from ToReachMap, got %s", em)
+ }
+ result := rm.Flatten(stdlib)
+ if !reflect.DeepEqual(expect, result) {
+ t.Errorf("Wrong imports in %q case:\n\t(GOT): %s\n\t(WNT): %s", name, result, expect)
+ }
+ }
+
+ all := []string{
+ "encoding/binary",
+ "github.com/Masterminds/semver",
+ "github.com/sdboyer/gps",
+ "go/parser",
+ "hash",
+ "net/http",
+ "os",
+ "sort",
+ }
+
+ // helper to rewrite expect, except for a couple packages
+ //
+ // this makes it easier to see what we're taking out on each test
+ except := func(not ...string) {
+ expect = make([]string, len(all)-len(not))
+
+ drop := make(map[string]bool)
+ for _, npath := range not {
+ drop[npath] = true
+ }
+
+ k := 0
+ for _, path := range all {
+ if !drop[path] {
+ expect[k] = path
+ k++
+ }
+ }
+ }
+
+ // everything on
+ name = "simple"
+ except()
+ stdlib, main, tests = true, true, true
+ validate()
+
+ // turning off stdlib should cut most things, but we need to override the
+ // function
+ internal.IsStdLib = doIsStdLib
+ name = "no stdlib"
+ stdlib = false
+ except("encoding/binary", "go/parser", "hash", "net/http", "os", "sort")
+ validate()
+ // restore stdlib func override
+ overrideIsStdLib()
+
+ // stdlib back in; now exclude tests, which should just cut one
+ name = "no tests"
+ stdlib, tests = true, false
+ except("encoding/binary")
+ validate()
+
+ // Now skip main, which still just cuts out one
+ name = "no main"
+ main, tests = false, true
+ except("net/http")
+ validate()
+
+ // No test and no main, which should be additive
+ name = "no test, no main"
+ main, tests = false, false
+ except("net/http", "encoding/binary")
+ validate()
+
+ // now, the ignore tests. turn main and tests back on
+ main, tests = true, true
+
+ // start with non-matching
+ name = "non-matching ignore"
+ ignore = map[string]bool{
+ "nomatch": true,
+ }
+ except()
+ validate()
+
+ // should have the same effect as ignoring main
+ name = "ignore the root"
+ ignore = map[string]bool{
+ "github.com/example/varied": true,
+ }
+ except("net/http")
+ validate()
+
+ // now drop a more interesting one
+ name = "ignore simple"
+ ignore = map[string]bool{
+ "github.com/example/varied/simple": true,
+ }
+ // we get github.com/sdboyer/gps from m1p, too, so it should still be there
+ except("go/parser")
+ validate()
+
+ // now drop two
+ name = "ignore simple and namemismatch"
+ ignore = map[string]bool{
+ "github.com/example/varied/simple": true,
+ "github.com/example/varied/namemismatch": true,
+ }
+ except("go/parser", "github.com/Masterminds/semver")
+ validate()
+
+ // make sure tests and main play nice with ignore
+ name = "ignore simple and namemismatch, and no tests"
+ tests = false
+ except("go/parser", "github.com/Masterminds/semver", "encoding/binary")
+ validate()
+ name = "ignore simple and namemismatch, and no main"
+ main, tests = false, true
+ except("go/parser", "github.com/Masterminds/semver", "net/http")
+ validate()
+ name = "ignore simple and namemismatch, and no main or tests"
+ main, tests = false, false
+ except("go/parser", "github.com/Masterminds/semver", "net/http", "encoding/binary")
+ validate()
+
+ main, tests = true, true
+
+ // ignore two that should knock out gps
+ name = "ignore both importers"
+ ignore = map[string]bool{
+ "github.com/example/varied/simple": true,
+ "github.com/example/varied/m1p": true,
+ }
+ except("sort", "github.com/sdboyer/gps", "go/parser")
+ validate()
+
+ // finally, directly ignore some external packages
+ name = "ignore external"
+ ignore = map[string]bool{
+ "github.com/sdboyer/gps": true,
+ "go/parser": true,
+ "sort": true,
+ }
+ except("sort", "github.com/sdboyer/gps", "go/parser")
+ validate()
+
+ // The only thing varied *doesn't* cover is disallowed path patterns
+ ptree, err := ListPackages(filepath.Join(getTestdataRootDir(t), "src", "disallow"), "disallow")
+ if err != nil {
+ t.Fatalf("ListPackages failed on disallow test case: %s", err)
+ }
+
+ rm, em := ptree.ToReachMap(false, false, true, nil)
+ if len(em) != 0 {
+ t.Errorf("Should not have any error packages from ToReachMap, got %s", em)
+ }
+ result := rm.Flatten(true)
+ expect = []string{"github.com/sdboyer/gps", "hash", "sort"}
+ if !reflect.DeepEqual(expect, result) {
+ t.Errorf("Wrong imports in %q case:\n\t(GOT): %s\n\t(WNT): %s", name, result, expect)
+ }
+}
+
// Verify that we handle import cycles correctly - drop em all
func TestToReachMapCycle(t *testing.T) {
- ptree, err := ListPackages(filepath.Join(getwd(t), "_testdata", "src", "cycle"), "cycle")
+ ptree, err := ListPackages(filepath.Join(getTestdataRootDir(t), "src", "cycle"), "cycle")
if err != nil {
t.Fatalf("ListPackages failed on cycle test case: %s", err)
}
@@ -1845,10 +1866,10 @@ func TestToReachMapCycle(t *testing.T) {
}
}
-func getwd(t *testing.T) string {
+func getTestdataRootDir(t *testing.T) string {
cwd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
- return cwd
+ return filepath.Join(cwd, "..", "_testdata")
}
diff --git a/vendor/github.com/sdboyer/gps/pkgtree/reachmap.go b/vendor/github.com/sdboyer/gps/pkgtree/reachmap.go
new file mode 100644
index 0000000000..5d1f155907
--- /dev/null
+++ b/vendor/github.com/sdboyer/gps/pkgtree/reachmap.go
@@ -0,0 +1,75 @@
+package pkgtree
+
+import (
+ "sort"
+ "strings"
+
+ "github.com/sdboyer/gps/internal"
+)
+
+// ReachMap maps a set of import paths (keys) to the sets of transitively
+// reachable tree-internal packages, and all the tree-external packages
+// reachable through those internal packages.
+//
+// See PackageTree.ToReachMap() for more information.
+type ReachMap map[string]struct {
+ Internal, External []string
+}
+
+// FlattenAll flattens a reachmap into a sorted, deduplicated list of all the
+// external imports named by its contained packages.
+//
+// If stdlib is false, then stdlib imports are excluded from the result.
+func (rm ReachMap) FlattenAll(stdlib bool) []string {
+ return rm.flatten(func(pkg string) bool { return true }, stdlib)
+}
+
+// Flatten flattens a reachmap into a sorted, deduplicated list of all the
+// external imports named by its contained packages, but excludes imports coming
+// from packages with disallowed patterns in their names: any path element with
+// a leading dot, a leading underscore, with the name "testdata".
+//
+// If stdlib is false, then stdlib imports are excluded from the result.
+func (rm ReachMap) Flatten(stdlib bool) []string {
+ f := func(pkg string) bool {
+ // Eliminate import paths with any elements having leading dots, leading
+ // underscores, or testdata. If these are internally reachable (which is
+ // a no-no, but possible), any external imports will have already been
+ // pulled up through ExternalReach. The key here is that we don't want
+ // to treat such packages as themselves being sources.
+ for _, elem := range strings.Split(pkg, "/") {
+ if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
+ return false
+ }
+ }
+ return true
+ }
+
+ return rm.flatten(f, stdlib)
+}
+
+func (rm ReachMap) flatten(filter func(string) bool, stdlib bool) []string {
+ exm := make(map[string]struct{})
+ for pkg, ie := range rm {
+ if filter(pkg) {
+ for _, ex := range ie.External {
+ if !stdlib && internal.IsStdLib(ex) {
+ continue
+ }
+ exm[ex] = struct{}{}
+ }
+ }
+ }
+
+ if len(exm) == 0 {
+ return []string{}
+ }
+
+ ex := make([]string, 0, len(exm))
+ for p := range exm {
+ ex = append(ex, p)
+ }
+
+ sort.Strings(ex)
+ return ex
+}
\ No newline at end of file
diff --git a/vendor/github.com/sdboyer/gps/result_test.go b/vendor/github.com/sdboyer/gps/result_test.go
index ee6ab359f4..1cf9273266 100644
--- a/vendor/github.com/sdboyer/gps/result_test.go
+++ b/vendor/github.com/sdboyer/gps/result_test.go
@@ -44,6 +44,7 @@ func TestWriteDepTree(t *testing.T) {
if testing.Short() {
t.Skip("Skipping dep tree writing test in short mode")
}
+ requiresBins(t, "git", "hg", "bzr")
tmp, err := ioutil.TempDir("", "writetree")
if err != nil {
diff --git a/vendor/github.com/sdboyer/gps/rootdata.go b/vendor/github.com/sdboyer/gps/rootdata.go
index 3a4696c602..79d838216b 100644
--- a/vendor/github.com/sdboyer/gps/rootdata.go
+++ b/vendor/github.com/sdboyer/gps/rootdata.go
@@ -4,6 +4,8 @@ import (
"sort"
"github.com/armon/go-radix"
+ "github.com/sdboyer/gps/internal"
+ "github.com/sdboyer/gps/pkgtree"
)
// rootdata holds static data and constraining rules from the root project for
@@ -39,10 +41,10 @@ type rootdata struct {
rl safeLock
// A defensively copied instance of params.RootPackageTree
- rpt PackageTree
+ rpt pkgtree.PackageTree
}
-// rootImportList returns a list of the unique imports from the root data.
+// externalImportList returns a list of the unique imports from the root data.
// Ignores and requires are taken into consideration, stdlib is excluded, and
// errors within the local set of package are not backpropagated.
func (rd rootdata) externalImportList() []string {
@@ -50,7 +52,7 @@ func (rd rootdata) externalImportList() []string {
all := rm.Flatten(false)
reach := make([]string, 0, len(all))
for _, r := range all {
- if !isStdLib(r) {
+ if !internal.IsStdLib(r) {
reach = append(reach, r)
}
}
@@ -112,7 +114,7 @@ func (rd rootdata) getApplicableConstraints() []workingConstraint {
// Walk all dep import paths we have to consider and mark the corresponding
// wc entry in the trie, if any
for _, im := range rd.externalImportList() {
- if isStdLib(im) {
+ if internal.IsStdLib(im) {
continue
}
diff --git a/vendor/github.com/sdboyer/gps/rootdata_test.go b/vendor/github.com/sdboyer/gps/rootdata_test.go
index c0ad5c3951..e3126322bc 100644
--- a/vendor/github.com/sdboyer/gps/rootdata_test.go
+++ b/vendor/github.com/sdboyer/gps/rootdata_test.go
@@ -204,11 +204,13 @@ func TestGetApplicableConstraints(t *testing.T) {
}
for _, fix := range table {
- fix.mut()
-
- got := rd.getApplicableConstraints()
- if !reflect.DeepEqual(fix.result, got) {
- t.Errorf("(fix: %q) unexpected applicable constraint set:\n\t(GOT): %+v\n\t(WNT): %+v", fix.name, got, fix.result)
- }
+ t.Run(fix.name, func(t *testing.T) {
+ fix.mut()
+
+ got := rd.getApplicableConstraints()
+ if !reflect.DeepEqual(fix.result, got) {
+ t.Errorf("unexpected applicable constraint set:\n\t(GOT): %+v\n\t(WNT): %+v", got, fix.result)
+ }
+ })
}
}
diff --git a/vendor/github.com/sdboyer/gps/solve_basic_test.go b/vendor/github.com/sdboyer/gps/solve_basic_test.go
index 956692782a..575bfa54a0 100644
--- a/vendor/github.com/sdboyer/gps/solve_basic_test.go
+++ b/vendor/github.com/sdboyer/gps/solve_basic_test.go
@@ -6,6 +6,7 @@ import (
"strings"
"github.com/Masterminds/semver"
+ "github.com/sdboyer/gps/pkgtree"
)
var regfrom = regexp.MustCompile(`^(\w*) from (\w*) ([0-9\.\*]*)`)
@@ -371,7 +372,7 @@ type pident struct {
type specfix interface {
name() string
rootmanifest() RootManifest
- rootTree() PackageTree
+ rootTree() pkgtree.PackageTree
specs() []depspec
maxTries() int
solution() map[ProjectIdentifier]LockedProject
@@ -439,7 +440,7 @@ func (f basicFixture) rootmanifest() RootManifest {
}
}
-func (f basicFixture) rootTree() PackageTree {
+func (f basicFixture) rootTree() pkgtree.PackageTree {
var imp, timp []string
for _, dep := range f.ds[0].deps {
imp = append(imp, string(dep.Ident.ProjectRoot))
@@ -449,11 +450,11 @@ func (f basicFixture) rootTree() PackageTree {
}
n := string(f.ds[0].n)
- pt := PackageTree{
+ pt := pkgtree.PackageTree{
ImportRoot: n,
- Packages: map[string]PackageOrErr{
+ Packages: map[string]pkgtree.PackageOrErr{
string(n): {
- P: Package{
+ P: pkgtree.Package{
ImportPath: n,
Name: n,
Imports: imp,
@@ -1350,7 +1351,7 @@ func init() {
}
// reachMaps contain externalReach()-type data for a given depspec fixture's
-// universe of proejcts, packages, and versions.
+// universe of projects, packages, and versions.
type reachMap map[pident]map[string][]string
type depspecSourceManager struct {
@@ -1404,8 +1405,8 @@ func (sm *depspecSourceManager) GetManifestAndLock(id ProjectIdentifier, v Versi
return nil, nil, fmt.Errorf("Project %s at version %s could not be found", id.errString(), v)
}
-func (sm *depspecSourceManager) AnalyzerInfo() (string, *semver.Version) {
- return "depspec-sm-builtin", sv("v1.0.0")
+func (sm *depspecSourceManager) AnalyzerInfo() (string, int) {
+ return "depspec-sm-builtin", 1
}
func (sm *depspecSourceManager) ExternalReach(id ProjectIdentifier, v Version) (map[string][]string, error) {
@@ -1416,15 +1417,15 @@ func (sm *depspecSourceManager) ExternalReach(id ProjectIdentifier, v Version) (
return nil, fmt.Errorf("No reach data for %s at version %s", id.errString(), v)
}
-func (sm *depspecSourceManager) ListPackages(id ProjectIdentifier, v Version) (PackageTree, error) {
+func (sm *depspecSourceManager) ListPackages(id ProjectIdentifier, v Version) (pkgtree.PackageTree, error) {
pid := pident{n: ProjectRoot(id.normalizedSource()), v: v}
if r, exists := sm.rm[pid]; exists {
- return PackageTree{
+ return pkgtree.PackageTree{
ImportRoot: string(pid.n),
- Packages: map[string]PackageOrErr{
+ Packages: map[string]pkgtree.PackageOrErr{
string(pid.n): {
- P: Package{
+ P: pkgtree.Package{
ImportPath: string(pid.n),
Name: string(pid.n),
Imports: r[string(pid.n)],
@@ -1440,11 +1441,11 @@ func (sm *depspecSourceManager) ListPackages(id ProjectIdentifier, v Version) (P
uv := pv.Unpair()
for pid, r := range sm.rm {
if uv.Matches(pid.v) {
- return PackageTree{
+ return pkgtree.PackageTree{
ImportRoot: string(pid.n),
- Packages: map[string]PackageOrErr{
+ Packages: map[string]pkgtree.PackageOrErr{
string(pid.n): {
- P: Package{
+ P: pkgtree.Package{
ImportPath: string(pid.n),
Name: string(pid.n),
Imports: r[string(pid.n)],
@@ -1456,7 +1457,7 @@ func (sm *depspecSourceManager) ListPackages(id ProjectIdentifier, v Version) (P
}
}
- return PackageTree{}, fmt.Errorf("Project %s at version %s could not be found", pid.n, v)
+ return pkgtree.PackageTree{}, fmt.Errorf("Project %s at version %s could not be found", pid.n, v)
}
func (sm *depspecSourceManager) ListVersions(id ProjectIdentifier) (pi []Version, err error) {
@@ -1545,7 +1546,7 @@ func (b *depspecBridge) verifyRootDir(path string) error {
return nil
}
-func (b *depspecBridge) ListPackages(id ProjectIdentifier, v Version) (PackageTree, error) {
+func (b *depspecBridge) ListPackages(id ProjectIdentifier, v Version) (pkgtree.PackageTree, error) {
return b.sm.(fixSM).ListPackages(id, v)
}
@@ -1600,195 +1601,3 @@ func (dummyLock) InputHash() []byte {
func (dummyLock) Projects() []LockedProject {
return nil
}
-
-// We've borrowed this bestiary from pub's tests:
-// https://github.com/dart-lang/pub/blob/master/test/version_solver_test.dart
-
-// TODO(sdboyer) finish converting all of these
-
-/*
-func basicGraph() {
- testResolve("circular dependency", {
- "myapp 1.0.0": {
- "foo": "1.0.0"
- },
- "foo 1.0.0": {
- "bar": "1.0.0"
- },
- "bar 1.0.0": {
- "foo": "1.0.0"
- }
- }, result: {
- "myapp from root": "1.0.0",
- "foo": "1.0.0",
- "bar": "1.0.0"
- });
-
-}
-
-func withLockFile() {
-
-}
-
-func rootDependency() {
- testResolve("with root source", {
- "myapp 1.0.0": {
- "foo": "1.0.0"
- },
- "foo 1.0.0": {
- "myapp from root": ">=1.0.0"
- }
- }, result: {
- "myapp from root": "1.0.0",
- "foo": "1.0.0"
- });
-
- testResolve("with different source", {
- "myapp 1.0.0": {
- "foo": "1.0.0"
- },
- "foo 1.0.0": {
- "myapp": ">=1.0.0"
- }
- }, result: {
- "myapp from root": "1.0.0",
- "foo": "1.0.0"
- });
-
- testResolve("with wrong version", {
- "myapp 1.0.0": {
- "foo": "1.0.0"
- },
- "foo 1.0.0": {
- "myapp": "<1.0.0"
- }
- }, error: couldNotSolve);
-}
-
-func unsolvable() {
-
- testResolve("mismatched descriptions", {
- "myapp 0.0.0": {
- "foo": "1.0.0",
- "bar": "1.0.0"
- },
- "foo 1.0.0": {
- "shared-x": "1.0.0"
- },
- "bar 1.0.0": {
- "shared-y": "1.0.0"
- },
- "shared-x 1.0.0": {},
- "shared-y 1.0.0": {}
- }, error: descriptionMismatch("shared", "foo", "bar"));
-
- testResolve("mismatched sources", {
- "myapp 0.0.0": {
- "foo": "1.0.0",
- "bar": "1.0.0"
- },
- "foo 1.0.0": {
- "shared": "1.0.0"
- },
- "bar 1.0.0": {
- "shared from mock2": "1.0.0"
- },
- "shared 1.0.0": {},
- "shared 1.0.0 from mock2": {}
- }, error: sourceMismatch("shared", "foo", "bar"));
-
-
-
- // This is a regression test for #18300.
- testResolve("...", {
- "myapp 0.0.0": {
- "angular": "any",
- "collection": "any"
- },
- "analyzer 0.12.2": {},
- "angular 0.10.0": {
- "di": ">=0.0.32 <0.1.0",
- "collection": ">=0.9.1 <1.0.0"
- },
- "angular 0.9.11": {
- "di": ">=0.0.32 <0.1.0",
- "collection": ">=0.9.1 <1.0.0"
- },
- "angular 0.9.10": {
- "di": ">=0.0.32 <0.1.0",
- "collection": ">=0.9.1 <1.0.0"
- },
- "collection 0.9.0": {},
- "collection 0.9.1": {},
- "di 0.0.37": {"analyzer": ">=0.13.0 <0.14.0"},
- "di 0.0.36": {"analyzer": ">=0.13.0 <0.14.0"}
- }, error: noVersion(["analyzer", "di"]), maxTries: 2);
-}
-
-func badSource() {
- testResolve("fail if the root package has a bad source in dep", {
- "myapp 0.0.0": {
- "foo from bad": "any"
- },
- }, error: unknownSource("myapp", "foo", "bad"));
-
- testResolve("fail if the root package has a bad source in dev dep", {
- "myapp 0.0.0": {
- "(dev) foo from bad": "any"
- },
- }, error: unknownSource("myapp", "foo", "bad"));
-
- testResolve("fail if all versions have bad source in dep", {
- "myapp 0.0.0": {
- "foo": "any"
- },
- "foo 1.0.0": {
- "bar from bad": "any"
- },
- "foo 1.0.1": {
- "baz from bad": "any"
- },
- "foo 1.0.3": {
- "bang from bad": "any"
- },
- }, error: unknownSource("foo", "bar", "bad"), maxTries: 3);
-
- testResolve("ignore versions with bad source in dep", {
- "myapp 1.0.0": {
- "foo": "any"
- },
- "foo 1.0.0": {
- "bar": "any"
- },
- "foo 1.0.1": {
- "bar from bad": "any"
- },
- "foo 1.0.3": {
- "bar from bad": "any"
- },
- "bar 1.0.0": {}
- }, result: {
- "myapp from root": "1.0.0",
- "foo": "1.0.0",
- "bar": "1.0.0"
- }, maxTries: 3);
-}
-
-func backtracking() {
- testResolve("circular dependency on older version", {
- "myapp 0.0.0": {
- "a": ">=1.0.0"
- },
- "a 1.0.0": {},
- "a 2.0.0": {
- "b": "1.0.0"
- },
- "b 1.0.0": {
- "a": "1.0.0"
- }
- }, result: {
- "myapp from root": "0.0.0",
- "a": "1.0.0"
- }, maxTries: 2);
-}
-*/
diff --git a/vendor/github.com/sdboyer/gps/solve_bimodal_test.go b/vendor/github.com/sdboyer/gps/solve_bimodal_test.go
index 3ee7493f2c..48f63a404b 100644
--- a/vendor/github.com/sdboyer/gps/solve_bimodal_test.go
+++ b/vendor/github.com/sdboyer/gps/solve_bimodal_test.go
@@ -4,6 +4,8 @@ import (
"fmt"
"path/filepath"
"strings"
+
+ "github.com/sdboyer/gps/pkgtree"
)
// dsp - "depspec with packages"
@@ -285,6 +287,33 @@ var bimodalFixtures = map[string]bimodalFixture{
"a 1.0.0",
),
},
+ "project cycle involving root with backtracking": {
+ ds: []depspec{
+ dsp(mkDepspec("root 0.0.0", "a ~1.0.0"),
+ pkg("root", "a", "b"),
+ pkg("root/foo"),
+ ),
+ dsp(mkDepspec("a 1.0.0"),
+ pkg("a", "root/foo"),
+ ),
+ dsp(mkDepspec("a 1.0.1"),
+ pkg("a", "root/foo"),
+ ),
+ dsp(mkDepspec("b 1.0.0", "a 1.0.0"),
+ pkg("b", "a"),
+ ),
+ dsp(mkDepspec("b 1.0.1", "a 1.0.0"),
+ pkg("b", "a"),
+ ),
+ dsp(mkDepspec("b 1.0.2", "a 1.0.0"),
+ pkg("b", "a"),
+ ),
+ },
+ r: mksolution(
+ "a 1.0.0",
+ "b 1.0.2",
+ ),
+ },
"project cycle not involving root": {
ds: []depspec{
dsp(mkDepspec("root 0.0.0", "a ~1.0.0"),
@@ -975,7 +1004,7 @@ type tpkg struct {
type bimodalFixture struct {
// name of this fixture datum
n string
- // bimodal project. first is always treated as root project
+ // bimodal project; first is always treated as root project
ds []depspec
// results; map of name/version pairs
r map[ProjectIdentifier]LockedProject
@@ -1034,16 +1063,16 @@ func (f bimodalFixture) rootmanifest() RootManifest {
return m
}
-func (f bimodalFixture) rootTree() PackageTree {
- pt := PackageTree{
+func (f bimodalFixture) rootTree() pkgtree.PackageTree {
+ pt := pkgtree.PackageTree{
ImportRoot: string(f.ds[0].n),
- Packages: map[string]PackageOrErr{},
+ Packages: map[string]pkgtree.PackageOrErr{},
}
for _, pkg := range f.ds[0].pkgs {
elems := strings.Split(pkg.path, "/")
- pt.Packages[pkg.path] = PackageOrErr{
- P: Package{
+ pt.Packages[pkg.path] = pkgtree.PackageOrErr{
+ P: pkgtree.Package{
ImportPath: pkg.path,
Name: elems[len(elems)-1],
// TODO(sdboyer) ugh, tpkg type has no space for supporting test
@@ -1080,17 +1109,17 @@ func newbmSM(bmf bimodalFixture) *bmSourceManager {
return sm
}
-func (sm *bmSourceManager) ListPackages(id ProjectIdentifier, v Version) (PackageTree, error) {
+func (sm *bmSourceManager) ListPackages(id ProjectIdentifier, v Version) (pkgtree.PackageTree, error) {
for k, ds := range sm.specs {
// Cheat for root, otherwise we blow up b/c version is empty
if id.normalizedSource() == string(ds.n) && (k == 0 || ds.v.Matches(v)) {
- ptree := PackageTree{
+ ptree := pkgtree.PackageTree{
ImportRoot: id.normalizedSource(),
- Packages: make(map[string]PackageOrErr),
+ Packages: make(map[string]pkgtree.PackageOrErr),
}
for _, pkg := range ds.pkgs {
- ptree.Packages[pkg.path] = PackageOrErr{
- P: Package{
+ ptree.Packages[pkg.path] = pkgtree.PackageOrErr{
+ P: pkgtree.Package{
ImportPath: pkg.path,
Name: filepath.Base(pkg.path),
Imports: pkg.imports,
@@ -1102,7 +1131,7 @@ func (sm *bmSourceManager) ListPackages(id ProjectIdentifier, v Version) (Packag
}
}
- return PackageTree{}, fmt.Errorf("Project %s at version %s could not be found", id.errString(), v)
+ return pkgtree.PackageTree{}, fmt.Errorf("Project %s at version %s could not be found", id.errString(), v)
}
func (sm *bmSourceManager) GetManifestAndLock(id ProjectIdentifier, v Version) (Manifest, Lock, error) {
@@ -1126,36 +1155,25 @@ func (sm *bmSourceManager) GetManifestAndLock(id ProjectIdentifier, v Version) (
// Note that it does not do things like stripping out stdlib packages - these
// maps are intended for use in SM fixtures, and that's a higher-level
// responsibility within the system.
-func computeBimodalExternalMap(ds []depspec) map[pident]map[string][]string {
+func computeBimodalExternalMap(specs []depspec) map[pident]map[string][]string {
// map of project name+version -> map of subpkg name -> external pkg list
rm := make(map[pident]map[string][]string)
- // algorithm adapted from externalReach()
- for _, d := range ds {
- // Keeps a list of all internal and external reaches for packages within
- // a given root. We create one on each pass through, rather than doing
- // them all at once, because the depspec set may (read: is expected to)
- // have multiple versions of the same base project, and each of those
- // must be calculated independently.
- workmap := make(map[string]wm)
-
- for _, pkg := range d.pkgs {
- w := wm{
- ex: make(map[string]bool),
- in: make(map[string]bool),
- }
-
- for _, imp := range pkg.imports {
- if !eqOrSlashedPrefix(imp, string(d.n)) {
- w.ex[imp] = true
- } else {
- w.in[imp] = true
- }
+ for _, ds := range specs {
+ ptree := pkgtree.PackageTree{
+ ImportRoot: string(ds.n),
+ Packages: make(map[string]pkgtree.PackageOrErr),
+ }
+ for _, pkg := range ds.pkgs {
+ ptree.Packages[pkg.path] = pkgtree.PackageOrErr{
+ P: pkgtree.Package{
+ ImportPath: pkg.path,
+ Name: filepath.Base(pkg.path),
+ Imports: pkg.imports,
+ },
}
- workmap[pkg.path] = w
}
-
- reachmap, em := wmToReach(workmap, true)
+ reachmap, em := ptree.ToReachMap(false, true, true, nil)
if len(em) > 0 {
panic(fmt.Sprintf("pkgs with errors in reachmap processing: %s", em))
}
@@ -1164,7 +1182,7 @@ func computeBimodalExternalMap(ds []depspec) map[pident]map[string][]string {
for ip, ie := range reachmap {
drm[ip] = ie.External
}
- rm[pident{n: d.n, v: d.v}] = drm
+ rm[pident{n: ds.n, v: ds.v}] = drm
}
return rm
diff --git a/vendor/github.com/sdboyer/gps/solve_test.go b/vendor/github.com/sdboyer/gps/solve_test.go
index 9b203f0c4a..8fc4161b96 100644
--- a/vendor/github.com/sdboyer/gps/solve_test.go
+++ b/vendor/github.com/sdboyer/gps/solve_test.go
@@ -7,12 +7,15 @@ import (
"io/ioutil"
"log"
"math/rand"
- "os"
"reflect"
"sort"
"strconv"
"strings"
"testing"
+ "unicode"
+
+ "github.com/sdboyer/gps/internal"
+ "github.com/sdboyer/gps/pkgtree"
)
var fixtorun string
@@ -44,18 +47,36 @@ func overrideMkBridge() {
// sets the isStdLib func to always return false, otherwise it would identify
// pretty much all of our fixtures as being stdlib and skip everything
func overrideIsStdLib() {
- isStdLib = func(path string) bool {
+ internal.IsStdLib = func(path string) bool {
return false
}
}
-var stderrlog = log.New(os.Stderr, "", 0)
+type testlogger struct {
+ *testing.T
+}
+
+func (t testlogger) Write(b []byte) (n int, err error) {
+ str := string(b)
+ if len(str) == 0 {
+ return 0, nil
+ }
-func fixSolve(params SolveParameters, sm SourceManager) (Solution, error) {
- if testing.Verbose() {
- params.Trace = true
- params.TraceLogger = stderrlog
+ for _, part := range strings.Split(str, "\n") {
+ str := strings.TrimRightFunc(part, unicode.IsSpace)
+ if len(str) != 0 {
+ t.T.Log(str)
+ }
}
+ return len(b), err
+}
+
+func fixSolve(params SolveParameters, sm SourceManager, t *testing.T) (Solution, error) {
+ // Trace unconditionally; by passing the trace through t.Log(), the testing
+ // system will decide whether or not to actually show the output (based on
+ // -v, or selectively on test failure).
+ params.Trace = true
+ params.TraceLogger = log.New(testlogger{T: t}, "", 0)
s, err := Prepare(params, sm)
if err != nil {
@@ -82,19 +103,14 @@ func TestBasicSolves(t *testing.T) {
sort.Strings(names)
for _, n := range names {
- solveBasicsAndCheck(basicFixtures[n], t)
- if testing.Verbose() {
- // insert a line break between tests
- stderrlog.Println("")
- }
+ t.Run(n, func(t *testing.T) {
+ solveBasicsAndCheck(basicFixtures[n], t)
+ })
}
}
}
func solveBasicsAndCheck(fix basicFixture, t *testing.T) (res Solution, err error) {
- if testing.Verbose() {
- stderrlog.Printf("[[fixture %q]]", fix.n)
- }
sm := newdepspecSM(fix.ds, nil)
params := SolveParameters{
@@ -111,7 +127,7 @@ func solveBasicsAndCheck(fix basicFixture, t *testing.T) (res Solution, err erro
params.Lock = fix.l
}
- res, err = fixSolve(params, sm)
+ res, err = fixSolve(params, sm, t)
return fixtureSolveSimpleChecks(fix, res, err, t)
}
@@ -133,19 +149,14 @@ func TestBimodalSolves(t *testing.T) {
sort.Strings(names)
for _, n := range names {
- solveBimodalAndCheck(bimodalFixtures[n], t)
- if testing.Verbose() {
- // insert a line break between tests
- stderrlog.Println("")
- }
+ t.Run(n, func(t *testing.T) {
+ solveBimodalAndCheck(bimodalFixtures[n], t)
+ })
}
}
}
func solveBimodalAndCheck(fix bimodalFixture, t *testing.T) (res Solution, err error) {
- if testing.Verbose() {
- stderrlog.Printf("[[fixture %q]]", fix.n)
- }
sm := newbmSM(fix)
params := SolveParameters{
@@ -161,7 +172,7 @@ func solveBimodalAndCheck(fix bimodalFixture, t *testing.T) (res Solution, err e
params.Lock = fix.l
}
- res, err = fixSolve(params, sm)
+ res, err = fixSolve(params, sm, t)
return fixtureSolveSimpleChecks(fix, res, err, t)
}
@@ -288,7 +299,7 @@ func TestRootLockNoVersionPairMatching(t *testing.T) {
Lock: l2,
}
- res, err := fixSolve(params, sm)
+ res, err := fixSolve(params, sm, t)
fixtureSolveSimpleChecks(fix, res, err, t)
}
@@ -325,7 +336,7 @@ func TestBadSolveOpts(t *testing.T) {
t.Error("Prepare should have given error on empty import root, but gave:", err)
}
- params.RootPackageTree = PackageTree{
+ params.RootPackageTree = pkgtree.PackageTree{
ImportRoot: pn,
}
_, err = Prepare(params, sm)
@@ -335,11 +346,11 @@ func TestBadSolveOpts(t *testing.T) {
t.Error("Prepare should have given error on empty import root, but gave:", err)
}
- params.RootPackageTree = PackageTree{
+ params.RootPackageTree = pkgtree.PackageTree{
ImportRoot: pn,
- Packages: map[string]PackageOrErr{
+ Packages: map[string]pkgtree.PackageOrErr{
pn: {
- P: Package{
+ P: pkgtree.Package{
ImportPath: pn,
Name: pn,
},
diff --git a/vendor/github.com/sdboyer/gps/solver.go b/vendor/github.com/sdboyer/gps/solver.go
index 95c913c72f..3d3d8240b2 100644
--- a/vendor/github.com/sdboyer/gps/solver.go
+++ b/vendor/github.com/sdboyer/gps/solver.go
@@ -8,8 +8,27 @@ import (
"strings"
"github.com/armon/go-radix"
+ "github.com/sdboyer/gps/internal"
+ "github.com/sdboyer/gps/pkgtree"
)
+var (
+ osList []string
+ archList []string
+ ignoreTags = []string{} //[]string{"appengine", "ignore"} //TODO: appengine is a special case for now: https://github.com/tools/godep/issues/353
+)
+
+func init() {
+ // The supported systems are listed in
+ // https://github.com/golang/go/blob/master/src/go/build/syslist.go
+ // The lists are not exported, so we need to duplicate them here.
+ osListString := "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows"
+ osList = strings.Split(osListString, " ")
+
+ archListString := "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc s390 s390x sparc sparc64"
+ archList = strings.Split(archListString, " ")
+}
+
var rootRev = Revision("")
// SolveParameters hold all arguments to a solver run.
@@ -38,7 +57,7 @@ type SolveParameters struct {
//
// The ImportRoot property must be a non-empty string, and at least one
// element must be present in the Packages map.
- RootPackageTree PackageTree
+ RootPackageTree pkgtree.PackageTree
// The root manifest. This contains all the dependency constraints
// associated with normal Manifests, as well as the particular controls
@@ -157,7 +176,7 @@ func (params SolveParameters) toRootdata() (rootdata, error) {
ig: params.Manifest.IgnoredPackages(),
req: params.Manifest.RequiredPackages(),
ovr: params.Manifest.Overrides(),
- rpt: params.RootPackageTree.dup(),
+ rpt: params.RootPackageTree.Copy(),
chng: make(map[ProjectRoot]struct{}),
rlm: make(map[ProjectRoot]LockedProject),
chngall: params.ChangeAll,
@@ -579,7 +598,7 @@ func (s *solver) intersectConstraintsWithImports(deps []workingConstraint, reach
dmap := make(map[ProjectRoot]completeDep)
for _, rp := range reach {
// If it's a stdlib-shaped package, skip it.
- if isStdLib(rp) {
+ if internal.IsStdLib(rp) {
continue
}
@@ -1152,6 +1171,12 @@ func (s *solver) unselectLast() (atomWithPackages, bool) {
}
for _, dep := range deps {
+ // Skip popping if the dep is the root project, which can occur if
+ // there's a project-level import cycle. (This occurs frequently with
+ // e.g. kubernetes and docker)
+ if s.rd.isRoot(dep.Ident.ProjectRoot) {
+ continue
+ }
s.sel.popDep(dep.Ident)
// if no parents/importers, remove from unselected queue
diff --git a/vendor/github.com/sdboyer/gps/source.go b/vendor/github.com/sdboyer/gps/source.go
index 2ee2ec5cf4..075c8cfd48 100644
--- a/vendor/github.com/sdboyer/gps/source.go
+++ b/vendor/github.com/sdboyer/gps/source.go
@@ -5,6 +5,8 @@ import (
"os"
"path/filepath"
"sync"
+
+ "github.com/sdboyer/gps/pkgtree"
)
// sourceExistence values represent the extent to which a project "exists."
@@ -48,7 +50,7 @@ type source interface {
checkExistence(sourceExistence) bool
exportVersionTo(Version, string) error
getManifestAndLock(ProjectRoot, Version) (Manifest, Lock, error)
- listPackages(ProjectRoot, Version) (PackageTree, error)
+ listPackages(ProjectRoot, Version) (pkgtree.PackageTree, error)
listVersions() ([]Version, error)
revisionPresentIn(Revision) (bool, error)
}
@@ -56,7 +58,7 @@ type source interface {
type sourceMetaCache struct {
//Version string // TODO(sdboyer) use this
infos map[Revision]projectInfo
- ptrees map[Revision]PackageTree
+ ptrees map[Revision]pkgtree.PackageTree
vMap map[UnpairedVersion]Revision
rMap map[Revision][]UnpairedVersion
// TODO(sdboyer) mutexes. actually probably just one, b/c complexity
@@ -79,7 +81,7 @@ type existence struct {
func newMetaCache() *sourceMetaCache {
return &sourceMetaCache{
infos: make(map[Revision]projectInfo),
- ptrees: make(map[Revision]PackageTree),
+ ptrees: make(map[Revision]pkgtree.PackageTree),
vMap: make(map[UnpairedVersion]Revision),
rMap: make(map[Revision][]UnpairedVersion),
}
@@ -353,7 +355,7 @@ func (bs *baseVCSSource) syncLocal() error {
return bs.syncerr
}
-func (bs *baseVCSSource) listPackages(pr ProjectRoot, v Version) (ptree PackageTree, err error) {
+func (bs *baseVCSSource) listPackages(pr ProjectRoot, v Version) (ptree pkgtree.PackageTree, err error) {
if err = bs.ensureCacheExistence(); err != nil {
return
}
@@ -390,7 +392,7 @@ func (bs *baseVCSSource) listPackages(pr ProjectRoot, v Version) (ptree PackageT
}
if err == nil {
- ptree, err = ListPackages(bs.crepo.r.LocalPath(), string(pr))
+ ptree, err = pkgtree.ListPackages(bs.crepo.r.LocalPath(), string(pr))
// TODO(sdboyer) cache errs?
if err == nil {
bs.dc.ptrees[r] = ptree
diff --git a/vendor/github.com/sdboyer/gps/source_manager.go b/vendor/github.com/sdboyer/gps/source_manager.go
index 2ed04deeb8..2c10d15861 100644
--- a/vendor/github.com/sdboyer/gps/source_manager.go
+++ b/vendor/github.com/sdboyer/gps/source_manager.go
@@ -11,7 +11,7 @@ import (
"sync/atomic"
"time"
- "github.com/Masterminds/semver"
+ "github.com/sdboyer/gps/pkgtree"
)
// Used to compute a friendly filepath from a URL-shaped input
@@ -45,7 +45,7 @@ type SourceManager interface {
// ListPackages parses the tree of the Go packages at or below root of the
// provided ProjectIdentifier, at the provided version.
- ListPackages(ProjectIdentifier, Version) (PackageTree, error)
+ ListPackages(ProjectIdentifier, Version) (pkgtree.PackageTree, error)
// GetManifestAndLock returns manifest and lock information for the provided
// root import path.
@@ -61,7 +61,7 @@ type SourceManager interface {
// AnalyzerInfo reports the name and version of the logic used to service
// GetManifestAndLock().
- AnalyzerInfo() (name string, version *semver.Version)
+ AnalyzerInfo() (name string, version int)
// DeduceRootProject takes an import path and deduces the corresponding
// project/source root.
@@ -77,7 +77,7 @@ type ProjectAnalyzer interface {
DeriveManifestAndLock(path string, importRoot ProjectRoot) (Manifest, Lock, error)
// Report the name and version of this ProjectAnalyzer.
- Info() (name string, version *semver.Version)
+ Info() (name string, version int)
}
// SourceMgr is the default SourceManager for gps.
@@ -312,7 +312,7 @@ func (sm *SourceMgr) doRelease() {
}
// AnalyzerInfo reports the name and version of the injected ProjectAnalyzer.
-func (sm *SourceMgr) AnalyzerInfo() (name string, version *semver.Version) {
+func (sm *SourceMgr) AnalyzerInfo() (name string, version int) {
return sm.an.Info()
}
@@ -344,9 +344,9 @@ func (sm *SourceMgr) GetManifestAndLock(id ProjectIdentifier, v Version) (Manife
// ListPackages parses the tree of the Go packages at and below the ProjectRoot
// of the given ProjectIdentifier, at the given version.
-func (sm *SourceMgr) ListPackages(id ProjectIdentifier, v Version) (PackageTree, error) {
+func (sm *SourceMgr) ListPackages(id ProjectIdentifier, v Version) (pkgtree.PackageTree, error) {
if atomic.CompareAndSwapInt32(&sm.releasing, 1, 1) {
- return PackageTree{}, smIsReleased{}
+ return pkgtree.PackageTree{}, smIsReleased{}
}
atomic.AddInt32(&sm.opcount, 1)
sm.glock.RLock()
@@ -357,7 +357,7 @@ func (sm *SourceMgr) ListPackages(id ProjectIdentifier, v Version) (PackageTree,
src, err := sm.getSourceFor(id)
if err != nil {
- return PackageTree{}, err
+ return pkgtree.PackageTree{}, err
}
return src.listPackages(id.ProjectRoot, v)
diff --git a/vendor/github.com/sdboyer/gps/source_test.go b/vendor/github.com/sdboyer/gps/source_test.go
index db4f1d6e22..d3c84bbf61 100644
--- a/vendor/github.com/sdboyer/gps/source_test.go
+++ b/vendor/github.com/sdboyer/gps/source_test.go
@@ -3,6 +3,7 @@ package gps
import (
"io/ioutil"
"net/url"
+ "os/exec"
"reflect"
"sync"
"testing"
@@ -13,6 +14,7 @@ func TestGitSourceInteractions(t *testing.T) {
if testing.Short() {
t.Skip("Skipping git source version fetching test in short mode")
}
+ requiresBins(t, "git")
cpath, err := ioutil.TempDir("", "smcache")
if err != nil {
@@ -113,6 +115,7 @@ func TestGopkginSourceInteractions(t *testing.T) {
if testing.Short() {
t.Skip("Skipping gopkg.in source version fetching test in short mode")
}
+ requiresBins(t, "git")
cpath, err := ioutil.TempDir("", "smcache")
if err != nil {
@@ -252,6 +255,7 @@ func TestBzrSourceInteractions(t *testing.T) {
if testing.Short() {
t.Skip("Skipping bzr source version fetching test in short mode")
}
+ requiresBins(t, "bzr")
cpath, err := ioutil.TempDir("", "smcache")
if err != nil {
@@ -361,6 +365,7 @@ func TestHgSourceInteractions(t *testing.T) {
if testing.Short() {
t.Skip("Skipping hg source version fetching test in short mode")
}
+ requiresBins(t, "hg")
cpath, err := ioutil.TempDir("", "smcache")
if err != nil {
@@ -481,3 +486,13 @@ func TestHgSourceInteractions(t *testing.T) {
<-donech
rf()
}
+
+// Fail a test if the specified binaries aren't installed.
+func requiresBins(t *testing.T, bins ...string) {
+ for _, b := range bins {
+ _, err := exec.LookPath(b)
+ if err != nil {
+ t.Fatalf("%s is not installed", b)
+ }
+ }
+}
diff --git a/vendor/github.com/sdboyer/gps/trace.go b/vendor/github.com/sdboyer/gps/trace.go
index 97858ac816..c12100d928 100644
--- a/vendor/github.com/sdboyer/gps/trace.go
+++ b/vendor/github.com/sdboyer/gps/trace.go
@@ -4,6 +4,8 @@ import (
"fmt"
"strconv"
"strings"
+
+ "github.com/sdboyer/gps/pkgtree"
)
const (
@@ -104,7 +106,7 @@ func (s *solver) traceFinish(sol solution, err error) {
}
// traceSelectRoot is called just once, when the root project is selected
-func (s *solver) traceSelectRoot(ptree PackageTree, cdeps []completeDep) {
+func (s *solver) traceSelectRoot(ptree pkgtree.PackageTree, cdeps []completeDep) {
if s.tl == nil {
return
}
diff --git a/vendor/github.com/sdboyer/gps/vcs_repo.go b/vendor/github.com/sdboyer/gps/vcs_repo.go
new file mode 100644
index 0000000000..d2e992a49e
--- /dev/null
+++ b/vendor/github.com/sdboyer/gps/vcs_repo.go
@@ -0,0 +1,314 @@
+package gps
+
+import (
+ "bytes"
+ "encoding/xml"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "time"
+
+ "github.com/Masterminds/vcs"
+)
+
+// original implementation of these methods come from
+// https://github.com/Masterminds/vcs
+
+type gitRepo struct {
+ *vcs.GitRepo
+}
+
+func (r *gitRepo) Get() error {
+ out, err := runFromCwd("git", "clone", "--recursive", r.Remote(), r.LocalPath())
+
+ // There are some windows cases where Git cannot create the parent directory,
+ // if it does not already exist, to the location it's trying to create the
+ // repo. Catch that error and try to handle it.
+ if err != nil && r.isUnableToCreateDir(err) {
+ basePath := filepath.Dir(filepath.FromSlash(r.LocalPath()))
+ if _, err := os.Stat(basePath); os.IsNotExist(err) {
+ err = os.MkdirAll(basePath, 0755)
+ if err != nil {
+ return vcs.NewLocalError("unable to create directory", err, "")
+ }
+
+ out, err = runFromCwd("git", "clone", r.Remote(), r.LocalPath())
+ if err != nil {
+ return vcs.NewRemoteError("unable to get repository", err, string(out))
+ }
+ return err
+ }
+ } else if err != nil {
+ return vcs.NewRemoteError("unable to get repository", err, string(out))
+ }
+
+ return nil
+}
+
+func (r *gitRepo) Update() error {
+ // Perform a fetch to make sure everything is up to date.
+ out, err := runFromRepoDir(r, "git", "fetch", "--tags", r.RemoteLocation)
+ if err != nil {
+ return vcs.NewRemoteError("unable to update repository", err, string(out))
+ }
+
+ // When in a detached head state, such as when an individual commit is checked
+ // out do not attempt a pull. It will cause an error.
+ detached, err := r.isDetachedHead()
+ if err != nil {
+ return vcs.NewLocalError("unable to update repository", err, "")
+ }
+
+ if detached {
+ return nil
+ }
+
+ out, err = runFromRepoDir(r, "git", "pull")
+ if err != nil {
+ return vcs.NewRemoteError("unable to update repository", err, string(out))
+ }
+
+ return r.defendAgainstSubmodules()
+}
+
+// defendAgainstSubmodules tries to keep repo state sane in the event of
+// submodules. Or nested submodules. What a great idea, submodules.
+func (r *gitRepo) defendAgainstSubmodules() error {
+ // First, update them to whatever they should be, if there should happen to be any.
+ out, err := runFromRepoDir(r, "git", "submodule", "update", "--init", "--recursive")
+ if err != nil {
+ return vcs.NewLocalError("unexpected error while defensively updating submodules", err, string(out))
+ }
+
+ // Now, do a special extra-aggressive clean in case changing versions caused
+ // one or more submodules to go away.
+ out, err = runFromRepoDir(r, "git", "clean", "-x", "-d", "-f", "-f")
+ if err != nil {
+ return vcs.NewLocalError("unexpected error while defensively cleaning up after possible derelict submodule directories", err, string(out))
+ }
+
+ // Then, repeat just in case there are any nested submodules that went away.
+ out, err = runFromRepoDir(r, "git", "submodule", "foreach", "--recursive", "git", "clean", "-x", "-d", "-f", "-f")
+ if err != nil {
+ return vcs.NewLocalError("unexpected error while defensively cleaning up after possible derelict nested submodule directories", err, string(out))
+ }
+
+ return nil
+}
+
+// isUnableToCreateDir checks for an error in the command to see if an error
+// where the parent directory of the VCS local path doesn't exist. This is
+// done in a multi-lingual manner.
+func (r *gitRepo) isUnableToCreateDir(err error) bool {
+ msg := err.Error()
+ if strings.HasPrefix(msg, "could not create work tree dir") ||
+ strings.HasPrefix(msg, "不能创建工作区目录") ||
+ strings.HasPrefix(msg, "no s'ha pogut crear el directori d'arbre de treball") ||
+ strings.HasPrefix(msg, "impossible de créer le répertoire de la copie de travail") ||
+ strings.HasPrefix(msg, "kunde inte skapa arbetskatalogen") ||
+ (strings.HasPrefix(msg, "Konnte Arbeitsverzeichnis") && strings.Contains(msg, "nicht erstellen")) ||
+ (strings.HasPrefix(msg, "작업 디렉터리를") && strings.Contains(msg, "만들 수 없습니다")) {
+ return true
+ }
+
+ return false
+}
+
+// isDetachedHead will detect if git repo is in "detached head" state.
+func (r *gitRepo) isDetachedHead() (bool, error) {
+ p := filepath.Join(r.LocalPath(), ".git", "HEAD")
+ contents, err := ioutil.ReadFile(p)
+ if err != nil {
+ return false, err
+ }
+
+ contents = bytes.TrimSpace(contents)
+ if bytes.HasPrefix(contents, []byte("ref: ")) {
+ return false, nil
+ }
+
+ return true, nil
+}
+
+type bzrRepo struct {
+ *vcs.BzrRepo
+}
+
+func (r *bzrRepo) Get() error {
+ basePath := filepath.Dir(filepath.FromSlash(r.LocalPath()))
+ if _, err := os.Stat(basePath); os.IsNotExist(err) {
+ err = os.MkdirAll(basePath, 0755)
+ if err != nil {
+ return vcs.NewLocalError("unable to create directory", err, "")
+ }
+ }
+
+ out, err := runFromCwd("bzr", "branch", r.Remote(), r.LocalPath())
+ if err != nil {
+ return vcs.NewRemoteError("unable to get repository", err, string(out))
+ }
+
+ return nil
+}
+
+func (r *bzrRepo) Update() error {
+ out, err := runFromRepoDir(r, "bzr", "pull")
+ if err != nil {
+ return vcs.NewRemoteError("unable to update repository", err, string(out))
+ }
+
+ out, err = runFromRepoDir(r, "bzr", "update")
+ if err != nil {
+ return vcs.NewRemoteError("unable to update repository", err, string(out))
+ }
+
+ return nil
+}
+
+type hgRepo struct {
+ *vcs.HgRepo
+}
+
+func (r *hgRepo) Get() error {
+ out, err := runFromCwd("hg", "clone", r.Remote(), r.LocalPath())
+ if err != nil {
+ return vcs.NewRemoteError("unable to get repository", err, string(out))
+ }
+
+ return nil
+}
+
+func (r *hgRepo) Update() error {
+ return r.UpdateVersion(``)
+}
+
+func (r *hgRepo) UpdateVersion(version string) error {
+ out, err := runFromRepoDir(r, "hg", "pull")
+ if err != nil {
+ return vcs.NewRemoteError("unable to update checked out version", err, string(out))
+ }
+
+ if len(strings.TrimSpace(version)) > 0 {
+ out, err = runFromRepoDir(r, "hg", "update", version)
+ } else {
+ out, err = runFromRepoDir(r, "hg", "update")
+ }
+
+ if err != nil {
+ return vcs.NewRemoteError("unable to update checked out version", err, string(out))
+ }
+
+ return nil
+}
+
+type svnRepo struct {
+ *vcs.SvnRepo
+}
+
+func (r *svnRepo) Get() error {
+ remote := r.Remote()
+ if strings.HasPrefix(remote, "/") {
+ remote = "file://" + remote
+ } else if runtime.GOOS == "windows" && filepath.VolumeName(remote) != "" {
+ remote = "file:///" + remote
+ }
+
+ out, err := runFromCwd("svn", "checkout", remote, r.LocalPath())
+ if err != nil {
+ return vcs.NewRemoteError("unable to get repository", err, string(out))
+ }
+
+ return nil
+}
+
+func (r *svnRepo) Update() error {
+ out, err := runFromRepoDir(r, "svn", "update")
+ if err != nil {
+ return vcs.NewRemoteError("unable to update repository", err, string(out))
+ }
+
+ return err
+}
+
+func (r *svnRepo) UpdateVersion(version string) error {
+ out, err := runFromRepoDir(r, "svn", "update", "-r", version)
+ if err != nil {
+ return vcs.NewRemoteError("unable to update checked out version", err, string(out))
+ }
+
+ return nil
+}
+
+func (r *svnRepo) CommitInfo(id string) (*vcs.CommitInfo, error) {
+ // There are cases where Svn log doesn't return anything for HEAD or BASE.
+ // svn info does provide details for these but does not have elements like
+ // the commit message.
+ if id == "HEAD" || id == "BASE" {
+ type commit struct {
+ Revision string `xml:"revision,attr"`
+ }
+
+ type info struct {
+ Commit commit `xml:"entry>commit"`
+ }
+
+ out, err := runFromRepoDir(r, "svn", "info", "-r", id, "--xml")
+ if err != nil {
+ return nil, vcs.NewLocalError("unable to retrieve commit information", err, string(out))
+ }
+
+ infos := new(info)
+ err = xml.Unmarshal(out, &infos)
+ if err != nil {
+ return nil, vcs.NewLocalError("unable to retrieve commit information", err, string(out))
+ }
+
+ id = infos.Commit.Revision
+ if id == "" {
+ return nil, vcs.ErrRevisionUnavailable
+ }
+ }
+
+ out, err := runFromRepoDir(r, "svn", "log", "-r", id, "--xml")
+ if err != nil {
+ return nil, vcs.NewRemoteError("unable to retrieve commit information", err, string(out))
+ }
+
+ type logentry struct {
+ Author string `xml:"author"`
+ Date string `xml:"date"`
+ Msg string `xml:"msg"`
+ }
+
+ type log struct {
+ XMLName xml.Name `xml:"log"`
+ Logs []logentry `xml:"logentry"`
+ }
+
+ logs := new(log)
+ err = xml.Unmarshal(out, &logs)
+ if err != nil {
+ return nil, vcs.NewLocalError("unable to retrieve commit information", err, string(out))
+ }
+
+ if len(logs.Logs) == 0 {
+ return nil, vcs.ErrRevisionUnavailable
+ }
+
+ ci := &vcs.CommitInfo{
+ Commit: id,
+ Author: logs.Logs[0].Author,
+ Message: logs.Logs[0].Msg,
+ }
+
+ if len(logs.Logs[0].Date) > 0 {
+ ci.Date, err = time.Parse(time.RFC3339Nano, logs.Logs[0].Date)
+ if err != nil {
+ return nil, vcs.NewLocalError("unable to retrieve commit information", err, string(out))
+ }
+ }
+
+ return ci, nil
+}
diff --git a/vendor/github.com/sdboyer/gps/vcs_repo_test.go b/vendor/github.com/sdboyer/gps/vcs_repo_test.go
new file mode 100644
index 0000000000..722edb3483
--- /dev/null
+++ b/vendor/github.com/sdboyer/gps/vcs_repo_test.go
@@ -0,0 +1,308 @@
+package gps
+
+import (
+ "io/ioutil"
+ "os"
+ "testing"
+ "time"
+
+ "github.com/Masterminds/vcs"
+)
+
+// original implementation of these test files come from
+// https://github.com/Masterminds/vcs test files
+
+func TestSvnRepo(t *testing.T) {
+ if testing.Short() {
+ t.Skip("Skipping slow test in short mode")
+ }
+
+ tempDir, err := ioutil.TempDir("", "go-vcs-svn-tests")
+ if err != nil {
+ t.Error(err)
+ }
+ defer func() {
+ err = os.RemoveAll(tempDir)
+ if err != nil {
+ t.Error(err)
+ }
+ }()
+
+ rep, err := vcs.NewSvnRepo("https://github.com/Masterminds/VCSTestRepo/trunk", tempDir+string(os.PathSeparator)+"VCSTestRepo")
+ if err != nil {
+ t.Error(err)
+ }
+ repo := &svnRepo{rep}
+
+ // Do an initial checkout.
+ err = repo.Get()
+ if err != nil {
+ t.Errorf("Unable to checkout SVN repo. Err was %s", err)
+ }
+
+ // Verify SVN repo is a SVN repo
+ if !repo.CheckLocal() {
+ t.Error("Problem checking out repo or SVN CheckLocal is not working")
+ }
+
+ // Update the version to a previous version.
+ err = repo.UpdateVersion("r2")
+ if err != nil {
+ t.Errorf("Unable to update SVN repo version. Err was %s", err)
+ }
+
+ // Use Version to verify we are on the right version.
+ v, err := repo.Version()
+ if v != "2" {
+ t.Error("Error checking checked SVN out version")
+ }
+ if err != nil {
+ t.Error(err)
+ }
+
+ // Perform an update which should take up back to the latest version.
+ err = repo.Update()
+ if err != nil {
+ t.Error(err)
+ }
+
+ // Make sure we are on a newer version because of the update.
+ v, err = repo.Version()
+ if v == "2" {
+ t.Error("Error with version. Still on old version. Update failed")
+ }
+ if err != nil {
+ t.Error(err)
+ }
+
+ ci, err := repo.CommitInfo("2")
+ if err != nil {
+ t.Error(err)
+ }
+ if ci.Commit != "2" {
+ t.Error("Svn.CommitInfo wrong commit id")
+ }
+ if ci.Author != "matt.farina" {
+ t.Error("Svn.CommitInfo wrong author")
+ }
+ if ci.Message != "Update README.md" {
+ t.Error("Svn.CommitInfo wrong message")
+ }
+ ti, err := time.Parse(time.RFC3339Nano, "2015-07-29T13:46:20.000000Z")
+ if err != nil {
+ t.Error(err)
+ }
+ if !ti.Equal(ci.Date) {
+ t.Error("Svn.CommitInfo wrong date")
+ }
+
+ _, err = repo.CommitInfo("555555555")
+ if err != vcs.ErrRevisionUnavailable {
+ t.Error("Svn didn't return expected ErrRevisionUnavailable")
+ }
+}
+
+func TestHgRepo(t *testing.T) {
+ if testing.Short() {
+ t.Skip("Skipping slow test in short mode")
+ }
+
+ tempDir, err := ioutil.TempDir("", "go-vcs-hg-tests")
+ if err != nil {
+ t.Error(err)
+ }
+
+ defer func() {
+ err = os.RemoveAll(tempDir)
+ if err != nil {
+ t.Error(err)
+ }
+ }()
+
+ rep, err := vcs.NewHgRepo("https://bitbucket.org/mattfarina/testhgrepo", tempDir+"/testhgrepo")
+ if err != nil {
+ t.Error(err)
+ }
+
+ repo := &hgRepo{rep}
+
+ // Do an initial clone.
+ err = repo.Get()
+ if err != nil {
+ t.Errorf("Unable to clone Hg repo. Err was %s", err)
+ }
+
+ // Verify Hg repo is a Hg repo
+ if !repo.CheckLocal() {
+ t.Error("Problem checking out repo or Hg CheckLocal is not working")
+ }
+
+ // Set the version using the short hash.
+ err = repo.UpdateVersion("a5494ba2177f")
+ if err != nil {
+ t.Errorf("Unable to update Hg repo version. Err was %s", err)
+ }
+
+ // Use Version to verify we are on the right version.
+ v, err := repo.Version()
+ if v != "a5494ba2177ff9ef26feb3c155dfecc350b1a8ef" {
+ t.Errorf("Error checking checked out Hg version: %s", v)
+ }
+ if err != nil {
+ t.Error(err)
+ }
+
+ // Perform an update.
+ err = repo.Update()
+ if err != nil {
+ t.Error(err)
+ }
+
+ v, err = repo.Version()
+ if v != "9c6ccbca73e8a1351c834f33f57f1f7a0329ad35" {
+ t.Errorf("Error checking checked out Hg version: %s", v)
+ }
+ if err != nil {
+ t.Error(err)
+ }
+}
+
+func TestGitRepo(t *testing.T) {
+ if testing.Short() {
+ t.Skip("Skipping slow test in short mode")
+ }
+
+ tempDir, err := ioutil.TempDir("", "go-vcs-git-tests")
+ if err != nil {
+ t.Error(err)
+ }
+
+ defer func() {
+ err = os.RemoveAll(tempDir)
+ if err != nil {
+ t.Error(err)
+ }
+ }()
+
+ rep, err := vcs.NewGitRepo("https://github.com/Masterminds/VCSTestRepo", tempDir+"/VCSTestRepo")
+ if err != nil {
+ t.Error(err)
+ }
+
+ repo := &gitRepo{rep}
+
+ // Do an initial clone.
+ err = repo.Get()
+ if err != nil {
+ t.Errorf("Unable to clone Git repo. Err was %s", err)
+ }
+
+ // Verify Git repo is a Git repo
+ if !repo.CheckLocal() {
+ t.Error("Problem checking out repo or Git CheckLocal is not working")
+ }
+
+ // Perform an update.
+ err = repo.Update()
+ if err != nil {
+ t.Error(err)
+ }
+
+ v, err := repo.Current()
+ if err != nil {
+ t.Errorf("Error trying Git Current: %s", err)
+ }
+ if v != "master" {
+ t.Errorf("Current failed to detect Git on tip of master. Got version: %s", v)
+ }
+
+ // Set the version using the short hash.
+ err = repo.UpdateVersion("806b07b")
+ if err != nil {
+ t.Errorf("Unable to update Git repo version. Err was %s", err)
+ }
+
+ // Once a ref has been checked out the repo is in a detached head state.
+ // Trying to pull in an update in this state will cause an error. Update
+ // should cleanly handle this. Pulling on a branch (tested elsewhere) and
+ // skipping that here.
+ err = repo.Update()
+ if err != nil {
+ t.Error(err)
+ }
+
+ // Use Version to verify we are on the right version.
+ v, err = repo.Version()
+ if v != "806b07b08faa21cfbdae93027904f80174679402" {
+ t.Error("Error checking checked out Git version")
+ }
+ if err != nil {
+ t.Error(err)
+ }
+}
+
+func TestBzrRepo(t *testing.T) {
+ if testing.Short() {
+ t.Skip("Skipping slow test in short mode")
+ }
+
+ tempDir, err := ioutil.TempDir("", "go-vcs-bzr-tests")
+ if err != nil {
+ t.Error(err)
+ }
+
+ defer func() {
+ err = os.RemoveAll(tempDir)
+ if err != nil {
+ t.Error(err)
+ }
+ }()
+
+ rep, err := vcs.NewBzrRepo("https://launchpad.net/govcstestbzrrepo", tempDir+"/govcstestbzrrepo")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ repo := &bzrRepo{rep}
+
+ // Do an initial clone.
+ err = repo.Get()
+ if err != nil {
+ t.Errorf("Unable to clone Bzr repo. Err was %s", err)
+ }
+
+ // Verify Bzr repo is a Bzr repo
+ if !repo.CheckLocal() {
+ t.Error("Problem checking out repo or Bzr CheckLocal is not working")
+ }
+
+ v, err := repo.Current()
+ if err != nil {
+ t.Errorf("Error trying Bzr Current: %s", err)
+ }
+ if v != "-1" {
+ t.Errorf("Current failed to detect Bzr on tip of branch. Got version: %s", v)
+ }
+
+ err = repo.UpdateVersion("2")
+ if err != nil {
+ t.Errorf("Unable to update Bzr repo version. Err was %s", err)
+ }
+
+ // Use Version to verify we are on the right version.
+ v, err = repo.Version()
+ if v != "2" {
+ t.Error("Error checking checked out Bzr version")
+ }
+ if err != nil {
+ t.Error(err)
+ }
+
+ v, err = repo.Current()
+ if err != nil {
+ t.Errorf("Error trying Bzr Current: %s", err)
+ }
+ if v != "2" {
+ t.Errorf("Current failed to detect Bzr on rev 2 of branch. Got version: %s", v)
+ }
+}
diff --git a/vendor/github.com/sdboyer/gps/vcs_source.go b/vendor/github.com/sdboyer/gps/vcs_source.go
index 3663a97c56..940dd82ec8 100644
--- a/vendor/github.com/sdboyer/gps/vcs_source.go
+++ b/vendor/github.com/sdboyer/gps/vcs_source.go
@@ -11,6 +11,7 @@ import (
"github.com/Masterminds/semver"
"github.com/Masterminds/vcs"
+ "github.com/sdboyer/gps/internal/fs"
)
// Kept here as a reference in case it does become important to implement a
@@ -50,20 +51,20 @@ func (s *gitSource) exportVersionTo(v Version, to string) error {
// Back up original index
idx, bak := filepath.Join(r.LocalPath(), ".git", "index"), filepath.Join(r.LocalPath(), ".git", "origindex")
- err := renameWithFallback(idx, bak)
+ err := fs.RenameWithFallback(idx, bak)
if err != nil {
return err
}
// could have an err here...but it's hard to imagine how?
- defer renameWithFallback(bak, idx)
+ defer fs.RenameWithFallback(bak, idx)
vstr := v.String()
if rv, ok := v.(PairedVersion); ok {
vstr = rv.Underlying().String()
}
- out, err := r.RunFromDir("git", "read-tree", vstr)
+ out, err := runFromRepoDir(r, "git", "read-tree", vstr)
if err != nil {
return fmt.Errorf("%s: %s", out, err)
}
@@ -79,7 +80,7 @@ func (s *gitSource) exportVersionTo(v Version, to string) error {
// though we have a bunch of housekeeping to do to set up, then tear
// down, the sparse checkout controls, as well as restore the original
// index and HEAD.
- out, err = r.RunFromDir("git", "checkout-index", "-a", "--prefix="+to)
+ out, err = runFromRepoDir(r, "git", "checkout-index", "-a", "--prefix="+to)
if err != nil {
return fmt.Errorf("%s: %s", out, err)
}
@@ -170,7 +171,7 @@ func (s *gitSource) doListVersions() (vlist []Version, err error) {
s.crepo.synced = true
s.crepo.mut.RLock()
- out, err = r.RunFromDir("git", "show-ref", "--dereference")
+ out, err = runFromRepoDir(r, "git", "show-ref", "--dereference")
s.crepo.mut.RUnlock()
if err != nil {
// TODO(sdboyer) More-er proper-er error
@@ -385,6 +386,22 @@ type bzrSource struct {
baseVCSSource
}
+func (s *bzrSource) update() error {
+ r := s.crepo.r
+
+ out, err := runFromRepoDir(r, "bzr", "pull")
+ if err != nil {
+ return vcs.NewRemoteError("Unable to update repository", err, string(out))
+ }
+
+ out, err = runFromRepoDir(r, "bzr", "update")
+ if err != nil {
+ return vcs.NewRemoteError("Unable to update repository", err, string(out))
+ }
+
+ return nil
+}
+
func (s *bzrSource) listVersions() (vlist []Version, err error) {
s.baseVCSSource.lvmut.Lock()
defer s.baseVCSSource.lvmut.Unlock()
@@ -411,7 +428,7 @@ func (s *bzrSource) listVersions() (vlist []Version, err error) {
// didn't create it
if !s.crepo.synced {
s.crepo.mut.Lock()
- err = r.Update()
+ err = s.update()
s.crepo.mut.Unlock()
if err != nil {
return
@@ -422,7 +439,7 @@ func (s *bzrSource) listVersions() (vlist []Version, err error) {
var out []byte
// Now, list all the tags
- out, err = r.RunFromDir("bzr", "tags", "--show-ids", "-v")
+ out, err = runFromRepoDir(r, "bzr", "tags", "--show-ids", "-v")
if err != nil {
return nil, fmt.Errorf("%s: %s", err, string(out))
}
@@ -430,7 +447,7 @@ func (s *bzrSource) listVersions() (vlist []Version, err error) {
all := bytes.Split(bytes.TrimSpace(out), []byte("\n"))
var branchrev []byte
- branchrev, err = r.RunFromDir("bzr", "version-info", "--custom", "--template={revision_id}", "--revision=branch:.")
+ branchrev, err = runFromRepoDir(r, "bzr", "version-info", "--custom", "--template={revision_id}", "--revision=branch:.")
br := string(branchrev)
if err != nil {
return nil, fmt.Errorf("%s: %s", err, br)
@@ -473,6 +490,22 @@ type hgSource struct {
baseVCSSource
}
+func (s *hgSource) update() error {
+ r := s.crepo.r
+
+ out, err := runFromRepoDir(r, "hg", "pull")
+ if err != nil {
+ return vcs.NewLocalError("Unable to update checked out version", err, string(out))
+ }
+
+ out, err = runFromRepoDir(r, "hg", "update")
+ if err != nil {
+ return vcs.NewLocalError("Unable to update checked out version", err, string(out))
+ }
+
+ return nil
+}
+
func (s *hgSource) listVersions() (vlist []Version, err error) {
s.baseVCSSource.lvmut.Lock()
defer s.baseVCSSource.lvmut.Unlock()
@@ -499,7 +532,7 @@ func (s *hgSource) listVersions() (vlist []Version, err error) {
// didn't create it
if !s.crepo.synced {
s.crepo.mut.Lock()
- err = unwrapVcsErr(r.Update())
+ err = unwrapVcsErr(s.update())
s.crepo.mut.Unlock()
if err != nil {
return
@@ -511,7 +544,7 @@ func (s *hgSource) listVersions() (vlist []Version, err error) {
var out []byte
// Now, list all the tags
- out, err = r.RunFromDir("hg", "tags", "--debug", "--verbose")
+ out, err = runFromRepoDir(r, "hg", "tags", "--debug", "--verbose")
if err != nil {
return nil, fmt.Errorf("%s: %s", err, string(out))
}
@@ -545,7 +578,7 @@ func (s *hgSource) listVersions() (vlist []Version, err error) {
// bookmarks next, because the presence of the magic @ bookmark has to
// determine how we handle the branches
var magicAt bool
- out, err = r.RunFromDir("hg", "bookmarks", "--debug")
+ out, err = runFromRepoDir(r, "hg", "bookmarks", "--debug")
if err != nil {
// better nothing than partial and misleading
return nil, fmt.Errorf("%s: %s", err, string(out))
@@ -578,7 +611,7 @@ func (s *hgSource) listVersions() (vlist []Version, err error) {
}
}
- out, err = r.RunFromDir("hg", "branches", "-c", "--debug")
+ out, err = runFromRepoDir(r, "hg", "branches", "-c", "--debug")
if err != nil {
// better nothing than partial and misleading
return nil, fmt.Errorf("%s: %s", err, string(out))
@@ -653,7 +686,7 @@ func (r *repo) exportVersionTo(v Version, to string) error {
// TODO(sdboyer) this is a simplistic approach and relying on the tools
// themselves might make it faster, but git's the overwhelming case (and has
// its own method) so fine for now
- return copyDir(r.rpath, to)
+ return fs.CopyDir(r.rpath, to)
}
// This func copied from Masterminds/vcs so we can exec our own commands