]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: detect which VCS to use with Bitbucket when the API call fails.
authorBillie H. Cleek <bhcleek@gmail.com>
Sun, 21 Dec 2014 01:05:05 +0000 (17:05 -0800)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 9 Apr 2015 09:57:12 +0000 (09:57 +0000)
      The API call will fail when Bitbucket repositories are private. In
that case, probe for the repository using vcsCmd.ping.

      Fixes #5375

Change-Id: Ia604ecf9014805579dfda4b5c8e627a52783d56e
Reviewed-on: https://go-review.googlesource.com/1910
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/go/bootstrap.go
src/cmd/go/http.go
src/cmd/go/vcs.go

index dc7ed5f4c0689af7c2f666db03503012615e2f3b..0c13380054847586e2fa943dbb467ff94bcd956a 100644 (file)
@@ -17,6 +17,14 @@ import (
 
 var errHTTP = errors.New("no http in bootstrap go command")
 
+type httpError struct {
+       statusCode int
+}
+
+func (e *httpError) Error() string {
+       panic("unreachable")
+}
+
 func httpGET(url string) ([]byte, error) {
        return nil, errHTTP
 }
index 107b820f28c52c6da056998c18a6fc6cc207be35..8b1247bfbe8eb61a62e4fa96f9ac9d49c327c616 100644 (file)
@@ -24,6 +24,16 @@ import (
 // changed by tests, without modifying http.DefaultClient.
 var httpClient = http.DefaultClient
 
+type httpError struct {
+       status     string
+       statusCode int
+       url        string
+}
+
+func (e *httpError) Error() string {
+       return fmt.Sprintf("%s: %s", e.url, e.status)
+}
+
 // httpGET returns the data from an HTTP GET request for the given URL.
 func httpGET(url string) ([]byte, error) {
        resp, err := httpClient.Get(url)
@@ -32,7 +42,9 @@ func httpGET(url string) ([]byte, error) {
        }
        defer resp.Body.Close()
        if resp.StatusCode != 200 {
-               return nil, fmt.Errorf("%s: %s", url, resp.Status)
+               err := &httpError{status: resp.Status, statusCode: resp.StatusCode, url: url}
+
+               return nil, err
        }
        b, err := ioutil.ReadAll(resp.Body)
        if err != nil {
index 86f5ea82e82ff0d9f70a154e10041aae8bc1bd62..43027134e1efee3eeab5bb7c61a348fc7d1ca45d 100644 (file)
@@ -808,10 +808,25 @@ func bitbucketVCS(match map[string]string) error {
        url := expand(match, "https://api.bitbucket.org/1.0/repositories/{bitname}")
        data, err := httpGET(url)
        if err != nil {
-               return err
-       }
-       if err := json.Unmarshal(data, &resp); err != nil {
-               return fmt.Errorf("decoding %s: %v", url, err)
+               if httpErr, ok := err.(*httpError); ok && httpErr.statusCode == 403 {
+                       // this may be a private repository. If so, attempt to determine which
+                       // VCS it uses. See issue 5375.
+                       root := match["root"]
+                       for _, vcs := range []string{"git", "hg"} {
+                               if vcsByCmd(vcs).ping("https", root) == nil {
+                                       resp.SCM = vcs
+                                       break
+                               }
+                       }
+               }
+
+               if resp.SCM == "" {
+                       return err
+               }
+       } else {
+               if err := json.Unmarshal(data, &resp); err != nil {
+                       return fmt.Errorf("decoding %s: %v", url, err)
+               }
        }
 
        if vcsByCmd(resp.SCM) != nil {