Skip to content

Commit 6085aee

Browse files
feat: Filter by multiple statuses (#573)
Co-authored-by: Chmouel Boudjnah <[email protected]>
1 parent 7bae0d6 commit 6085aee

File tree

3 files changed

+69
-24
lines changed

3 files changed

+69
-24
lines changed

internal/cmd/issue/list/list.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ func SetFlags(cmd *cobra.Command) {
154154

155155
cmd.Flags().StringP("type", "t", "", "Filter issues by type")
156156
cmd.Flags().StringP("resolution", "R", "", "Filter issues by resolution type")
157-
cmd.Flags().StringP("status", "s", "", "Filter issues by status")
157+
cmd.Flags().StringArrayP("status", "s", []string{}, "Filter issues by status")
158158
cmd.Flags().StringP("priority", "y", "", "Filter issues by priority")
159159
cmd.Flags().StringP("reporter", "r", "", "Filter issues by reporter (email or display name)")
160160
cmd.Flags().StringP("assignee", "a", "", "Filter issues by assignee (email or display name)")

internal/query/issue.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ func (i *Issue) Get() string {
7777

7878
q.FilterBy("type", i.params.IssueType).
7979
FilterBy("resolution", i.params.Resolution).
80-
FilterBy("status", i.params.Status).
8180
FilterBy("priority", i.params.Priority).
8281
FilterBy("reporter", i.params.Reporter).
8382
FilterBy("assignee", i.params.Assignee).
@@ -95,6 +94,15 @@ func (i *Issue) Get() string {
9594
if len(negative) > 0 {
9695
q.NotIn("labels", negative...)
9796
}
97+
98+
positive, negative = splitPositiveNegative(i.params.Status)
99+
if len(positive) > 0 {
100+
q.In("status", positive...)
101+
}
102+
103+
if len(negative) > 0 {
104+
q.NotIn("status", negative...)
105+
}
98106
})
99107

100108
if i.params.Reverse {
@@ -164,7 +172,7 @@ type IssueParams struct {
164172
Resolution string
165173
IssueType string
166174
Parent string
167-
Status string
175+
Status []string
168176
Priority string
169177
Reporter string
170178
Assignee string
@@ -190,7 +198,7 @@ func (ip *IssueParams) init(flags FlagParser) error {
190198

191199
boolParams := []string{"history", "watching", "reverse", "debug"}
192200
stringParams := []string{
193-
"resolution", "type", "parent", "status", "priority", "reporter", "assignee", "component",
201+
"resolution", "type", "parent", "priority", "reporter", "assignee", "component",
194202
"created", "created-after", "created-before", "updated", "updated-after", "updated-before",
195203
"jql", "order-by", "paginate",
196204
}
@@ -213,6 +221,12 @@ func (ip *IssueParams) init(flags FlagParser) error {
213221
if err != nil {
214222
return err
215223
}
224+
225+
status, err := flags.GetStringArray("status")
226+
if err != nil {
227+
return err
228+
}
229+
216230
paginate, err := flags.GetString("paginate")
217231
if err != nil {
218232
return err
@@ -225,6 +239,7 @@ func (ip *IssueParams) init(flags FlagParser) error {
225239
ip.setBoolParams(boolParamsMap)
226240
ip.setStringParams(stringParamsMap)
227241
ip.Labels = labels
242+
ip.Status = status
228243
ip.From = from
229244
ip.Limit = limit
230245

@@ -255,8 +270,6 @@ func (ip *IssueParams) setStringParams(paramsMap map[string]string) {
255270
ip.IssueType = v
256271
case "parent":
257272
ip.Parent = v
258-
case "status":
259-
ip.Status = v
260273
case "priority":
261274
ip.Priority = v
262275
case "reporter":

internal/query/issue_test.go

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type issueParamsErr struct {
1414
resolution bool
1515
issueType bool
1616
labels bool
17+
status bool
1718
}
1819

1920
type issueFlagParser struct {
@@ -23,6 +24,7 @@ type issueFlagParser struct {
2324
orderDesc bool
2425
emptyType bool
2526
labels []string
27+
status []string
2628
withCreated bool
2729
withUpdated bool
2830
created string
@@ -109,6 +111,12 @@ func (tfp *issueFlagParser) GetStringArray(name string) ([]string, error) {
109111
if tfp.err.labels && name == "label" {
110112
return []string{}, fmt.Errorf("oops! couldn't fetch label flag")
111113
}
114+
if tfp.err.status && name == "status" {
115+
return []string{}, fmt.Errorf("oops! couldn't fetch status flag")
116+
}
117+
if name == "status" {
118+
return tfp.status, nil
119+
}
112120
return tfp.labels, nil
113121
}
114122

@@ -117,6 +125,8 @@ func (*issueFlagParser) GetUint(string) (uint, error) { r
117125
func (*issueFlagParser) Set(string, string) error { return nil }
118126

119127
func TestIssueGet(t *testing.T) {
128+
t.Parallel()
129+
120130
cases := []struct {
121131
name string
122132
initialize func() *Issue
@@ -130,7 +140,7 @@ func TestIssueGet(t *testing.T) {
130140
return i
131141
},
132142
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
133-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" ` +
143+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" ` +
134144
`AND assignee="test" AND component="test" AND parent="test" ORDER BY lastViewed ASC`,
135145
},
136146
{
@@ -141,7 +151,7 @@ func TestIssueGet(t *testing.T) {
141151
return i
142152
},
143153
expected: `project="TEST" AND issue IN watchedIssues() AND ` +
144-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" ` +
154+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" ` +
145155
`AND assignee="test" AND component="test" AND parent="test" ORDER BY created ASC`,
146156
},
147157
{
@@ -152,7 +162,7 @@ func TestIssueGet(t *testing.T) {
152162
return i
153163
},
154164
expected: `project="TEST" AND ` +
155-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" ` +
165+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" ` +
156166
`AND assignee="test" AND component="test" AND parent="test" ORDER BY created ASC`,
157167
},
158168
{
@@ -199,6 +209,17 @@ func TestIssueGet(t *testing.T) {
199209
},
200210
expected: "",
201211
},
212+
{
213+
name: "query with error when fetching status flag",
214+
initialize: func() *Issue {
215+
i, err := NewIssue("TEST", &issueFlagParser{err: issueParamsErr{
216+
status: true,
217+
}})
218+
assert.Error(t, err)
219+
return i
220+
},
221+
expected: "",
222+
},
202223
{
203224
name: "query with error when fetching type flag",
204225
initialize: func() *Issue {
@@ -218,7 +239,7 @@ func TestIssueGet(t *testing.T) {
218239
return i
219240
},
220241
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
221-
`resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
242+
`resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
222243
`AND component="test" AND parent="test" ORDER BY lastViewed ASC`,
223244
},
224245
{
@@ -229,7 +250,7 @@ func TestIssueGet(t *testing.T) {
229250
return i
230251
},
231252
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
232-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" ` +
253+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" ` +
233254
`AND assignee="test" AND component="test" AND parent="test" ORDER BY lastViewed DESC`,
234255
},
235256
{
@@ -240,9 +261,20 @@ func TestIssueGet(t *testing.T) {
240261
return i
241262
},
242263
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
243-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
264+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
244265
`AND component="test" AND parent="test" AND labels IN ("first", "second", "third") ORDER BY lastViewed ASC`,
245266
},
267+
{
268+
name: "query with status",
269+
initialize: func() *Issue {
270+
i, err := NewIssue("TEST", &issueFlagParser{status: []string{"first", "second", "~third"}})
271+
assert.NoError(t, err)
272+
return i
273+
},
274+
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
275+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
276+
`AND component="test" AND parent="test" AND status IN ("first", "second") AND status NOT IN ("third") ORDER BY lastViewed ASC`,
277+
},
246278
{
247279
name: "query with created and updated today filter",
248280
initialize: func() *Issue {
@@ -251,7 +283,7 @@ func TestIssueGet(t *testing.T) {
251283
return i
252284
},
253285
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
254-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
286+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
255287
`AND component="test" AND parent="test" AND createdDate>=startOfDay() AND updatedDate>=startOfDay() ORDER BY lastViewed ASC`,
256288
},
257289
{
@@ -262,7 +294,7 @@ func TestIssueGet(t *testing.T) {
262294
return i
263295
},
264296
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
265-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
297+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
266298
`AND component="test" AND parent="test" AND createdDate>=startOfWeek() AND updatedDate>=startOfWeek() ORDER BY lastViewed ASC`,
267299
},
268300
{
@@ -273,7 +305,7 @@ func TestIssueGet(t *testing.T) {
273305
return i
274306
},
275307
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
276-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
308+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
277309
`AND component="test" AND parent="test" AND createdDate>=startOfMonth() AND updatedDate>=startOfMonth() ORDER BY lastViewed ASC`,
278310
},
279311
{
@@ -284,7 +316,7 @@ func TestIssueGet(t *testing.T) {
284316
return i
285317
},
286318
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
287-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
319+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
288320
`AND component="test" AND parent="test" AND createdDate>=startOfYear() AND updatedDate>=startOfYear() ORDER BY lastViewed ASC`,
289321
},
290322
{
@@ -295,7 +327,7 @@ func TestIssueGet(t *testing.T) {
295327
return i
296328
},
297329
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
298-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" AND component="test" ` +
330+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" AND component="test" ` +
299331
`AND parent="test" AND createdDate>="2020-12-31" AND createdDate<"2021-01-01" AND updatedDate>="2020-12-31" AND updatedDate<"2021-01-01" ` +
300332
`ORDER BY lastViewed ASC`,
301333
},
@@ -307,7 +339,7 @@ func TestIssueGet(t *testing.T) {
307339
return i
308340
},
309341
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
310-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
342+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
311343
`AND component="test" AND parent="test" AND createdDate>="2020-15-31" AND updatedDate>="2020-12-31 10:30:30" ORDER BY lastViewed ASC`,
312344
},
313345
{
@@ -318,7 +350,7 @@ func TestIssueGet(t *testing.T) {
318350
return i
319351
},
320352
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
321-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
353+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
322354
`AND component="test" AND parent="test" AND createdDate>"2020-12-01" AND createdDate<"2020-12-31" ORDER BY lastViewed ASC`,
323355
},
324356
{
@@ -329,7 +361,7 @@ func TestIssueGet(t *testing.T) {
329361
return i
330362
},
331363
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
332-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
364+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
333365
`AND component="test" AND parent="test" AND updatedDate>"2020-12-01" AND updatedDate<"2020-12-31" ORDER BY lastViewed ASC`,
334366
},
335367
{
@@ -347,7 +379,7 @@ func TestIssueGet(t *testing.T) {
347379
return i
348380
},
349381
expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
350-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
382+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
351383
`AND component="test" AND parent="test" AND createdDate>="2020-11-01" AND createdDate<"2020-11-02" AND updatedDate>="-10d" ` +
352384
`ORDER BY lastViewed ASC`,
353385
},
@@ -367,7 +399,7 @@ func TestIssueGet(t *testing.T) {
367399
return i
368400
},
369401
expected: `project="TEST" AND issue IN watchedIssues() AND type="test" AND resolution="test" ` +
370-
`AND status="test" AND priority="test" AND reporter="test" AND assignee="test" AND component="test" ` +
402+
`AND priority="test" AND reporter="test" AND assignee="test" AND component="test" ` +
371403
`AND parent="test" AND createdDate>="2020-11-01" AND createdDate<"2020-11-02" AND updatedDate>="-10d" ` +
372404
`ORDER BY created ASC`,
373405
},
@@ -385,7 +417,7 @@ func TestIssueGet(t *testing.T) {
385417
return i
386418
},
387419
expected: `project="TEST" AND issue IN watchedIssues() AND type="test" AND resolution="test" ` +
388-
`AND status="test" AND priority="test" AND reporter="test" AND assignee="test" AND component="test" ` +
420+
`AND priority="test" AND reporter="test" AND assignee="test" AND component="test" ` +
389421
`AND parent="test" AND updatedDate>"2020-11-31" AND updatedDate<"2020-12-31" ` +
390422
`ORDER BY updated ASC`,
391423
},
@@ -397,7 +429,7 @@ func TestIssueGet(t *testing.T) {
397429
return i
398430
},
399431
expected: `project="TEST" AND summary ~ cli OR x = y AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
400-
`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" ` +
432+
`type="test" AND resolution="test" AND priority="test" AND reporter="test" ` +
401433
`AND assignee="test" AND component="test" AND parent="test" ORDER BY lastViewed ASC`,
402434
},
403435
}

0 commit comments

Comments
 (0)