From 115b47198d064aab13d5edf46900d756d843339a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 27 Dec 2020 04:27:03 +0100 Subject: [PATCH] issue, mr: Allow filtering lists by milestone It's useful to list all issues/merge requests associated with a milestone (for example for release planning), so add a corresponding filter option. --- cmd/issue_list.go | 29 ++++++++++----- cmd/issue_list_test.go | 16 +++++++++ cmd/mr_list.go | 12 +++++++ cmd/mr_test.go | 82 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 8 deletions(-) diff --git a/cmd/issue_list.go b/cmd/issue_list.go index ffc90498..819d7c41 100644 --- a/cmd/issue_list.go +++ b/cmd/issue_list.go @@ -12,11 +12,12 @@ import ( ) var ( - issueLabels []string - issueState string - issueSearch string - issueNumRet int - issueAll bool + issueLabels []string + issueMilestone string + issueState string + issueSearch string + issueNumRet int + issueAll bool ) var issueListCmd = &cobra.Command{ @@ -51,13 +52,22 @@ func issueList(args []string) ([]*gitlab.Issue, error) { return nil, err } + if issueMilestone != "" { + milestone, err := lab.MilestoneGet(rn, issueMilestone) + if err != nil { + return nil, err + } + issueMilestone = milestone.Title + } + opts := gitlab.ListProjectIssuesOptions{ ListOptions: gitlab.ListOptions{ PerPage: issueNumRet, }, - Labels: labels, - State: &issueState, - OrderBy: gitlab.String("updated_at"), + Labels: labels, + Milestone: &issueMilestone, + State: &issueState, + OrderBy: gitlab.String("updated_at"), } if issueSearch != "" { @@ -84,6 +94,9 @@ func init() { issueListCmd.Flags().BoolVarP( &issueAll, "all", "a", false, "list all issues on the project") + issueListCmd.Flags().StringVar( + &issueMilestone, "milestone", "", + "filter issues by milestone") issueCmd.AddCommand(issueListCmd) carapace.Gen(issueListCmd).FlagCompletion(carapace.ActionMap{ diff --git a/cmd/issue_list_test.go b/cmd/issue_list_test.go index 04831480..2ec6788a 100644 --- a/cmd/issue_list_test.go +++ b/cmd/issue_list_test.go @@ -56,6 +56,22 @@ func Test_issueListStateClosed(t *testing.T) { require.Contains(t, issues, "#4 test closed issue") } +func Test_issueListFlagMilestone(t *testing.T) { + t.Parallel() + repo := copyTestRepo(t) + cmd := exec.Command(labBinaryPath, "issue", "list", "--milestone", "1.0") + cmd.Dir = repo + + b, err := cmd.CombinedOutput() + if err != nil { + t.Fatal(err) + } + + issues := strings.Split(string(b), "\n") + t.Log(issues) + require.Contains(t, issues, "#1 test issue for lab list") +} + func Test_issueListSearch(t *testing.T) { t.Parallel() repo := copyTestRepo(t) diff --git a/cmd/mr_list.go b/cmd/mr_list.go index 2c5485a0..fbb6ba13 100644 --- a/cmd/mr_list.go +++ b/cmd/mr_list.go @@ -16,6 +16,7 @@ var ( mrLabels []string mrState string mrTargetBranch string + mrMilestone string mrNumRet int mrAll bool mrMine bool @@ -77,6 +78,14 @@ func mrList(args []string) ([]*gitlab.MergeRequest, error) { assigneeID = &_assigneeID } + if mrMilestone != "" { + milestone, err := lab.MilestoneGet(rn, mrMilestone) + if err != nil { + log.Fatal(err) + } + mrMilestone = milestone.Title + } + orderBy := gitlab.String(order) sort := gitlab.String(sortedBy) @@ -88,6 +97,7 @@ func mrList(args []string) ([]*gitlab.MergeRequest, error) { Labels: labels, State: &mrState, TargetBranch: &mrTargetBranch, + Milestone: &mrMilestone, OrderBy: orderBy, Sort: sort, AssigneeID: assigneeID, @@ -114,6 +124,8 @@ func init() { listCmd.Flags().StringVarP( &mrTargetBranch, "target-branch", "t", "", "filter merge requests by target branch") + listCmd.Flags().StringVar( + &mrMilestone, "milestone", "", "list only MRs for the given milestone") listCmd.Flags().BoolVarP(&mrAll, "all", "a", false, "list all MRs on the project") listCmd.Flags().BoolVarP(&mrMine, "mine", "m", false, "list only MRs assigned to me") listCmd.Flags().StringVar( diff --git a/cmd/mr_test.go b/cmd/mr_test.go index aedc3c45..c00b4207 100644 --- a/cmd/mr_test.go +++ b/cmd/mr_test.go @@ -344,6 +344,88 @@ func Test_mrCmd_Draft(t *testing.T) { }) } +func Test_mrCmd_Milestone(t *testing.T) { + repo := copyTestRepo(t) + var mrID string + t.Run("prepare", func(t *testing.T) { + cmd := exec.Command("sh", "-c", labBinaryPath+` mr list origin | grep -m1 'Test draft' | cut -c2- | awk '{print $1}' | xargs `+labBinaryPath+` mr origin -d`) + cmd.Dir = repo + + b, err := cmd.CombinedOutput() + if err != nil { + t.Log(string(b)) + //t.Fatal(err) + } + }) + t.Run("create", func(t *testing.T) { + git := exec.Command("git", "checkout", "mrtest") + git.Dir = repo + b, err := git.CombinedOutput() + if err != nil { + t.Log(string(b)) + t.Fatal(err) + } + + cmd := exec.Command(labBinaryPath, "mr", "create", "--milestone", "1.0", "origin", "master", + "-m", "MR for 1.0", + ) + cmd.Dir = repo + + b, _ = cmd.CombinedOutput() + out := string(b) + t.Log(out) + require.Contains(t, out, "https://gitlab.com/zaquestion/test/-/merge_requests") + + i := strings.Index(out, "/diffs\n") + mrID = strings.TrimPrefix(out[:i], "https://gitlab.com/zaquestion/test/-/merge_requests/") + t.Log(mrID) + }) + t.Run("list", func(t *testing.T) { + if mrID == "" { + t.Skip("mrID is empty, create likely failed") + } + cmd := exec.Command(labBinaryPath, "mr", "list", "--milestone", "1.0", "origin") + cmd.Dir = repo + + b, _ := cmd.CombinedOutput() + out := string(b) + t.Log(out) + require.Contains(t, out, "MR for 1.0") + }) + t.Run("modify", func(t *testing.T) { + if mrID == "" { + t.Skip("mrID is empty, create likely failed") + } + cmd := exec.Command(labBinaryPath, "mr", "edit", "--milestone", "", "origin") + cmd.Dir = repo + + b, _ := cmd.CombinedOutput() + t.Log(string(b)) + + cmd = exec.Command(labBinaryPath, "mr", "list", "--milestone", "1.0", "origin") + cmd.Dir = repo + + b, _ = cmd.CombinedOutput() + out := string(b) + t.Log(out) + require.NotContains(t, out, "MR for 1.0") + }) + t.Run("delete", func(t *testing.T) { + if mrID == "" { + t.Skip("mrID is empty, create likely failed") + } + cmd := exec.Command(labBinaryPath, "mr", "close", "origin", mrID) + cmd.Dir = repo + + b, err := cmd.CombinedOutput() + if err != nil { + t.Log(string(b)) + t.Fatal(err) + } + require.Contains(t, string(b), fmt.Sprintf("Merge Request !%s closed", mrID)) + }) +} + func Test_mrCmd_ByBranch(t *testing.T) { repo := copyTestRepo(t) var mrID string