Merge pull request #495 from Masterminds/vcs-1.8.0
Updating to Masterminds/vcs 1.8.0
diff --git a/glide.lock b/glide.lock
index 572094a..c7a384e 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 a8c5b4a..1a1f789 100644
--- a/glide.yaml
+++ b/glide.yaml
@@ -11,7 +11,7 @@
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 a8c32da..5c50c4a 100644
--- a/vendor/github.com/Masterminds/vcs/.travis.yml
+++ b/vendor/github.com/Masterminds/vcs/.travis.yml
@@ -18,4 +18,9 @@
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 d178685..6362674 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 6025f2d..cdb981f 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.
-[](https://travis-ci.org/Masterminds/vcs) [](https://godoc.org/github.com/Masterminds/vcs) [](http://goreportcard.com/report/Masterminds/vcs)
+[](https://travis-ci.org/Masterminds/vcs) [](https://godoc.org/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 a62451f..e8f55b6 100644
--- a/vendor/github.com/Masterminds/vcs/bzr.go
+++ b/vendor/github.com/Masterminds/vcs/bzr.go
@@ -16,6 +16,10 @@
// 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 778b6af..eb4b86e 100644
--- a/vendor/github.com/Masterminds/vcs/git.go
+++ b/vendor/github.com/Masterminds/vcs/git.go
@@ -14,6 +14,10 @@
// 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 0d7a994..df41cd6 100644
--- a/vendor/github.com/Masterminds/vcs/hg.go
+++ b/vendor/github.com/Masterminds/vcs/hg.go
@@ -14,6 +14,10 @@
// 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 @@
// 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 @@
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 99bc2d2..1298a5f 100644
--- a/vendor/github.com/Masterminds/vcs/repo.go
+++ b/vendor/github.com/Masterminds/vcs/repo.go
@@ -257,3 +257,11 @@
}
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 12f63f5..d61f6cb 100644
--- a/vendor/github.com/Masterminds/vcs/repo_test.go
+++ b/vendor/github.com/Masterminds/vcs/repo_test.go
@@ -60,3 +60,15 @@
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 48d089b..888ae09 100644
--- a/vendor/github.com/Masterminds/vcs/svn.go
+++ b/vendor/github.com/Masterminds/vcs/svn.go
@@ -2,21 +2,23 @@
import (
"encoding/xml"
+ "fmt"
"os"
"os/exec"
"path/filepath"
- "regexp"
"strings"
"time"
)
-var svnDetectURL = regexp.MustCompile("URL: (?P<foo>.+)\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 @@
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 @@
// 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 @@
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 85fac7f..0567af8 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 @@
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 @@
}
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 @@
}
t, err := v.addCheck(info, u)
if err != nil {
+ switch err.(type) {
+ case *RemoteError:
+ return "", err
+ }
return "", ErrCannotDetectVCS
}
@@ -299,7 +310,11 @@
}
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 fd7663e..e97bba8 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 @@
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 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")
+ }
+}