in commands/issuable/list/issuable_list.go [68:189]
func NewCmdList(f *cmdutils.Factory, runE func(opts *ListOptions) error, issueType issuable.IssueType) *cobra.Command {
opts := &ListOptions{
IO: f.IO,
IssueType: string(issueType),
}
issueListCmd := &cobra.Command{
Use: "list [flags]",
Short: fmt.Sprintf(`List project %ss.`, issueType),
Long: ``,
Aliases: []string{"ls"},
Example: heredoc.Doc(fmt.Sprintf(`
- glab %[1]s list --all
- glab %[1]s ls --all
- glab %[1]s list --assignee=@me
- glab %[1]s list --milestone release-2.0.0 --opened
`, issueType)),
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
// support repo override
opts.BaseRepo = f.BaseRepo
opts.HTTPClient = f.HttpClient
if len(opts.Labels) != 0 && len(opts.NotLabels) != 0 {
return cmdutils.FlagError{
Err: errors.New("flags --label and --not-label are mutually exclusive."),
}
}
if opts.Author != "" && len(opts.NotAuthor) != 0 {
return cmdutils.FlagError{
Err: errors.New("flags --author and --not-author are mutually exclusive."),
}
}
if opts.Assignee != "" && len(opts.NotAssignee) != 0 {
return cmdutils.FlagError{
Err: errors.New("flags --assignee and --not-assignee are mutually exclusive."),
}
}
if opts.All {
opts.State = "all"
} else if opts.Closed {
opts.State = "closed"
opts.TitleQualifier = "closed"
} else {
opts.State = "opened"
opts.TitleQualifier = "open"
}
group, err := flag.GroupOverride(cmd)
if err != nil {
return err
}
opts.Group = group
if opts.Epic != 0 && opts.Group == "" {
repo, err := opts.BaseRepo()
if err != nil {
return err
}
opts.Group = repo.RepoOwner()
}
if opts.Epic != 0 && opts.Group == "" {
return cmdutils.FlagError{
Err: errors.New("flag --epic requires flag --group"),
}
}
// The underlying API, ListEpicIssues, does not support filtering, so we do the filtering client-side.
// That means to implement pagination, we'd still need to request all previous issues and filter them.
// That means client side pagination is more expensive (O(n^2)) than requesting all issues belonging to an epic (O(n)).
if opts.Epic != 0 && opts.Page > 1 {
return cmdutils.FlagError{
Err: errors.New("--epic does not support the --page flag"),
}
}
if runE != nil {
return runE(opts)
}
return listRun(opts)
},
}
cmdutils.EnableRepoOverride(issueListCmd, f)
issueListCmd.Flags().StringVarP(&opts.Assignee, "assignee", "a", "", fmt.Sprintf("Filter %s by assignee <username>.", issueType))
issueListCmd.Flags().StringVar(&opts.NotAssignee, "not-assignee", "", fmt.Sprintf("Filter %s by not being assigned to <username>.", issueType))
issueListCmd.Flags().StringVar(&opts.Author, "author", "", fmt.Sprintf("Filter %s by author <username>.", issueType))
issueListCmd.Flags().StringVar(&opts.NotAuthor, "not-author", "", fmt.Sprintf("Filter %s by not being by author(s) <username>.", issueType))
issueListCmd.Flags().StringVar(&opts.Search, "search", "", "Search <string> in the fields defined by '--in'.")
issueListCmd.Flags().StringVar(&opts.In, "in", "title,description", "search in: title, description.")
issueListCmd.Flags().StringSliceVarP(&opts.Labels, "label", "l", []string{}, fmt.Sprintf("Filter %s by label <name>.", issueType))
issueListCmd.Flags().StringSliceVar(&opts.NotLabels, "not-label", []string{}, fmt.Sprintf("Filter %s by lack of label <name>.", issueType))
issueListCmd.Flags().StringVarP(&opts.Milestone, "milestone", "m", "", fmt.Sprintf("Filter %s by milestone <id>.", issueType))
issueListCmd.Flags().BoolVarP(&opts.All, "all", "A", false, fmt.Sprintf("Get all %ss.", issueType))
issueListCmd.Flags().BoolVarP(&opts.Closed, "closed", "c", false, fmt.Sprintf("Get only closed %ss.", issueType))
issueListCmd.Flags().BoolVarP(&opts.Confidential, "confidential", "C", false, fmt.Sprintf("Filter by confidential %ss.", issueType))
issueListCmd.Flags().StringVarP(&opts.OutputFormat, "output-format", "F", "details", "Options: 'details', 'ids', 'urls'.")
issueListCmd.Flags().StringVarP(&opts.Output, "output", "O", "text", "Options: 'text' or 'json'.")
issueListCmd.Flags().IntVarP(&opts.Page, "page", "p", 1, "Page number.")
issueListCmd.Flags().IntVarP(&opts.PerPage, "per-page", "P", 30, "Number of items to list per page.")
issueListCmd.PersistentFlags().StringP("group", "g", "", "Select a group or subgroup. Ignored if a repo argument is set.")
issueListCmd.Flags().IntVarP(&opts.Epic, "epic", "e", 0, "List issues belonging to a given epic (requires --group, no pagination support).")
issueListCmd.MarkFlagsMutuallyExclusive("output", "output-format")
if issueType == issuable.TypeIssue {
issueListCmd.Flags().StringVarP(&opts.IssueType, "issue-type", "t", "", "Filter issue by its type. Options: issue, incident, test_case.")
issueListCmd.Flags().IntVarP(&opts.Iteration, "iteration", "i", 0, "Filter issue by iteration <id>.")
}
issueListCmd.Flags().BoolP("opened", "o", false, fmt.Sprintf("Get only open %ss.", issueType))
_ = issueListCmd.Flags().MarkHidden("opened")
_ = issueListCmd.Flags().MarkDeprecated("opened", "default if --closed is not used.")
issueListCmd.Flags().BoolVarP(&opts.Mine, "mine", "M", false, fmt.Sprintf("Filter only %ss assigned to me.", issueType))
_ = issueListCmd.Flags().MarkHidden("mine")
_ = issueListCmd.Flags().MarkDeprecated("mine", "use --assignee=@me")
return issueListCmd
}