diff --git a/README.md b/README.md index 6b492024b..f257d0eb6 100644 --- a/README.md +++ b/README.md @@ -41,9 +41,19 @@ tool. Check out our [more detailed explanation](/docs/gh-vs-hub.md) to learn mor ### macOS +`gh` is available via Homebrew and MacPorts. + +#### Homebrew + Install: `brew install github/gh/gh` -Upgrade: `brew update && brew upgrade gh` +Upgrade: `brew upgrade gh` + +#### MacPorts + +Install: `sudo port install gh` + +Upgrade: `sudo port selfupdate && sudo port upgrade gh` ### Windows diff --git a/api/queries_pr.go b/api/queries_pr.go index 2a38bf909..8de56be48 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -104,12 +104,6 @@ type PullRequest struct { Milestone struct { Title string } - Participants struct { - Nodes []struct { - Login string - } - TotalCount int - } } type NotFoundError struct { @@ -418,12 +412,6 @@ func PullRequestByNumber(client *Client, repo ghrepo.Interface, number int) (*Pu milestone{ title } - participants(first: 100) { - nodes { - login - } - totalCount - } } } }` @@ -521,12 +509,6 @@ func PullRequestForBranch(client *Client, repo ghrepo.Interface, baseBranch, hea milestone{ title } - participants(first: 100) { - nodes { - login - } - totalCount - } } } } diff --git a/cmd/gh/main.go b/cmd/gh/main.go index a9e0837f3..17f2042f2 100644 --- a/cmd/gh/main.go +++ b/cmd/gh/main.go @@ -70,7 +70,11 @@ func printError(out io.Writer, err error, cmd *cobra.Command, debug bool) { } func shouldCheckForUpdate() bool { - return updaterEnabled != "" && utils.IsTerminal(os.Stderr) + return updaterEnabled != "" && !isCompletionCommand() && utils.IsTerminal(os.Stderr) +} + +func isCompletionCommand() bool { + return len(os.Args) > 1 && os.Args[1] == "completion" } func checkForUpdate(currentVersion string) (*update.ReleaseInfo, error) { diff --git a/command/completion.go b/command/completion.go index 94c9ccf5d..319d103a2 100644 --- a/command/completion.go +++ b/command/completion.go @@ -1,15 +1,18 @@ package command import ( + "errors" "fmt" + "os" "github.com/cli/cli/internal/cobrafish" + "github.com/cli/cli/utils" "github.com/spf13/cobra" ) func init() { RootCmd.AddCommand(completionCmd) - completionCmd.Flags().StringP("shell", "s", "bash", "Shell type: {bash|zsh|fish|powershell}") + completionCmd.Flags().StringP("shell", "s", "", "Shell type: {bash|zsh|fish|powershell}") } var completionCmd = &cobra.Command{ @@ -17,9 +20,12 @@ var completionCmd = &cobra.Command{ Short: "Generate shell completion scripts", Long: `Generate shell completion scripts for GitHub CLI commands. +The output of this command will be computer code and is meant to be saved to a +file or immediately evaluated by an interactive shell. + For example, for bash you could add this to your '~/.bash_profile': - eval "$(gh completion)" + eval "$(gh completion -s bash)" When installing GitHub CLI through a package manager, however, it's possible that no additional shell configuration is necessary to gain completion support. For @@ -31,6 +37,19 @@ Homebrew, see return err } + if shellType == "" { + out := cmd.OutOrStdout() + isTTY := false + if outFile, isFile := out.(*os.File); isFile { + isTTY = utils.IsTerminal(outFile) + } + + if isTTY { + return errors.New("error: the value for `--shell` is required\nsee `gh help completion` for more information") + } + shellType = "bash" + } + switch shellType { case "bash": return RootCmd.GenBashCompletion(cmd.OutOrStdout()) diff --git a/command/issue.go b/command/issue.go index 9e57556e1..fd2e03eef 100644 --- a/command/issue.go +++ b/command/issue.go @@ -38,7 +38,7 @@ func init() { issueListCmd.Flags().StringP("author", "A", "", "Filter by author") issueCmd.AddCommand(issueViewCmd) - issueViewCmd.Flags().BoolP("web", "w", false, "Open issue in browser") + issueViewCmd.Flags().BoolP("web", "w", false, "Open an issue in the browser") } var issueCmd = &cobra.Command{ @@ -74,7 +74,10 @@ var issueViewCmd = &cobra.Command{ return nil }, Short: "View an issue", - RunE: issueView, + Long: `Display the title, body, and other information about an issue. + +With '--web', open the issue in a web browser instead.`, + RunE: issueView, } func issueList(cmd *cobra.Command, args []string) error { diff --git a/command/pr.go b/command/pr.go index c008b1292..a8a197c46 100644 --- a/command/pr.go +++ b/command/pr.go @@ -32,7 +32,7 @@ func init() { prListCmd.Flags().StringSliceP("label", "l", nil, "Filter by label") prListCmd.Flags().StringP("assignee", "a", "", "Filter by assignee") - prViewCmd.Flags().BoolP("web", "w", false, "Open pull request in browser") + prViewCmd.Flags().BoolP("web", "w", false, "Open a pull request in the browser") } var prCmd = &cobra.Command{ @@ -57,11 +57,13 @@ var prStatusCmd = &cobra.Command{ } var prViewCmd = &cobra.Command{ Use: "view [{ | | }]", - Short: "View a pull request in the browser", - Long: `View a pull request specified by the argument. + Short: "View a pull request", + Long: `Display the title, body, and other information about a pull request. -Without an argument, the pull request that belongs to the current -branch is displayed.`, +Without an argument, the pull request that belongs to the current branch +is displayed. + +With '--web', open the pull request in a web browser instead.`, RunE: prView, } @@ -521,23 +523,6 @@ func prProjectList(pr api.PullRequest) string { return list } -func prParticipantList(pr api.PullRequest) string { - if len(pr.Participants.Nodes) == 0 { - return "" - } - - participantNames := make([]string, 0, len(pr.Participants.Nodes)) - for _, participant := range pr.Participants.Nodes { - participantNames = append(participantNames, participant.Login) - } - - list := strings.Join(participantNames, ", ") - if pr.Participants.TotalCount > len(pr.Participants.Nodes) { - list += ", …" - } - return list -} - var prURLRE = regexp.MustCompile(`^https://github\.com/([^/]+)/([^/]+)/pull/(\d+)`) func prFromURL(arg string) (string, ghrepo.Interface) { diff --git a/command/pr_checkout.go b/command/pr_checkout.go index 5db8fbd07..d237aefbb 100644 --- a/command/pr_checkout.go +++ b/command/pr_checkout.go @@ -123,7 +123,7 @@ var prCheckoutCmd = &cobra.Command{ Short: "Check out a pull request in Git", Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { - return errors.New("requires a PR number as an argument") + return errors.New("requires a pull request number as an argument") } return nil }, diff --git a/command/repo.go b/command/repo.go index 5e16f9645..c0f16b09c 100644 --- a/command/repo.go +++ b/command/repo.go @@ -37,7 +37,7 @@ func init() { repoForkCmd.Flags().Lookup("remote").NoOptDefVal = "true" repoCmd.AddCommand(repoViewCmd) - repoViewCmd.Flags().BoolP("web", "w", false, "Open repository in browser") + repoViewCmd.Flags().BoolP("web", "w", false, "Open a repository in the browser") } var repoCmd = &cobra.Command{ @@ -51,7 +51,7 @@ A repository can be supplied as an argument in any of the following formats: } var repoCloneCmd = &cobra.Command{ - Use: "clone []", + Use: "clone []", Args: cobra.MinimumNArgs(1), Short: "Clone a repository locally", Long: `Clone a GitHub repository locally. @@ -80,10 +80,12 @@ With no argument, creates a fork of the current repository. Otherwise, forks the var repoViewCmd = &cobra.Command{ Use: "view []", - Short: "View a repository in the browser", - Long: `View a GitHub repository. + Short: "View a repository", + Long: `Display the description and the README of a GitHub repository. -With no argument, the repository for the current directory is displayed.`, +With no argument, the repository for the current directory is displayed. + +With '--web', open the repository in a web browser instead.`, RunE: repoView, } @@ -169,7 +171,7 @@ func addUpstreamRemote(parentRepo ghrepo.Interface, cloneDir string) error { // TODO: support SSH remote URLs upstreamURL := fmt.Sprintf("https://github.com/%s.git", ghrepo.FullName(parentRepo)) - cloneCmd := git.GitCommand("-C", cloneDir, "remote", "add", "upstream", upstreamURL) + cloneCmd := git.GitCommand("-C", cloneDir, "remote", "add", "-f", "upstream", upstreamURL) cloneCmd.Stdout = os.Stdout cloneCmd.Stderr = os.Stderr return run.PrepareCmd(cloneCmd).Run() diff --git a/command/repo_test.go b/command/repo_test.go index e52df1313..cf3fe3423 100644 --- a/command/repo_test.go +++ b/command/repo_test.go @@ -186,7 +186,7 @@ func TestRepoFork_outside_yes(t *testing.T) { eq(t, output.Stderr(), "") eq(t, strings.Join(cs.Calls[0].Args, " "), "git clone https://github.com/someone/repo.git") - eq(t, strings.Join(cs.Calls[1].Args, " "), "git -C repo remote add upstream https://github.com/OWNER/REPO.git") + eq(t, strings.Join(cs.Calls[1].Args, " "), "git -C repo remote add -f upstream https://github.com/OWNER/REPO.git") test.ExpectLines(t, output.String(), "Created fork someone/REPO", @@ -219,7 +219,7 @@ func TestRepoFork_outside_survey_yes(t *testing.T) { eq(t, output.Stderr(), "") eq(t, strings.Join(cs.Calls[0].Args, " "), "git clone https://github.com/someone/repo.git") - eq(t, strings.Join(cs.Calls[1].Args, " "), "git -C repo remote add upstream https://github.com/OWNER/REPO.git") + eq(t, strings.Join(cs.Calls[1].Args, " "), "git -C repo remote add -f upstream https://github.com/OWNER/REPO.git") test.ExpectLines(t, output.String(), "Created fork someone/REPO", @@ -484,7 +484,7 @@ func TestRepoClone_hasParent(t *testing.T) { } eq(t, cs.Count, 2) - eq(t, strings.Join(cs.Calls[1].Args, " "), "git -C REPO remote add upstream https://github.com/hubot/ORIG.git") + eq(t, strings.Join(cs.Calls[1].Args, " "), "git -C REPO remote add -f upstream https://github.com/hubot/ORIG.git") } func TestRepoCreate(t *testing.T) { diff --git a/test/fixtures/prViewPreview.json b/test/fixtures/prViewPreview.json index 408d0f1fa..f660eaa6c 100644 --- a/test/fixtures/prViewPreview.json +++ b/test/fixtures/prViewPreview.json @@ -25,14 +25,6 @@ "milestone": { "title": "" }, - "participants": { - "nodes": [ - { - "login": "marseilles" - } - ], - "totalcount": 1 - }, "commits": { "totalCount": 12 }, diff --git a/test/fixtures/prViewPreviewWithLotsOfMetadata.json b/test/fixtures/prViewPreviewWithLotsOfMetadata.json deleted file mode 100644 index b6cd1d7ca..000000000 --- a/test/fixtures/prViewPreviewWithLotsOfMetadata.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "data": { - "repository": { - "pullRequest": { - "number": 12, - "title": "Blueberries are from a fork", - "state": "OPEN", - "body": "**blueberries taste good**", - "url": "https://github.com/OWNER/REPO/pull/12", - "author": { - "login": "nobody" - }, - "assignees": { - "nodes": [ - { - "login": "marseilles" - }, - { - "login": "monaco" - }, - { - "login": "montpellier" - } - ], - "totalcount": 4 - }, - "labels": { - "nodes": [ - { - "name": "one" - }, - { - "name": "two" - }, - { - "name": "three" - } - ], - "totalcount": 4 - }, - "projectcards": { - "nodes": [ - { - "project": { - "name": "Project 1" - }, - "column": { - "name": "column A" - } - }, - { - "project": { - "name": "Project 2" - }, - "column": { - "name": "column B" - } - }, - { - "project": { - "name": "Project 3" - }, - "column": { - "name": "column C" - } - } - ], - "totalcount": 4 - }, - "milestone": { - "title": "uluru" - }, - "participants": { - "nodes": [ - { - "login": "marseilles" - }, - { - "login": "monaco" - }, - { - "login": "montpellier" - } - ], - "totalcount": 4 - }, - "commits": { - "totalCount": 12 - }, - "baseRefName": "master", - "headRefName": "blueberries", - "headRepositoryOwner": { - "login": "hubot" - }, - "isCrossRepository": true, - "isDraft": false - } - } - } -} diff --git a/test/fixtures/prViewPreviewWithMetadataByBranch.json b/test/fixtures/prViewPreviewWithMetadataByBranch.json index 483b4d63c..aaf9c6dfa 100644 --- a/test/fixtures/prViewPreviewWithMetadataByBranch.json +++ b/test/fixtures/prViewPreviewWithMetadataByBranch.json @@ -27,14 +27,6 @@ "totalcount": 0 }, "milestone": {}, - "participants": { - "nodes": [ - { - "login": "nobody" - } - ], - "totalcount": 1 - }, "commits": { "totalCount": 12 }, @@ -118,20 +110,6 @@ "milestone": { "title": "uluru" }, - "participants": { - "nodes": [ - { - "login": "marseilles" - }, - { - "login": "monaco" - }, - { - "login": "montpellier" - } - ], - "totalcount": 3 - }, "headRepositoryOwner": { "login": "OWNER" }, diff --git a/test/fixtures/prViewPreviewWithMetadataByNumber.json b/test/fixtures/prViewPreviewWithMetadataByNumber.json index 7c82f438a..0981f4263 100644 --- a/test/fixtures/prViewPreviewWithMetadataByNumber.json +++ b/test/fixtures/prViewPreviewWithMetadataByNumber.json @@ -106,20 +106,6 @@ "milestone": { "title": "uluru" }, - "participants": { - "nodes": [ - { - "login": "marseilles" - }, - { - "login": "monaco" - }, - { - "login": "montpellier" - } - ], - "totalcount": 3 - }, "commits": { "totalCount": 12 },