Merge remote-tracking branch 'origin' into pr-commands-isolate

This commit is contained in:
Mislav Marohnić 2020-08-04 15:01:30 +02:00
commit a73584db72
32 changed files with 387 additions and 293 deletions

View file

@ -20,20 +20,21 @@ func Command(url string) (*exec.Cmd, error) {
// ForOS produces an exec.Cmd to open the web browser for different OS
func ForOS(goos, url string) *exec.Cmd {
exe := "open"
var args []string
switch goos {
case "darwin":
args = []string{"open"}
args = append(args, url)
case "windows":
args = []string{"cmd", "/c", "start"}
exe = "cmd"
r := strings.NewReplacer("&", "^&")
url = r.Replace(url)
args = append(args, "/c", "start", r.Replace(url))
default:
args = []string{"xdg-open"}
exe = "xdg-open"
args = append(args, url)
}
args = append(args, url)
cmd := exec.Command(args[0], args[1:]...)
cmd := exec.Command(exe, args...)
cmd.Stderr = os.Stderr
return cmd
}

View file

@ -74,6 +74,9 @@ on the format of the value:
- if the value starts with "@", the rest of the value is interpreted as a
filename to read the value from. Pass "-" to read from standard input.
For GraphQL requests, all fields other than "query" and "operationName" are
interpreted as GraphQL variables.
Raw request body may be passed from the outside via a file specified by '--input'.
Pass "-" to read from standard input. In this mode, parameters specified via
'--field' flags are serialized into URL query parameters.

View file

@ -13,10 +13,10 @@ import (
func httpRequest(client *http.Client, method string, p string, params interface{}, headers []string) (*http.Response, error) {
var requestURL string
// TODO: GHE support
if strings.Contains(p, "://") {
requestURL = p
} else {
// TODO: GHE support
requestURL = "https://api.github.com/" + p
}
@ -87,7 +87,7 @@ func groupGraphQLVariables(params map[string]interface{}) map[string]interface{}
for key, val := range params {
switch key {
case "query":
case "query", "operationName":
topLevel[key] = val
default:
variables[key] = val

View file

@ -55,6 +55,21 @@ func Test_groupGraphQLVariables(t *testing.T) {
},
},
},
{
name: "query + operationName + variables",
args: map[string]interface{}{
"query": "query Q1{} query Q2{}",
"operationName": "Q1",
"power": 9001,
},
want: map[string]interface{}{
"query": "query Q1{} query Q2{}",
"operationName": "Q1",
"variables": map[string]interface{}{
"power": 9001,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View file

@ -11,6 +11,7 @@ import (
"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/api"
"github.com/cli/cli/internal/ghinstance"
"github.com/cli/cli/pkg/cmdutil"
"github.com/cli/cli/pkg/iostreams"
"github.com/cli/cli/utils"
@ -103,7 +104,8 @@ func createRun(opts *CreateOptions) error {
return err
}
gist, err := apiCreate(httpClient, opts.Description, opts.Public, files)
// TODO: GHE support
gist, err := apiCreate(httpClient, ghinstance.Default(), opts.Description, opts.Public, files)
if err != nil {
var httpError api.HTTPError
if errors.As(err, &httpError) {

View file

@ -22,7 +22,7 @@ type GistFile struct {
Content string `json:"content,omitempty"`
}
func apiCreate(httpClient *http.Client, description string, public bool, files map[string]string) (*Gist, error) {
func apiCreate(httpClient *http.Client, hostname string, description string, public bool, files map[string]string) (*Gist, error) {
gistFiles := map[GistFilename]GistFile{}
for filename, content := range files {
@ -44,7 +44,7 @@ func apiCreate(httpClient *http.Client, description string, public bool, files m
requestBody := bytes.NewReader(requestByte)
apiClient := api.NewClientFromHTTP(httpClient)
err = apiClient.REST("POST", path, requestBody, &result)
err = apiClient.REST(hostname, "POST", path, requestBody, &result)
if err != nil {
return nil, err
}

View file

@ -99,7 +99,7 @@ func reviewRun(opts *ReviewOptions) error {
return fmt.Errorf("did not understand desired review action: %w", err)
}
pr, _, err := shared.PRFromArgs(apiClient, opts.BaseRepo, opts.Branch, opts.Remotes, opts.SelectorArg)
pr, baseRepo, err := shared.PRFromArgs(apiClient, opts.BaseRepo, opts.Branch, opts.Remotes, opts.SelectorArg)
if err != nil {
return err
}
@ -119,7 +119,7 @@ func reviewRun(opts *ReviewOptions) error {
}
}
err = api.AddReview(apiClient, pr, reviewData)
err = api.AddReview(apiClient, baseRepo, pr, reviewData)
if err != nil {
return fmt.Errorf("failed to create review: %w", err)
}

View file

@ -8,6 +8,7 @@ import (
"github.com/cli/cli/api"
"github.com/cli/cli/git"
"github.com/cli/cli/internal/config"
"github.com/cli/cli/internal/ghinstance"
"github.com/cli/cli/internal/ghrepo"
"github.com/cli/cli/pkg/cmdutil"
"github.com/cli/cli/pkg/iostreams"
@ -79,7 +80,8 @@ func cloneRun(opts *CloneOptions) error {
cloneURL := opts.Repository
if !strings.Contains(cloneURL, ":") {
if !strings.Contains(cloneURL, "/") {
currentUser, err := api.CurrentLoginName(apiClient)
// TODO: GHE compat
currentUser, err := api.CurrentLoginName(apiClient, ghinstance.Default())
if err != nil {
return err
}

View file

@ -5,6 +5,7 @@ import (
"net/http"
"github.com/cli/cli/api"
"github.com/cli/cli/internal/ghinstance"
)
// repoCreateInput represents input parameters for repoCreate
@ -50,7 +51,10 @@ func repoCreate(client *http.Client, input repoCreateInput) (*api.Repository, er
"input": input,
}
err := apiClient.GraphQL(`
// TODO: GHE support
hostname := ghinstance.Default()
err := apiClient.GraphQL(hostname, `
mutation RepositoryCreate($input: CreateRepositoryInput!) {
createRepository(input: $input) {
repository {
@ -66,8 +70,7 @@ func repoCreate(client *http.Client, input repoCreateInput) (*api.Repository, er
return nil, err
}
// FIXME: support Enterprise hosts
return api.InitRepoHostname(&response.CreateRepository.Repository, "github.com"), nil
return api.InitRepoHostname(&response.CreateRepository.Repository, hostname), nil
}
// using API v3 here because the equivalent in GraphQL needs `read:org` scope
@ -75,7 +78,8 @@ func resolveOrganization(client *api.Client, orgName string) (string, error) {
var response struct {
NodeID string `json:"node_id"`
}
err := client.REST("GET", fmt.Sprintf("users/%s", orgName), nil, &response)
// TODO: GHE support
err := client.REST(ghinstance.Default(), "GET", fmt.Sprintf("users/%s", orgName), nil, &response)
return response.NodeID, err
}
@ -87,6 +91,7 @@ func resolveOrganizationTeam(client *api.Client, orgName, teamSlug string) (stri
NodeID string `json:"node_id"`
}
}
err := client.REST("GET", fmt.Sprintf("orgs/%s/teams/%s", orgName, teamSlug), nil, &response)
// TODO: GHE support
err := client.REST(ghinstance.Default(), "GET", fmt.Sprintf("orgs/%s/teams/%s", orgName, teamSlug), nil, &response)
return response.Organization.NodeID, response.NodeID, err
}

View file

@ -120,21 +120,17 @@ func creditsRun(opts *CreditsOptions) error {
client := api.NewClientFromHTTP(httpClient)
var owner string
var repo string
var baseRepo ghrepo.Interface
if opts.Repository == "" {
baseRepo, err := opts.BaseRepo()
baseRepo, err = opts.BaseRepo()
if err != nil {
return err
}
owner = baseRepo.RepoOwner()
repo = baseRepo.RepoName()
} else {
parts := strings.SplitN(opts.Repository, "/", 2)
owner = parts[0]
repo = parts[1]
baseRepo, err = ghrepo.FromFullName(opts.Repository)
if err != nil {
return err
}
}
type Contributor struct {
@ -145,9 +141,9 @@ func creditsRun(opts *CreditsOptions) error {
result := Result{}
body := bytes.NewBufferString("")
path := fmt.Sprintf("repos/%s/%s/contributors", owner, repo)
path := fmt.Sprintf("repos/%s/%s/contributors", baseRepo.RepoOwner(), baseRepo.RepoName())
err = client.REST("GET", path, body, &result)
err = client.REST(baseRepo.RepoHost(), "GET", path, body, &result)
if err != nil {
return err
}

View file

@ -24,7 +24,7 @@ func RepositoryReadme(client *http.Client, repo ghrepo.Interface) (*RepoReadme,
Content string
}
err := apiClient.REST("GET", fmt.Sprintf("repos/%s/readme", ghrepo.FullName(repo)), nil, &response)
err := apiClient.REST(repo.RepoHost(), "GET", fmt.Sprintf("repos/%s/readme", ghrepo.FullName(repo)), nil, &response)
if err != nil {
var httpError api.HTTPError
if errors.As(err, &httpError) && httpError.StatusCode == 404 {