Commit a2d12201 authored by Billie H. Cleek's avatar Billie H. Cleek Committed by Brad Fitzpatrick

cmd/go: detect which VCS to use with Bitbucket when the API call fails.

      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/1910Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 878a86a1
...@@ -17,6 +17,14 @@ import ( ...@@ -17,6 +17,14 @@ import (
var errHTTP = errors.New("no http in bootstrap go command") 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) { func httpGET(url string) ([]byte, error) {
return nil, errHTTP return nil, errHTTP
} }
......
...@@ -24,6 +24,16 @@ import ( ...@@ -24,6 +24,16 @@ import (
// changed by tests, without modifying http.DefaultClient. // changed by tests, without modifying http.DefaultClient.
var httpClient = 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. // httpGET returns the data from an HTTP GET request for the given URL.
func httpGET(url string) ([]byte, error) { func httpGET(url string) ([]byte, error) {
resp, err := httpClient.Get(url) resp, err := httpClient.Get(url)
...@@ -32,7 +42,9 @@ func httpGET(url string) ([]byte, error) { ...@@ -32,7 +42,9 @@ func httpGET(url string) ([]byte, error) {
} }
defer resp.Body.Close() defer resp.Body.Close()
if resp.StatusCode != 200 { 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) b, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
......
...@@ -808,10 +808,25 @@ func bitbucketVCS(match map[string]string) error { ...@@ -808,10 +808,25 @@ func bitbucketVCS(match map[string]string) error {
url := expand(match, "https://api.bitbucket.org/1.0/repositories/{bitname}") url := expand(match, "https://api.bitbucket.org/1.0/repositories/{bitname}")
data, err := httpGET(url) data, err := httpGET(url)
if err != nil { if err != nil {
return err if httpErr, ok := err.(*httpError); ok && httpErr.statusCode == 403 {
} // this may be a private repository. If so, attempt to determine which
if err := json.Unmarshal(data, &resp); err != nil { // VCS it uses. See issue 5375.
return fmt.Errorf("decoding %s: %v", url, err) 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 { if vcsByCmd(resp.SCM) != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment