|
| 1 | +package issues |
| 2 | + |
| 3 | +import ( |
| 4 | + "github.com/MakeNowJust/heredoc" |
| 5 | + "github.com/cli/cli/v2/pkg/cmd/search/shared" |
| 6 | + "github.com/cli/cli/v2/pkg/cmdutil" |
| 7 | + "github.com/cli/cli/v2/pkg/search" |
| 8 | + "github.com/spf13/cobra" |
| 9 | +) |
| 10 | + |
| 11 | +func NewCmdIssues(f *cmdutil.Factory, runF func(*shared.IssuesOptions) error) *cobra.Command { |
| 12 | + var includePrs bool |
| 13 | + var locked bool |
| 14 | + var noAssignee, noLabel, noMilestone, noProject bool |
| 15 | + var order string |
| 16 | + var sort string |
| 17 | + opts := &shared.IssuesOptions{ |
| 18 | + Browser: f.Browser, |
| 19 | + Entity: shared.Issues, |
| 20 | + IO: f.IOStreams, |
| 21 | + Query: search.Query{Kind: search.KindIssues, |
| 22 | + Qualifiers: search.Qualifiers{Type: "issue"}}, |
| 23 | + } |
| 24 | + |
| 25 | + cmd := &cobra.Command{ |
| 26 | + Use: "issues [<query>]", |
| 27 | + Short: "Search for issues", |
| 28 | + Long: heredoc.Doc(` |
| 29 | + Search for issues on GitHub. |
| 30 | +
|
| 31 | + The command supports constructing queries using the GitHub search syntax, |
| 32 | + using the parameter and qualifier flags, or a combination of the two. |
| 33 | +
|
| 34 | + GitHub search syntax is documented at: |
| 35 | + <https://docs.github.com/search-github/searching-on-github/searching-issues-and-pull-requests> |
| 36 | + `), |
| 37 | + Example: heredoc.Doc(` |
| 38 | + # search issues matching set of keywords "readme" and "typo" |
| 39 | + $ gh search issues readme typo |
| 40 | +
|
| 41 | + # search issues matching phrase "broken feature" |
| 42 | + $ gh search issues "broken feature" |
| 43 | +
|
| 44 | + # search issues and pull requests in cli organization |
| 45 | + $ gh search issues --include-prs --owner=cli |
| 46 | +
|
| 47 | + # search open issues assigned to yourself |
| 48 | + $ gh search issues --assignee=@me --state=open |
| 49 | +
|
| 50 | + # search issues with numerous comments |
| 51 | + $ gh search issues --comments=">100" |
| 52 | + `), |
| 53 | + RunE: func(c *cobra.Command, args []string) error { |
| 54 | + if len(args) == 0 && c.Flags().NFlag() == 0 { |
| 55 | + return cmdutil.FlagErrorf("specify search keywords or flags") |
| 56 | + } |
| 57 | + if opts.Query.Limit < 1 || opts.Query.Limit > shared.SearchMaxResults { |
| 58 | + return cmdutil.FlagErrorf("`--limit` must be between 1 and 1000") |
| 59 | + } |
| 60 | + if includePrs { |
| 61 | + opts.Entity = shared.Both |
| 62 | + opts.Query.Qualifiers.Type = "" |
| 63 | + } |
| 64 | + if c.Flags().Changed("order") { |
| 65 | + opts.Query.Order = order |
| 66 | + } |
| 67 | + if c.Flags().Changed("sort") { |
| 68 | + opts.Query.Sort = sort |
| 69 | + } |
| 70 | + if c.Flags().Changed("locked") { |
| 71 | + if locked { |
| 72 | + opts.Query.Qualifiers.Is = append(opts.Query.Qualifiers.Is, "locked") |
| 73 | + } else { |
| 74 | + opts.Query.Qualifiers.Is = append(opts.Query.Qualifiers.Is, "unlocked") |
| 75 | + } |
| 76 | + } |
| 77 | + if c.Flags().Changed("no-assignee") && noAssignee { |
| 78 | + opts.Query.Qualifiers.No = append(opts.Query.Qualifiers.No, "assignee") |
| 79 | + } |
| 80 | + if c.Flags().Changed("no-label") && noLabel { |
| 81 | + opts.Query.Qualifiers.No = append(opts.Query.Qualifiers.No, "label") |
| 82 | + } |
| 83 | + if c.Flags().Changed("no-milestone") && noMilestone { |
| 84 | + opts.Query.Qualifiers.No = append(opts.Query.Qualifiers.No, "milestone") |
| 85 | + } |
| 86 | + if c.Flags().Changed("no-project") && noProject { |
| 87 | + opts.Query.Qualifiers.No = append(opts.Query.Qualifiers.No, "project") |
| 88 | + } |
| 89 | + opts.Query.Keywords = args |
| 90 | + if runF != nil { |
| 91 | + return runF(opts) |
| 92 | + } |
| 93 | + var err error |
| 94 | + opts.Searcher, err = shared.Searcher(f) |
| 95 | + if err != nil { |
| 96 | + return err |
| 97 | + } |
| 98 | + return shared.SearchIssues(opts) |
| 99 | + }, |
| 100 | + } |
| 101 | + |
| 102 | + // Output flags |
| 103 | + cmdutil.AddJSONFlags(cmd, &opts.Exporter, search.IssueFields) |
| 104 | + cmd.Flags().BoolVarP(&opts.WebMode, "web", "w", false, "Open the search query in the web browser") |
| 105 | + |
| 106 | + // Query parameter flags |
| 107 | + cmd.Flags().IntVarP(&opts.Query.Limit, "limit", "L", 30, "Maximum number of results to fetch") |
| 108 | + cmdutil.StringEnumFlag(cmd, &order, "order", "", "desc", []string{"asc", "desc"}, "Order of results returned, ignored unless '--sort' flag is specified") |
| 109 | + cmdutil.StringEnumFlag(cmd, &sort, "sort", "", "best-match", |
| 110 | + []string{ |
| 111 | + "comments", |
| 112 | + "created", |
| 113 | + "interactions", |
| 114 | + "reactions", |
| 115 | + "reactions-+1", |
| 116 | + "reactions--1", |
| 117 | + "reactions-heart", |
| 118 | + "reactions-smile", |
| 119 | + "reactions-tada", |
| 120 | + "reactions-thinking_face", |
| 121 | + "updated", |
| 122 | + }, "Sort fetched results") |
| 123 | + |
| 124 | + // Query qualifier flags |
| 125 | + cmd.Flags().BoolVar(&includePrs, "include-prs", false, "Include pull requests in results") |
| 126 | + cmdutil.NilBoolFlag(cmd, &opts.Query.Qualifiers.Archived, "archived", "", "Restrict search to archived repositories") |
| 127 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Assignee, "assignee", "", "Filter by assignee") |
| 128 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Author, "author", "", "Filter by author") |
| 129 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Closed, "closed", "", "Filter on closed at `date`") |
| 130 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Commenter, "commenter", "", "Filter based on comments by `user`") |
| 131 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Comments, "comments", "", "Filter on `number` of comments") |
| 132 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Created, "created", "", "Filter based on created at `date`") |
| 133 | + cmdutil.StringSliceEnumFlag(cmd, &opts.Query.Qualifiers.In, "match", "", nil, []string{"title", "body", "comments"}, "Restrict search to specific field of issue") |
| 134 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Interactions, "interactions", "", "Filter on `number` of reactions and comments") |
| 135 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Involves, "involves", "", "Filter based on involvement of `user`") |
| 136 | + cmdutil.StringSliceEnumFlag(cmd, &opts.Query.Qualifiers.Is, "visibility", "", nil, []string{"public", "private", "internal"}, "Filter based on repository visibility") |
| 137 | + cmd.Flags().StringSliceVar(&opts.Query.Qualifiers.Label, "label", nil, "Filter on label") |
| 138 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Language, "language", "", "Filter based on the coding language") |
| 139 | + cmd.Flags().BoolVar(&locked, "locked", false, "Filter on locked conversation status") |
| 140 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Mentions, "mentions", "", "Filter based on `user` mentions") |
| 141 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Milestone, "milestone", "", "Filter by milestone `title`") |
| 142 | + cmd.Flags().BoolVar(&noAssignee, "no-assignee", false, "Filter on missing assignee") |
| 143 | + cmd.Flags().BoolVar(&noLabel, "no-label", false, "Filter on missing label") |
| 144 | + cmd.Flags().BoolVar(&noMilestone, "no-milestone", false, "Filter on missing milestone") |
| 145 | + cmd.Flags().BoolVar(&noProject, "no-project", false, "Filter on missing project") |
| 146 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Org, "owner", "", "Filter on owner") |
| 147 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Project, "project", "", "Filter on project board `number`") |
| 148 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Reactions, "reactions", "", "Filter on `number` of reactions") |
| 149 | + cmd.Flags().StringSliceVar(&opts.Query.Qualifiers.Repo, "repo", nil, "Filter on repository") |
| 150 | + cmdutil.StringEnumFlag(cmd, &opts.Query.Qualifiers.State, "state", "", "", []string{"open", "closed"}, "Filter based on state") |
| 151 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Team, "team-mentions", "", "Filter based on team mentions") |
| 152 | + cmd.Flags().StringVar(&opts.Query.Qualifiers.Updated, "updated", "", "Filter on last updated at `date`") |
| 153 | + |
| 154 | + return cmd |
| 155 | +} |
0 commit comments