Skip to content

Commit c894c65

Browse files
author
Ismar Iljazovic
committed
feat: add --board parameter to sprint list (from PR ankitpokhrel#899)
Cherry-picked from andreadecorte/add_board_param Original author: Andrea Decorte
1 parent 3e91678 commit c894c65

File tree

4 files changed

+123
-23
lines changed

4 files changed

+123
-23
lines changed

internal/cmd/sprint/list/list.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func SetFlags(cmd *cobra.Command) {
7272
func sprintList(cmd *cobra.Command, args []string) {
7373
server := viper.GetString("server")
7474
project := viper.GetString("project.key")
75-
boardID := viper.GetInt("board.id")
75+
boardID := getBoardID(cmd)
7676

7777
debug, err := cmd.Flags().GetBool("debug")
7878
cmdutil.ExitIfError(err)
@@ -203,6 +203,8 @@ func sprintExplorerView(sprintQuery *query.Sprint, flags query.FlagParser, board
203203
return
204204
}
205205

206+
boardName := getBoardName(client, boardID)
207+
206208
if sprintQuery.Params().Current || sprintQuery.Params().Prev || sprintQuery.Params().Next {
207209
sprint := sprints[0]
208210
if sprintQuery.Params().Next {
@@ -235,7 +237,7 @@ func sprintExplorerView(sprintQuery *query.Sprint, flags query.FlagParser, board
235237

236238
v := view.SprintList{
237239
Project: project,
238-
Board: viper.GetString("board.name"),
240+
Board: boardName,
239241
Server: server,
240242
Data: sprints,
241243
Issues: func(boardID, sprintID int) []*jira.Issue {
@@ -289,6 +291,7 @@ func getIssueQuery(project string, flags query.FlagParser, showAll bool) (string
289291
}
290292

291293
func setFlags(cmd *cobra.Command) {
294+
cmd.Flags().String("board", "", "Board ID to use (overrides board.id from config)")
292295
cmd.Flags().String("state", "", "Filter sprint by its state (comma separated).\n"+
293296
"Valid values are future, active and closed.\n"+
294297
`Defaults to "active,closed"`)
@@ -303,6 +306,32 @@ func setFlags(cmd *cobra.Command) {
303306
cmd.Flags().Bool("next", false, "List issues in next planned sprint")
304307
}
305308

309+
func getBoardID(cmd *cobra.Command) int {
310+
boardFlag, err := cmd.Flags().GetString("board")
311+
cmdutil.ExitIfError(err)
312+
313+
if boardFlag != "" {
314+
boardID, err := strconv.Atoi(boardFlag)
315+
cmdutil.ExitIfError(err)
316+
return boardID
317+
}
318+
319+
return viper.GetInt("board.id")
320+
}
321+
322+
func getBoardName(client *jira.Client, boardID int) string {
323+
if boardID == 0 {
324+
return viper.GetString("board.name")
325+
}
326+
327+
board, err := client.BoardByID(boardID)
328+
if err != nil {
329+
return viper.GetString("board.name")
330+
}
331+
332+
return board.Name
333+
}
334+
306335
func hideFlags(cmd *cobra.Command) {
307336
cmdutil.ExitIfError(cmd.Flags().MarkHidden("history"))
308337
cmdutil.ExitIfError(cmd.Flags().MarkHidden("watching"))

pkg/jira/board.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,30 @@ func (c *Client) BoardSearch(project, name string) (*BoardResult, error) {
3838
return c.board(path)
3939
}
4040

41+
// BoardByID fetches a single board by its ID.
42+
func (c *Client) BoardByID(boardID int) (*Board, error) {
43+
path := fmt.Sprintf("/board/%d", boardID)
44+
45+
res, err := c.GetV1(context.Background(), path, nil)
46+
if err != nil {
47+
return nil, err
48+
}
49+
if res == nil {
50+
return nil, ErrEmptyResponse
51+
}
52+
defer func() { _ = res.Body.Close() }()
53+
54+
if res.StatusCode != http.StatusOK {
55+
return nil, formatUnexpectedResponse(res)
56+
}
57+
58+
var out Board
59+
60+
err = json.NewDecoder(res.Body).Decode(&out)
61+
62+
return &out, err
63+
}
64+
4165
func (c *Client) board(path string) (*BoardResult, error) {
4266
res, err := c.GetV1(context.Background(), path, nil)
4367
if err != nil {

pkg/jira/board_test.go

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,37 +13,47 @@ import (
1313

1414
func TestBoards(t *testing.T) {
1515
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
16-
assert.Equal(t, "/rest/agile/1.0/board", r.URL.Path)
16+
switch r.URL.Path {
17+
case "/rest/agile/1.0/board":
18+
qs := r.URL.Query()
1719

18-
qs := r.URL.Query()
20+
switch qs.Get("projectKeyOrId") {
21+
case "BAD":
22+
w.WriteHeader(400)
23+
case "TEST":
24+
assert.Equal(t, url.Values{
25+
"projectKeyOrId": []string{"TEST"},
26+
"type": []string{"scrum"},
27+
}, qs)
1928

20-
switch qs.Get("projectKeyOrId") {
21-
case "BAD":
22-
w.WriteHeader(400)
23-
case "TEST":
24-
assert.Equal(t, url.Values{
25-
"projectKeyOrId": []string{"TEST"},
26-
"type": []string{"scrum"},
27-
}, qs)
29+
resp, err := os.ReadFile("./testdata/boards.json")
30+
assert.NoError(t, err)
2831

29-
resp, err := os.ReadFile("./testdata/boards.json")
30-
assert.NoError(t, err)
32+
w.Header().Set("Content-Type", "application/json")
33+
w.WriteHeader(200)
34+
_, _ = w.Write(resp)
35+
case "SEARCH":
36+
assert.Equal(t, url.Values{
37+
"projectKeyOrId": []string{"SEARCH"},
38+
"name": []string{"board"},
39+
}, qs)
3140

32-
w.Header().Set("Content-Type", "application/json")
33-
w.WriteHeader(200)
34-
_, _ = w.Write(resp)
35-
case "SEARCH":
36-
assert.Equal(t, url.Values{
37-
"projectKeyOrId": []string{"SEARCH"},
38-
"name": []string{"board"},
39-
}, qs)
41+
resp, err := os.ReadFile("./testdata/boards.json")
42+
assert.NoError(t, err)
4043

41-
resp, err := os.ReadFile("./testdata/boards.json")
44+
w.Header().Set("Content-Type", "application/json")
45+
w.WriteHeader(200)
46+
_, _ = w.Write(resp)
47+
}
48+
case "/rest/agile/1.0/board/1":
49+
resp, err := os.ReadFile("./testdata/board.json")
4250
assert.NoError(t, err)
4351

4452
w.Header().Set("Content-Type", "application/json")
4553
w.WriteHeader(200)
4654
_, _ = w.Write(resp)
55+
case "/rest/agile/1.0/board/999":
56+
w.WriteHeader(404)
4757
}
4858
}))
4959
defer server.Close()
@@ -81,3 +91,35 @@ func TestBoards(t *testing.T) {
8191
assert.NoError(t, err)
8292
assert.Equal(t, expected, actual)
8393
}
94+
95+
func TestBoardByID(t *testing.T) {
96+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
97+
switch r.URL.Path {
98+
case "/rest/agile/1.0/board/1":
99+
resp, err := os.ReadFile("./testdata/board.json")
100+
assert.NoError(t, err)
101+
102+
w.Header().Set("Content-Type", "application/json")
103+
w.WriteHeader(200)
104+
_, _ = w.Write(resp)
105+
case "/rest/agile/1.0/board/999":
106+
w.WriteHeader(404)
107+
}
108+
}))
109+
defer server.Close()
110+
111+
client := NewClient(Config{Server: server.URL}, WithTimeout(3*time.Second))
112+
113+
actual, err := client.BoardByID(1)
114+
assert.NoError(t, err)
115+
116+
expected := &Board{
117+
ID: 1,
118+
Name: "Board 1",
119+
Type: "scrum",
120+
}
121+
assert.Equal(t, expected, actual)
122+
123+
_, err = client.BoardByID(999)
124+
assert.Error(t, &ErrUnexpectedResponse{}, err)
125+
}

pkg/jira/testdata/board.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"id": 1,
3+
"name": "Board 1",
4+
"type": "scrum"
5+
}

0 commit comments

Comments
 (0)