Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue list search #242

Merged
merged 5 commits into from
Nov 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions cmd/issue_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,22 @@ import (
var (
issueLabels []string
issueState string
issueSearch string
issueNumRet int
issueAll bool
)

var issueListCmd = &cobra.Command{
claytonrcarter marked this conversation as resolved.
Show resolved Hide resolved
Use: "list [remote]",
Aliases: []string{"ls"},
Use: "list [remote] [search]",
Aliases: []string{"ls", "search"},
Short: "List issues",
Long: ``,
Example: `lab issue list # list all open issues
lab issue list "search terms" # search issues for "search terms"
lab issue search "search terms" # same as above
lab issue list remote "search terms" # search "remote" for issues with "search terms"`,
Run: func(cmd *cobra.Command, args []string) {
rn, _, err := parseArgs(args)
rn, issueSearch, err := parseArgsRemoteString(args)
if err != nil {
log.Fatal(err)
}
Expand All @@ -35,6 +40,11 @@ var issueListCmd = &cobra.Command{
State: &issueState,
OrderBy: gitlab.String("updated_at"),
}

if issueSearch != "" {
opts.Search = &issueSearch
}

num := issueNumRet
if issueAll {
num = -1
Expand All @@ -51,13 +61,16 @@ var issueListCmd = &cobra.Command{

func init() {
issueListCmd.Flags().StringSliceVarP(
&issueLabels, "label", "l", []string{}, "Filter issues by label")
&issueLabels, "label", "l", []string{},
"Filter issues by label")
issueListCmd.Flags().StringVarP(
&issueState, "state", "s", "opened",
"Filter issues by state (opened/closed)")
issueListCmd.Flags().IntVarP(
&issueNumRet, "number", "n", 10,
"Number of issues to return")
issueListCmd.Flags().BoolVarP(&issueAll, "all", "a", false, "List all issues on the project")
issueListCmd.Flags().BoolVarP(
&issueAll, "all", "a", false,
"List all issues on the project")
issueCmd.AddCommand(issueListCmd)
}
17 changes: 17 additions & 0 deletions cmd/issue_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,20 @@ func Test_issueListStateClosed(t *testing.T) {
t.Log(issues)
require.Contains(t, issues, "#4 test closed issue")
}

func Test_issueListSearch(t *testing.T) {
t.Parallel()
repo := copyTestRepo(t)
cmd := exec.Command("../lab_bin", "issue", "list", "filter labels")
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, "#3 test filter labels 1")
require.NotContains(t, issues, "#1 test issue for lab list")
}
53 changes: 53 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ func init() {
// parseArgsStr returns a string and a number if parsed. Many commands accept a
// string to operate on (remote or search) and number such as a page id
func parseArgsStr(args []string) (string, int64, error) {
return parseArgsStringInt(args)
}

// parseArgsStringInt returns a string and a number if parsed.
func parseArgsStringInt(args []string) (string, int64, error) {
if len(args) == 2 {
n, err := strconv.ParseInt(args[1], 0, 64)
if err != nil {
Expand All @@ -127,7 +132,14 @@ func parseArgsStr(args []string) (string, int64, error) {
return "", 0, nil
}

// parseArgs returns a remote name and a number if parsed
func parseArgs(args []string) (string, int64, error) {
return parseArgsRemoteInt(args)
}

// parseArgsRemoteInt is similar to parseArgsStringInt except that it uses the
// string argument as a remote and returns the project name for that remote
func parseArgsRemoteInt(args []string) (string, int64, error) {
if !git.InsideGitRepo() {
return "", 0, nil
}
Expand Down Expand Up @@ -156,6 +168,47 @@ func parseArgs(args []string) (string, int64, error) {
return rn, num, nil
}

// parseArgsRemoteString returns a remote name and a string if parsed.
// If there is an error, it returns two empty strings.
// If no remote is given, it returns the project name of the default remote
// (ie 'origin').
// If no second argument is given, it returns "" as second return value.
func parseArgsRemoteString(args []string) (string, string, error) {
if !git.InsideGitRepo() {
return "", "", nil
}

remote, str := forkedFromRemote, ""

if len(args) == 1 {
ok, err := git.IsRemote(args[0])
if err != nil {
return "", "", err
}
if ok {
remote = args[0]
} else {
str = args[0]
}
} else if len(args) > 1 {
remote, str = args[0], args[1]
}

ok, err := git.IsRemote(remote)
if err != nil {
return "", "", err
}
if !ok {
return "", "", errors.Errorf("%s is not a valid remote", remote)
}

remote, err = git.PathWithNameSpace(remote)
if err != nil {
return "", "", err
}
return remote, str, nil
}

var (
// Will be updated to upstream in Execute() if "upstream" remote exists
forkedFromRemote = "origin"
Expand Down
65 changes: 65 additions & 0 deletions cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,68 @@ func Test_parseArgs(t *testing.T) {
})
}
}

func Test_parseArgsRemoteString(t *testing.T) {
tests := []struct {
Name string
Args []string
ExpectedRemote string
ExpectedString string
ExpectedErr string
}{
{
Name: "No Args",
Args: nil,
ExpectedRemote: "zaquestion/test",
ExpectedString: "",
ExpectedErr: "",
},
{
Name: "1 arg remote",
Args: []string{"lab-testing"},
ExpectedRemote: "lab-testing/test",
ExpectedString: "",
ExpectedErr: "",
},
{
Name: "1 arg non remote",
Args: []string{"foo123"},
ExpectedRemote: "zaquestion/test",
ExpectedString: "foo123",
ExpectedErr: "",
},
{
Name: "1 arg page",
Args: []string{"100"},
ExpectedRemote: "zaquestion/test",
ExpectedString: "100",
ExpectedErr: "",
},
{
Name: "2 arg remote and string",
Args: []string{"origin", "foo123"},
ExpectedRemote: "zaquestion/test",
ExpectedString: "foo123",
ExpectedErr: "",
},
{
Name: "2 arg invalid remote and string",
Args: []string{"foo", "string123"},
ExpectedRemote: "",
ExpectedString: "",
ExpectedErr: "foo is not a valid remote",
},
}
for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
test := test
t.Parallel()
r, s, err := parseArgsRemoteString(test.Args)
if err != nil {
assert.EqualError(t, err, test.ExpectedErr)
}
assert.Equal(t, test.ExpectedRemote, r)
assert.Equal(t, test.ExpectedString, s)
})
}
}