mirror of https://gitlab.com/gitlab-org/cli.git
256 lines
7.2 KiB
Go
256 lines
7.2 KiB
Go
package list
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"gitlab.com/gitlab-org/cli/pkg/iostreams"
|
|
|
|
"github.com/MakeNowJust/heredoc"
|
|
"gitlab.com/gitlab-org/cli/internal/glrepo"
|
|
|
|
"gitlab.com/gitlab-org/cli/api"
|
|
"gitlab.com/gitlab-org/cli/commands/cmdutils"
|
|
"gitlab.com/gitlab-org/cli/commands/mr/mrutils"
|
|
"gitlab.com/gitlab-org/cli/pkg/utils"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/xanzy/go-gitlab"
|
|
)
|
|
|
|
type ListOptions struct {
|
|
// metadata
|
|
Assignee []string
|
|
Reviewer []string
|
|
Author string
|
|
Labels []string
|
|
NotLabels []string
|
|
Milestone string
|
|
SourceBranch string
|
|
TargetBranch string
|
|
Search string
|
|
Mine bool
|
|
Group string
|
|
|
|
// issue states
|
|
State string
|
|
Closed bool
|
|
Merged bool
|
|
All bool
|
|
Draft bool
|
|
|
|
// Pagination
|
|
Page int
|
|
PerPage int
|
|
|
|
// display opts
|
|
ListType string
|
|
TitleQualifier string
|
|
|
|
IO *iostreams.IOStreams
|
|
BaseRepo func() (glrepo.Interface, error)
|
|
HTTPClient func() (*gitlab.Client, error)
|
|
}
|
|
|
|
func NewCmdList(f *cmdutils.Factory, runE func(opts *ListOptions) error) *cobra.Command {
|
|
var opts = &ListOptions{
|
|
IO: f.IO,
|
|
}
|
|
|
|
var mrListCmd = &cobra.Command{
|
|
Use: "list [flags]",
|
|
Short: `List merge requests`,
|
|
Long: ``,
|
|
Aliases: []string{"ls"},
|
|
Example: heredoc.Doc(`
|
|
glab mr list --all
|
|
glab mr ls -a
|
|
glab mr list --assignee=@me
|
|
glab mr list --reviewer=@me
|
|
glab mr list --source-branch=new-feature
|
|
glab mr list --target-branch=main
|
|
glab mr list --search "this adds feature X"
|
|
glab mr list --label needs-review
|
|
glab mr list --not-label waiting-maintainer-feedback,subsystem-x
|
|
glab mr list -M --per-page 10
|
|
`),
|
|
Args: cobra.ExactArgs(0),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
// supports 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"),
|
|
}
|
|
}
|
|
|
|
// check if any of the two or all of states flag are specified
|
|
if opts.Closed && opts.Merged {
|
|
return cmdutils.FlagError{
|
|
Err: errors.New("specify either --closed or --merged. Use --all issues in all states"),
|
|
}
|
|
}
|
|
if opts.All {
|
|
opts.State = "all"
|
|
} else if opts.Closed {
|
|
opts.State = "closed"
|
|
opts.TitleQualifier = opts.State
|
|
} else if opts.Merged {
|
|
opts.State = "merged"
|
|
opts.TitleQualifier = opts.State
|
|
} else {
|
|
opts.State = "opened"
|
|
opts.TitleQualifier = "open"
|
|
}
|
|
|
|
if runE != nil {
|
|
return runE(opts)
|
|
}
|
|
|
|
return listRun(opts)
|
|
},
|
|
}
|
|
|
|
mrListCmd.Flags().StringSliceVarP(&opts.Labels, "label", "l", []string{}, "Filter merge request by label <name>")
|
|
mrListCmd.Flags().StringSliceVar(&opts.NotLabels, "not-label", []string{}, "Filter merge requests by not having label <name>")
|
|
mrListCmd.Flags().StringVar(&opts.Author, "author", "", "Filter merge request by Author <username>")
|
|
mrListCmd.Flags().StringVarP(&opts.Milestone, "milestone", "m", "", "Filter merge request by milestone <id>")
|
|
mrListCmd.Flags().StringVarP(&opts.SourceBranch, "source-branch", "s", "", "Filter by source branch <name>")
|
|
mrListCmd.Flags().StringVarP(&opts.TargetBranch, "target-branch", "t", "", "Filter by target branch <name>")
|
|
mrListCmd.Flags().StringVar(&opts.Search, "search", "", "Filter by <string> in title and description")
|
|
mrListCmd.Flags().BoolVarP(&opts.All, "all", "A", false, "Get all merge requests")
|
|
mrListCmd.Flags().BoolVarP(&opts.Closed, "closed", "c", false, "Get only closed merge requests")
|
|
mrListCmd.Flags().BoolVarP(&opts.Merged, "merged", "M", false, "Get only merged merge requests")
|
|
mrListCmd.Flags().BoolVarP(&opts.Draft, "draft", "d", false, "Filter by draft merge requests")
|
|
mrListCmd.Flags().IntVarP(&opts.Page, "page", "p", 1, "Page number")
|
|
mrListCmd.Flags().IntVarP(&opts.PerPage, "per-page", "P", 30, "Number of items to list per page")
|
|
mrListCmd.Flags().StringSliceVarP(&opts.Assignee, "assignee", "a", []string{}, "Get only merge requests assigned to users")
|
|
mrListCmd.Flags().StringSliceVarP(&opts.Reviewer, "reviewer", "r", []string{}, "Get only merge requests with users as reviewer")
|
|
|
|
mrListCmd.Flags().BoolP("opened", "o", false, "Get only open merge requests")
|
|
_ = mrListCmd.Flags().MarkHidden("opened")
|
|
_ = mrListCmd.Flags().MarkDeprecated("opened", "default value if neither --closed, --locked or --merged is used")
|
|
|
|
mrListCmd.Flags().BoolVarP(&opts.Mine, "mine", "", false, "Get only merge requests assigned to me")
|
|
_ = mrListCmd.Flags().MarkHidden("mine")
|
|
_ = mrListCmd.Flags().MarkDeprecated("mine", "use --assignee=@me")
|
|
mrListCmd.Flags().StringVarP(&opts.Group, "group", "g", "", "Get MRs from group and it's subgroups")
|
|
|
|
return mrListCmd
|
|
}
|
|
|
|
func listRun(opts *ListOptions) error {
|
|
var mergeRequests []*gitlab.MergeRequest
|
|
|
|
apiClient, err := opts.HTTPClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
repo, err := opts.BaseRepo()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
l := &gitlab.ListProjectMergeRequestsOptions{
|
|
State: gitlab.String(opts.State),
|
|
}
|
|
l.Page = 1
|
|
l.PerPage = 30
|
|
|
|
if opts.Author != "" {
|
|
u, err := api.UserByName(apiClient, opts.Author)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
l.AuthorID = gitlab.Int(u.ID)
|
|
opts.ListType = "search"
|
|
}
|
|
if opts.SourceBranch != "" {
|
|
l.SourceBranch = gitlab.String(opts.SourceBranch)
|
|
opts.ListType = "search"
|
|
}
|
|
if opts.TargetBranch != "" {
|
|
l.TargetBranch = gitlab.String(opts.TargetBranch)
|
|
opts.ListType = "search"
|
|
}
|
|
if opts.Search != "" {
|
|
l.Search = gitlab.String(opts.Search)
|
|
opts.ListType = "search"
|
|
}
|
|
if len(opts.Labels) > 0 {
|
|
l.Labels = (*gitlab.Labels)(&opts.Labels)
|
|
opts.ListType = "search"
|
|
}
|
|
if opts.Milestone != "" {
|
|
l.Milestone = gitlab.String(opts.Milestone)
|
|
opts.ListType = "search"
|
|
}
|
|
if opts.Page != 0 {
|
|
l.Page = opts.Page
|
|
}
|
|
if opts.PerPage != 0 {
|
|
l.PerPage = opts.PerPage
|
|
}
|
|
if opts.Draft {
|
|
l.WIP = gitlab.String("yes")
|
|
opts.ListType = "search"
|
|
}
|
|
|
|
if opts.Mine {
|
|
l.Scope = gitlab.String("assigned_to_me")
|
|
opts.ListType = "search"
|
|
}
|
|
|
|
assigneeIds := make([]int, 0)
|
|
if len(opts.Assignee) > 0 {
|
|
users, err := api.UsersByNames(apiClient, opts.Assignee)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, user := range users {
|
|
assigneeIds = append(assigneeIds, user.ID)
|
|
}
|
|
}
|
|
|
|
reviewerIds := make([]int, 0)
|
|
if len(opts.Reviewer) > 0 {
|
|
users, err := api.UsersByNames(apiClient, opts.Reviewer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, user := range users {
|
|
reviewerIds = append(reviewerIds, user.ID)
|
|
}
|
|
}
|
|
title := utils.NewListTitle(opts.TitleQualifier + " merge request")
|
|
title.RepoName = repo.FullName()
|
|
|
|
if len(assigneeIds) > 0 || len(reviewerIds) > 0 {
|
|
mergeRequests, err = api.ListMRsWithAssigneesOrReviewers(apiClient, repo.FullName(), l, assigneeIds, reviewerIds)
|
|
|
|
} else if opts.Group != "" {
|
|
mergeRequests, err = api.ListGroupMRs(apiClient, opts.Group, api.ProjectListMROptionsToGroup(l))
|
|
title.RepoName = opts.Group
|
|
} else {
|
|
mergeRequests, err = api.ListMRs(apiClient, repo.FullName(), l)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
title.Page = l.Page
|
|
title.ListActionType = opts.ListType
|
|
title.CurrentPageTotal = len(mergeRequests)
|
|
|
|
if err = opts.IO.StartPager(); err != nil {
|
|
return err
|
|
}
|
|
defer opts.IO.StopPager()
|
|
fmt.Fprintf(opts.IO.StdOut, "%s\n%s\n", title.Describe(), mrutils.DisplayAllMRs(opts.IO, mergeRequests))
|
|
|
|
return nil
|
|
}
|