diff --git a/glide.lock b/glide.lock index 572094ab..c7a384e5 100644 --- a/glide.lock +++ b/glide.lock @@ -1,12 +1,12 @@ -hash: ebc39e5b2036ba2235316f2897fb9f2e696c6a7d5389416812722cc8ed3dfa21 -updated: 2016-06-10T16:27:29.24243625-04:00 +hash: 89ab42baaeb2d708ad98cbd606ebeecfcb7874d64b30bc130c6e337f2ea3a4ea +updated: 2016-06-30T09:50:18.895962151-04:00 imports: - name: github.com/codegangsta/cli version: 71f57d300dd6a780ac1856c005c4b518cfd498ec - name: github.com/Masterminds/semver version: 808ed7761c233af2de3f9729a041d68c62527f3a - name: github.com/Masterminds/vcs - version: 7af28b64c5ec41b1558f5514fd938379822c237c + version: fbe9fb6ad5b5f35b3e82a7c21123cfc526cbf895 - name: gopkg.in/yaml.v2 version: a83829b6f1293c91addabc89d0571c246397bbf4 testImports: [] diff --git a/glide.yaml b/glide.yaml index a8c5b4a6..1a1f7895 100644 --- a/glide.yaml +++ b/glide.yaml @@ -11,7 +11,7 @@ owners: import: - package: gopkg.in/yaml.v2 - package: github.com/Masterminds/vcs - version: ^1.7.0 + version: ^1.8.0 - package: github.com/codegangsta/cli version: ~1.14.0 - package: github.com/Masterminds/semver diff --git a/vendor/github.com/Masterminds/vcs/.travis.yml b/vendor/github.com/Masterminds/vcs/.travis.yml index a8c32da3..5c50c4a1 100644 --- a/vendor/github.com/Masterminds/vcs/.travis.yml +++ b/vendor/github.com/Masterminds/vcs/.travis.yml @@ -18,4 +18,9 @@ before_script: sudo: false notifications: - irc: "irc.freenode.net#masterminds" + webhooks: + urls: + - https://webhooks.gitter.im/e/06e3328629952dabe3e0 + on_success: change # options: [always|never|change] default: always + on_failure: always # options: [always|never|change] default: always + on_start: never # options: [always|never|change] default: always diff --git a/vendor/github.com/Masterminds/vcs/CHANGELOG.md b/vendor/github.com/Masterminds/vcs/CHANGELOG.md index d178685d..63626742 100644 --- a/vendor/github.com/Masterminds/vcs/CHANGELOG.md +++ b/vendor/github.com/Masterminds/vcs/CHANGELOG.md @@ -1,4 +1,18 @@ -1.7.0 (2016-05-05) +# 1.8.0 (2016-06-29) + +## Added +- #43: Detect when tool (e.g., git, svn, etc) not installed +- #49: Detect access denied and not found situations + +## Changed +- #48: Updated Go Report Gard url to new format +- Refactored SVN handling to detect when not in a top level directory +- Updating tagging to v[SemVer] structure for compatibility with other tools. + +## Fixed +- #45: Fixed hg's update method so that it pulls from remote before updates + +# 1.7.0 (2016-05-05) - Adds a glide.yaml file with some limited information. - Implements #37: Ability to export source as a directory. diff --git a/vendor/github.com/Masterminds/vcs/README.md b/vendor/github.com/Masterminds/vcs/README.md index 6025f2d8..cdb981fd 100644 --- a/vendor/github.com/Masterminds/vcs/README.md +++ b/vendor/github.com/Masterminds/vcs/README.md @@ -3,7 +3,7 @@ Manage repos in varying version control systems with ease through a common interface. -[![Build Status](https://travis-ci.org/Masterminds/vcs.svg)](https://travis-ci.org/Masterminds/vcs) [![GoDoc](https://godoc.org/github.com/Masterminds/vcs?status.png)](https://godoc.org/github.com/Masterminds/vcs) [![Go Report Card](http://goreportcard.com/badge/Masterminds/vcs)](http://goreportcard.com/report/Masterminds/vcs) +[![Build Status](https://travis-ci.org/Masterminds/vcs.svg)](https://travis-ci.org/Masterminds/vcs) [![GoDoc](https://godoc.org/github.com/Masterminds/vcs?status.png)](https://godoc.org/github.com/Masterminds/vcs) [![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/vcs)](https://goreportcard.com/report/github.com/Masterminds/vcs) ## Quick Usage diff --git a/vendor/github.com/Masterminds/vcs/bzr.go b/vendor/github.com/Masterminds/vcs/bzr.go index a62451fc..e8f55b67 100644 --- a/vendor/github.com/Masterminds/vcs/bzr.go +++ b/vendor/github.com/Masterminds/vcs/bzr.go @@ -16,6 +16,10 @@ var bzrDetectURL = regexp.MustCompile("parent branch: (?P.+)\n") // NewBzrRepo creates a new instance of BzrRepo. The remote and local directories // need to be passed in. func NewBzrRepo(remote, local string) (*BzrRepo, error) { + ins := depInstalled("bzr") + if !ins { + return nil, NewLocalError("bzr is not installed", nil, "") + } ltype, err := DetectVcsFromFS(local) // Found a VCS other than Bzr. Need to report an error. diff --git a/vendor/github.com/Masterminds/vcs/git.go b/vendor/github.com/Masterminds/vcs/git.go index 778b6af3..eb4b86e9 100644 --- a/vendor/github.com/Masterminds/vcs/git.go +++ b/vendor/github.com/Masterminds/vcs/git.go @@ -14,6 +14,10 @@ import ( // NewGitRepo creates a new instance of GitRepo. The remote and local directories // need to be passed in. func NewGitRepo(remote, local string) (*GitRepo, error) { + ins := depInstalled("git") + if !ins { + return nil, NewLocalError("git is not installed", nil, "") + } ltype, err := DetectVcsFromFS(local) // Found a VCS other than Git. Need to report an error. diff --git a/vendor/github.com/Masterminds/vcs/hg.go b/vendor/github.com/Masterminds/vcs/hg.go index 0d7a9945..df41cd62 100644 --- a/vendor/github.com/Masterminds/vcs/hg.go +++ b/vendor/github.com/Masterminds/vcs/hg.go @@ -14,6 +14,10 @@ var hgDetectURL = regexp.MustCompile("default = (?P.+)\n") // NewHgRepo creates a new instance of HgRepo. The remote and local directories // need to be passed in. func NewHgRepo(remote, local string) (*HgRepo, error) { + ins := depInstalled("hg") + if !ins { + return nil, NewLocalError("hg is not installed", nil, "") + } ltype, err := DetectVcsFromFS(local) // Found a VCS other than Hg. Need to report an error. @@ -84,11 +88,7 @@ func (s *HgRepo) Init() error { // Update performs a Mercurial pull to an existing checkout. func (s *HgRepo) Update() error { - out, err := s.RunFromDir("hg", "update") - if err != nil { - return NewRemoteError("Unable to update repository", err, string(out)) - } - return nil + return s.UpdateVersion(``) } // UpdateVersion sets the version of a package currently checked out via Hg. @@ -97,7 +97,11 @@ func (s *HgRepo) UpdateVersion(version string) error { if err != nil { return NewLocalError("Unable to update checked out version", err, string(out)) } - out, err = s.RunFromDir("hg", "update", version) + if len(strings.TrimSpace(version)) > 0 { + out, err = s.RunFromDir("hg", "update", version) + } else { + out, err = s.RunFromDir("hg", "update") + } if err != nil { return NewLocalError("Unable to update checked out version", err, string(out)) } diff --git a/vendor/github.com/Masterminds/vcs/repo.go b/vendor/github.com/Masterminds/vcs/repo.go index 99bc2d24..1298a5f9 100644 --- a/vendor/github.com/Masterminds/vcs/repo.go +++ b/vendor/github.com/Masterminds/vcs/repo.go @@ -257,3 +257,11 @@ NextVar: } return out } + +func depInstalled(name string) bool { + if _, err := exec.LookPath(name); err != nil { + return false + } + + return true +} diff --git a/vendor/github.com/Masterminds/vcs/repo_test.go b/vendor/github.com/Masterminds/vcs/repo_test.go index 12f63f5d..d61f6cbe 100644 --- a/vendor/github.com/Masterminds/vcs/repo_test.go +++ b/vendor/github.com/Masterminds/vcs/repo_test.go @@ -60,3 +60,15 @@ func TestTypeSwitch(t *testing.T) { t.Errorf("Not detecting repo switch from SVN to Git") } } + +func TestDepInstalled(t *testing.T) { + i := depInstalled("git") + if i != true { + t.Error("depInstalled not finding installed dep.") + } + + i = depInstalled("thisreallyisntinstalled") + if i != false { + 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 48d089b4..888ae095 100644 --- a/vendor/github.com/Masterminds/vcs/svn.go +++ b/vendor/github.com/Masterminds/vcs/svn.go @@ -2,21 +2,23 @@ package vcs import ( "encoding/xml" + "fmt" "os" "os/exec" "path/filepath" - "regexp" "strings" "time" ) -var svnDetectURL = regexp.MustCompile("URL: (?P.+)\n") - // NewSvnRepo creates a new instance of SvnRepo. The remote and local directories // need to be passed in. The remote location should include the branch for SVN. // For example, if the package is https://github.com/Masterminds/cookoo/ the remote // should be https://github.com/Masterminds/cookoo/trunk for the trunk branch. func NewSvnRepo(remote, local string) (*SvnRepo, error) { + ins := depInstalled("svn") + if !ins { + return nil, NewLocalError("svn is not installed", nil, "") + } ltype, err := DetectVcsFromFS(local) // Found a VCS other than Svn. Need to report an error. @@ -39,15 +41,18 @@ func NewSvnRepo(remote, local string) (*SvnRepo, error) { return nil, NewLocalError("Unable to retrieve local repo information", err, string(out)) } - m := svnDetectURL.FindStringSubmatch(string(out)) - if m[1] != "" && m[1] != remote { + detectedRemote, err := detectRemoteFromInfoCommand(string(out)) + if err != nil { + return nil, NewLocalError("Unable to retrieve local repo information", err, string(out)) + } + if detectedRemote != "" && remote != "" && detectedRemote != remote { return nil, ErrWrongRemote } // If no remote was passed in but one is configured for the locally // checked out Svn repo use that one. - if remote == "" && m[1] != "" { - r.setRemote(m[1]) + if remote == "" && detectedRemote != "" { + r.setRemote(detectedRemote) } } @@ -185,12 +190,15 @@ func (s *SvnRepo) Date() (time.Time, error) { // CheckLocal verifies the local location is an SVN repo. func (s *SvnRepo) CheckLocal() bool { - if _, err := os.Stat(s.LocalPath() + "/.svn"); err == nil { - return true + 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 { + return true + } } - return false - } // Tags returns []string{} as there are no formal tags in SVN. Tags are a @@ -344,3 +352,24 @@ func (s *SvnRepo) isUnableToCreateDir(err error) bool { return false } + +// detectRemoteFromInfoCommand finds the remote url from the `svn info` +// command's output without using a regex. We avoid regex because URLs +// are notoriously complex to accurately match with a regex and +// splitting strings is less complex and often faster +func detectRemoteFromInfoCommand(infoOut string) (string, error) { + sBytes := []byte(infoOut) + urlIndex := strings.Index(infoOut, "URL: ") + if urlIndex == -1 { + return "", fmt.Errorf("Remote not specified in svn info") + } + urlEndIndex := strings.Index(string(sBytes[urlIndex:]), "\n") + if urlEndIndex == -1 { + urlEndIndex = strings.Index(string(sBytes[urlIndex:]), "\r") + if urlEndIndex == -1 { + return "", fmt.Errorf("Unable to parse remote URL for svn info") + } + } + + return string(sBytes[(urlIndex + 5):(urlIndex + urlEndIndex)]), nil +} diff --git a/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go b/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go index 85fac7fa..0567af8b 100644 --- a/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go +++ b/vendor/github.com/Masterminds/vcs/vcs_remote_lookup.go @@ -88,6 +88,8 @@ func detectVcsFromRemote(vcsURL string) (Type, string, error) { t, e := detectVcsFromURL(vcsURL) if e == nil { return t, vcsURL, nil + } else if e != ErrCannotDetectVCS { + return NoVCS, "", e } // Pages like https://golang.org/x/net provide an html document with @@ -114,6 +116,11 @@ func detectVcsFromRemote(vcsURL string) (Type, string, error) { } defer resp.Body.Close() if resp.StatusCode < 200 || resp.StatusCode >= 300 { + if resp.StatusCode == 404 { + return NoVCS, "", NewRemoteError(fmt.Sprintf("%s Not Found", vcsURL), nil, "") + } else if resp.StatusCode == 401 || resp.StatusCode == 403 { + return NoVCS, "", NewRemoteError(fmt.Sprintf("%s Access Denied", vcsURL), nil, "") + } return NoVCS, "", ErrCannotDetectVCS } @@ -202,6 +209,10 @@ func detectVcsFromURL(vcsURL string) (Type, error) { } t, err := v.addCheck(info, u) if err != nil { + switch err.(type) { + case *RemoteError: + return "", err + } return "", ErrCannotDetectVCS } @@ -299,7 +310,11 @@ func get(url string) ([]byte, error) { } defer resp.Body.Close() if resp.StatusCode != 200 { - // TODO(mattfarina): log the failed status + if resp.StatusCode == 404 { + return nil, NewRemoteError("Not Found", err, resp.Status) + } else if resp.StatusCode == 401 || resp.StatusCode == 403 { + return nil, NewRemoteError("Access Denied", err, resp.Status) + } return nil, fmt.Errorf("%s: %s", url, resp.Status) } b, err := ioutil.ReadAll(resp.Body) 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 fd7663e1..e97bba82 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,7 @@ package vcs import ( + "strings" "testing" ) @@ -58,7 +59,11 @@ func TestVCSLookup(t *testing.T) { t.Errorf("Error detecting VCS from URL(%s): %s", u, err) } - if err != nil && err != ErrCannotDetectVCS && c.work == false { + if err != nil && + err != ErrCannotDetectVCS && + !strings.HasSuffix(err.Error(), "Not Found") && + !strings.HasSuffix(err.Error(), "Access Denied") && + c.work == false { t.Errorf("Unexpected error returned (%s): %s", u, err) } @@ -67,3 +72,27 @@ func TestVCSLookup(t *testing.T) { } } } + +func TestNotFound(t *testing.T) { + _, _, err := detectVcsFromRemote("https://mattfarina.com/notfound") + if err == nil || !strings.HasSuffix(err.Error(), " Not Found") { + t.Errorf("Failed to find not found repo") + } + + _, err = NewRepo("https://mattfarina.com/notfound", "") + if err == nil || !strings.HasSuffix(err.Error(), " Not Found") { + t.Errorf("Failed to find not found repo") + } +} + +func TestAccessDenied(t *testing.T) { + _, _, err := detectVcsFromRemote("https://bitbucket.org/mattfarina/private-repo-for-vcs-testing") + if err == nil || err.Error() != "Access Denied" { + t.Errorf("Failed to detect access denied") + } + + _, err = NewRepo("https://bitbucket.org/mattfarina/private-repo-for-vcs-testing", "") + if err == nil || err.Error() != "Access Denied" { + t.Errorf("Failed to detect access denied") + } +}