Skip to content

Commit

Permalink
milestone: Add new milestone command
Browse files Browse the repository at this point in the history
Milestones are currently mostly unsupported. Start changing that
by adding a new command that mirrors the handling of labels.
  • Loading branch information
fmuellner committed Jan 12, 2021
1 parent 87310aa commit bdc9670
Show file tree
Hide file tree
Showing 7 changed files with 400 additions and 0 deletions.
20 changes: 20 additions & 0 deletions cmd/milestone.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cmd

import (
"github.com/spf13/cobra"
)

var milestoneCmd = &cobra.Command{
Use: "milestone",
Short: `List and search milestones`,
Long: ``,
PersistentPreRun: LabPersistentPreRun,
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
return
},
}

func init() {
RootCmd.AddCommand(milestoneCmd)
}
49 changes: 49 additions & 0 deletions cmd/milestone_create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package cmd

import (
"log"

"github.com/rsteube/carapace"
"github.com/spf13/cobra"
gitlab "github.com/xanzy/go-gitlab"
"github.com/zaquestion/lab/internal/action"
lab "github.com/zaquestion/lab/internal/gitlab"
)

var milestoneCreateCmd = &cobra.Command{
Use: "create [remote] <name>",
Aliases: []string{"add"},
Short: "Create a new milestone",
Long: ``,
Example: "lab milestone create my-milestone",
PersistentPreRun: LabPersistentPreRun,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
rn, title, err := parseArgsRemoteAndProject(args)
if err != nil {
log.Fatal(err)
}

desc, err := cmd.Flags().GetString("description")
if err != nil {
log.Fatal(err)
}

err = lab.MilestoneCreate(rn, &gitlab.CreateMilestoneOptions{
Title: &title,
Description: &desc,
})

if err != nil {
log.Fatal(err)
}
},
}

func init() {
milestoneCreateCmd.Flags().String("description", "", "description of the new milestone")
milestoneCmd.AddCommand(milestoneCreateCmd)
carapace.Gen(milestoneCmd).PositionalCompletion(
action.Remotes(),
)
}
37 changes: 37 additions & 0 deletions cmd/milestone_delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package cmd

import (
"log"

"github.com/rsteube/carapace"
"github.com/spf13/cobra"
"github.com/zaquestion/lab/internal/action"
lab "github.com/zaquestion/lab/internal/gitlab"
)

var milestoneDeleteCmd = &cobra.Command{
Use: "delete [remote] <name>",
Aliases: []string{"remove"},
Short: "Deletes an existing milestone",
Long: ``,
PersistentPreRun: LabPersistentPreRun,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
rn, name, err := parseArgsRemoteAndProject(args)
if err != nil {
log.Fatal(err)
}

err = lab.MilestoneDelete(rn, name)
if err != nil {
log.Fatal(err)
}
},
}

func init() {
milestoneCmd.AddCommand(milestoneDeleteCmd)
carapace.Gen(milestoneCmd).PositionalCompletion(
action.Remotes(),
)
}
63 changes: 63 additions & 0 deletions cmd/milestone_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package cmd

import (
"fmt"
"log"
"strings"

"github.com/rsteube/carapace"
"github.com/spf13/cobra"
gitlab "github.com/xanzy/go-gitlab"
"github.com/zaquestion/lab/internal/action"
lab "github.com/zaquestion/lab/internal/gitlab"
)

var milestoneListCmd = &cobra.Command{
Use: "list [remote] [search]",
Aliases: []string{"ls", "search"},
Short: "List milestones",
Long: ``,
Example: `lab milestone list # list all milestones
lab milestone list "search term" # search milestones for "search term"
lab milestone search "search term" # same as above
lab milestone list remote "search term" # search "remote" for milestones with "search term"`,
PersistentPreRun: LabPersistentPreRun,
Run: func(cmd *cobra.Command, args []string) {
rn, milestoneSearch, err := parseArgsRemoteAndProject(args)
if err != nil {
log.Fatal(err)
}

milestoneState, _ := cmd.Flags().GetString("state")
opts := &gitlab.ListMilestonesOptions{
State: &milestoneState,
}

milestoneSearch = strings.ToLower(milestoneSearch)
if milestoneSearch != "" {
opts.Search = &milestoneSearch
}

milestones, err := lab.MilestoneList(rn, opts)
if err != nil {
log.Fatal(err)
}

for _, milestone := range milestones {
description := ""
if milestone.Description != "" {
description = " - " + milestone.Description
}

fmt.Printf("%s%s\n", milestone.Title, description)
}
},
}

func init() {
milestoneListCmd.Flags().StringP("state", "s", "active", "filter milestones by state (active/closed)")
milestoneCmd.AddCommand(milestoneListCmd)
carapace.Gen(milestoneCmd).PositionalCompletion(
action.Remotes(),
)
}
57 changes: 57 additions & 0 deletions cmd/milestone_list_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package cmd

import (
"os/exec"
"strings"
"testing"

"github.com/stretchr/testify/require"
)

func Test_milestoneList(t *testing.T) {
t.Parallel()
repo := copyTestRepo(t)
cmd := exec.Command(labBinaryPath, "milestone", "list")
cmd.Dir = repo

b, err := cmd.CombinedOutput()
if err != nil {
t.Fatal(err)
}

milestones := strings.Split(string(b), "\n")
t.Log(milestones)
require.Contains(t, milestones, "1.0")
}

func Test_milestoneListSearch(t *testing.T) {
t.Parallel()
repo := copyTestRepo(t)
cmd := exec.Command(labBinaryPath, "milestone", "list", "99")
cmd.Dir = repo

b, err := cmd.CombinedOutput()
if err != nil {
t.Fatal(err)
}

milestones := strings.Split(string(b), "\n")
t.Log(milestones)
require.NotContains(t, milestones, "1.0")
}

func Test_milestoneListState(t *testing.T) {
t.Parallel()
repo := copyTestRepo(t)
cmd := exec.Command(labBinaryPath, "milestone", "list", "--state", "closed")
cmd.Dir = repo

b, err := cmd.CombinedOutput()
if err != nil {
t.Fatal(err)
}

milestones := strings.Split(string(b), "\n")
t.Log(milestones)
require.NotContains(t, milestones, "1.0")
}
61 changes: 61 additions & 0 deletions cmd/milestone_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package cmd

import (
"os/exec"
"strings"
"testing"

"github.com/stretchr/testify/require"
)

func Test_milestoneCmd(t *testing.T) {
t.Parallel()
repo := copyTestRepo(t)
t.Run("prepare", func(t *testing.T) {
cmd := exec.Command("sh", "-c", labBinaryPath+` milestone list lab-testing | grep -q 'test-milestone' && `+labBinaryPath+` milestone delete test-milestone`)
cmd.Dir = repo

b, err := cmd.CombinedOutput()
if err != nil {
t.Log(string(b))
//t.Fatal(err)
}
})
t.Run("create", func(t *testing.T) {
cmd := exec.Command(labBinaryPath, "milestone", "create", "lab-testing", "test-milestone")
cmd.Dir = repo

b, _ := cmd.CombinedOutput()
if strings.Contains(string(b), "403 Forbidden") {
t.Skip("No permission to change milestones, skipping")
}

cmd = exec.Command(labBinaryPath, "milestone", "list", "lab-testing")
cmd.Dir = repo

b, err := cmd.CombinedOutput()
out := string(b)
if err != nil {
t.Log(out)
//t.Fatal(err)
}
require.Contains(t, out, "test-milestone")
})
t.Run("delete", func(t *testing.T) {
cmd := exec.Command(labBinaryPath, "milestone", "delete", "lab-testing", "test-milestone")
cmd.Dir = repo

_ = cmd.Run()

cmd = exec.Command(labBinaryPath, "milestone", "list", "lab-testing")
cmd.Dir = repo

b, err := cmd.CombinedOutput()
out := string(b)
if err != nil {
t.Log(out)
//t.Fatal(err)
}
require.NotContains(t, out, "test-milestone")
})
}
Loading

0 comments on commit bdc9670

Please sign in to comment.