diff --git a/command/issue.go b/command/issue.go index 814daf3ae..4409aa179 100644 --- a/command/issue.go +++ b/command/issue.go @@ -37,6 +37,7 @@ func init() { issueCreateCmd.Flags().StringP("milestone", "m", "", "Add the issue to a milestone by `name`") issueCmd.AddCommand(issueListCmd) + issueListCmd.Flags().BoolP("web", "w", false, "Open the browser to list the issue(s)") issueListCmd.Flags().StringP("assignee", "a", "", "Filter by assignee") issueListCmd.Flags().StringSliceP("label", "l", nil, "Filter by labels") issueListCmd.Flags().StringP("state", "s", "open", "Filter by state: {open|closed|all}") @@ -84,6 +85,7 @@ var issueListCmd = &cobra.Command{ Example: heredoc.Doc(` $ gh issue list -l "help wanted" $ gh issue list -A monalisa + $ gh issue list --web `), Args: cmdutil.NoArgsQuoteReminder, RunE: issueList, @@ -116,6 +118,33 @@ var issueReopenCmd = &cobra.Command{ RunE: issueReopen, } +func listURLWithQuery(listURL, entity, state, assignee string, labels []string, author, baseBranch string) (string, error) { + u, err := url.Parse(listURL) + if err != nil { + return "", err + } + queries := fmt.Sprintf("is:%s ", entity) + if state != "all" { + queries += fmt.Sprintf("is:%s ", state) + } + if assignee != "" { + queries += fmt.Sprintf("assignee:%s ", assignee) + } + for _, label := range labels { + queries += fmt.Sprintf("label:%s ", label) + } + if author != "" { + queries += fmt.Sprintf("author:%s ", author) + } + if baseBranch != "" { + queries += fmt.Sprintf("base:%s ", baseBranch) + } + q := u.Query() + q.Set("q", queries) + u.RawQuery = q.Encode() + return u.String(), nil +} + func issueList(cmd *cobra.Command, args []string) error { ctx := contextForCommand(cmd) apiClient, err := apiClientForContext(ctx) @@ -128,6 +157,11 @@ func issueList(cmd *cobra.Command, args []string) error { return err } + web, err := cmd.Flags().GetBool("web") + if err != nil { + return err + } + state, err := cmd.Flags().GetString("state") if err != nil { return err @@ -156,6 +190,19 @@ func issueList(cmd *cobra.Command, args []string) error { return err } + if web { + issueListURL := fmt.Sprintf( + "https://github.com/%s/issues", + ghrepo.FullName(baseRepo), + ) + openURL, err := listURLWithQuery(issueListURL, "issue", state, assignee, labels, author, "") + if err != nil { + return err + } + fmt.Fprintf(cmd.ErrOrStderr(), "Opening %s in your browser.\n", openURL) + return utils.OpenInBrowser(openURL) + } + listResult, err := api.IssueList(apiClient, baseRepo, state, labels, assignee, limit, author) if err != nil { return err diff --git a/command/pr.go b/command/pr.go index 2068a10e8..67e9086d7 100644 --- a/command/pr.go +++ b/command/pr.go @@ -37,11 +37,13 @@ func init() { prCmd.AddCommand(prReadyCmd) prCmd.AddCommand(prListCmd) + prListCmd.Flags().BoolP("web", "w", false, "Open the browser to list the pull request(s)") prListCmd.Flags().IntP("limit", "L", 30, "Maximum number of items to fetch") prListCmd.Flags().StringP("state", "s", "open", "Filter by state: {open|closed|merged|all}") prListCmd.Flags().StringP("base", "B", "", "Filter by base branch") - prListCmd.Flags().StringSliceP("label", "l", nil, "Filter by label") + prListCmd.Flags().StringSliceP("label", "l", nil, "Filter by labels") prListCmd.Flags().StringP("assignee", "a", "", "Filter by assignee") + prListCmd.Flags().StringP("author", "A", "", "Filter by author") prCmd.AddCommand(prViewCmd) prViewCmd.Flags().BoolP("web", "w", false, "Open a pull request in the browser") @@ -71,6 +73,7 @@ var prListCmd = &cobra.Command{ $ gh pr list --limit 999 $ gh pr list --state closed $ gh pr list --label "priority 1" --label "bug" + $ gh pr list --web `), RunE: prList, } @@ -194,6 +197,11 @@ func prList(cmd *cobra.Command, args []string) error { return err } + web, err := cmd.Flags().GetBool("web") + if err != nil { + return err + } + limit, err := cmd.Flags().GetInt("limit") if err != nil { return err @@ -218,6 +226,26 @@ func prList(cmd *cobra.Command, args []string) error { if err != nil { return err } + author, err := cmd.Flags().GetString("author") + if err != nil { + return err + } + if author != "" && !web { + return errors.New("the --author flag is currently supported only with --web") + } + + if web { + prListURL := fmt.Sprintf( + "https://github.com/%s/pulls", + ghrepo.FullName(baseRepo), + ) + openURL, err := listURLWithQuery(prListURL, "pr", state, assignee, labels, author, baseBranch) + if err != nil { + return err + } + fmt.Fprintf(cmd.ErrOrStderr(), "Opening %s in your browser.\n", openURL) + return utils.OpenInBrowser(openURL) + } var graphqlState []string switch state { diff --git a/command/pr_create.go b/command/pr_create.go index b2dd48697..4053c031c 100644 --- a/command/pr_create.go +++ b/command/pr_create.go @@ -412,7 +412,7 @@ func determineTrackingBranch(remotes context.Remotes, headBranch string) *git.Tr func withPrAndIssueQueryParams(baseURL, title, body string, assignees, labels, projects []string, milestone string) (string, error) { u, err := url.Parse(baseURL) if err != nil { - return "", nil + return "", err } q := u.Query() if title != "" {