fizzy-cli 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0 - 2026-01-25
4
+
5
+ ### Features
6
+
7
+ #### Comment Management
8
+
9
+ - `fizzy comment list <card_number>` - List all comments on a card
10
+ - `fizzy comment show <card_number> <comment_id>` - Display a specific comment
11
+ - `fizzy comment add <card_number> <body>` - Create a new comment on a card
12
+
13
+ ### Fixes
14
+
15
+ - Fixed error handling in notification read-all command
16
+ - Removed global flag usage in some commands
17
+
3
18
  ## 0.4.0 - 2026-01-19
4
19
 
5
20
  ### Features
@@ -9,13 +9,6 @@ import (
9
9
  "github.com/spf13/cobra"
10
10
  )
11
11
 
12
- var (
13
- boardName string
14
- boardAllAccess bool
15
- boardAutoPostponePeriod int
16
- boardPublicDescription string
17
- )
18
-
19
12
  var boardCreateCmd = &cobra.Command{
20
13
  Use: "create",
21
14
  Short: "Create a new board",
@@ -33,11 +26,17 @@ func handleCreateBoard(cmd *cobra.Command) error {
33
26
  return fmt.Errorf("API client not available")
34
27
  }
35
28
 
29
+ // Read flag values directly from command
30
+ name, _ := cmd.Flags().GetString("name")
31
+ allAccess, _ := cmd.Flags().GetBool("all-access")
32
+ autoPostponePeriod, _ := cmd.Flags().GetInt("auto-postpone-period")
33
+ publicDescription, _ := cmd.Flags().GetString("description")
34
+
36
35
  payload := api.CreateBoardPayload{
37
- Name: boardName,
38
- AllAccess: boardAllAccess,
39
- AutoPostponePeriod: boardAutoPostponePeriod,
40
- PublicDescription: boardPublicDescription,
36
+ Name: name,
37
+ AllAccess: allAccess,
38
+ AutoPostponePeriod: autoPostponePeriod,
39
+ PublicDescription: publicDescription,
41
40
  }
42
41
 
43
42
  _, err := a.Client.PostBoards(context.Background(), payload)
@@ -45,16 +44,16 @@ func handleCreateBoard(cmd *cobra.Command) error {
45
44
  return fmt.Errorf("creating board: %w", err)
46
45
  }
47
46
 
48
- fmt.Printf("✓ Board '%s' created successfully\n", boardName)
47
+ fmt.Printf("✓ Board '%s' created successfully\n", name)
49
48
  return nil
50
49
  }
51
50
 
52
51
  func init() {
53
- boardCreateCmd.Flags().StringVarP(&boardName, "name", "n", "", "Board name (required)")
52
+ boardCreateCmd.Flags().StringP("name", "n", "", "Board name (required)")
54
53
  boardCreateCmd.MarkFlagRequired("name")
55
- boardCreateCmd.Flags().BoolVar(&boardAllAccess, "all-access", false, "Allow all access to the board")
56
- boardCreateCmd.Flags().IntVar(&boardAutoPostponePeriod, "auto-postpone-period", 0, "Auto postpone period in days")
57
- boardCreateCmd.Flags().StringVar(&boardPublicDescription, "description", "", "Public description of the board")
54
+ boardCreateCmd.Flags().Bool("all-access", false, "Allow all access to the board")
55
+ boardCreateCmd.Flags().Int("auto-postpone-period", 0, "Auto postpone period in days")
56
+ boardCreateCmd.Flags().String("description", "", "Public description of the board")
58
57
 
59
58
  boardCmd.AddCommand(boardCreateCmd)
60
59
  }
@@ -54,11 +54,6 @@ func TestBoardCreateCommandSuccess(t *testing.T) {
54
54
  cmd.SetContext(testApp.ToContext(context.Background()))
55
55
  cmd.ParseFlags([]string{"--name", "Test Board"})
56
56
 
57
- boardName = "Test Board"
58
- boardAllAccess = false
59
- boardAutoPostponePeriod = 0
60
- boardPublicDescription = ""
61
-
62
57
  if err := handleCreateBoard(cmd); err != nil {
63
58
  t.Fatalf("handleCreateBoard failed: %v", err)
64
59
  }
@@ -101,11 +96,6 @@ func TestBoardCreateCommandWithAllFlags(t *testing.T) {
101
96
  "--description", "Team project",
102
97
  })
103
98
 
104
- boardName = "Test Board"
105
- boardAllAccess = true
106
- boardAutoPostponePeriod = 7
107
- boardPublicDescription = "Team project"
108
-
109
99
  if err := handleCreateBoard(cmd); err != nil {
110
100
  t.Fatalf("handleCreateBoard failed: %v", err)
111
101
  }
@@ -125,11 +115,6 @@ func TestBoardCreateCommandAPIError(t *testing.T) {
125
115
  cmd.SetContext(testApp.ToContext(context.Background()))
126
116
  cmd.ParseFlags([]string{"--name", "Test Board"})
127
117
 
128
- boardName = "Test Board"
129
- boardAllAccess = false
130
- boardAutoPostponePeriod = 0
131
- boardPublicDescription = ""
132
-
133
118
  err := handleCreateBoard(cmd)
134
119
  if err == nil {
135
120
  t.Errorf("expected error for API failure")
@@ -146,8 +131,6 @@ func TestBoardCreateCommandNoClient(t *testing.T) {
146
131
  cmd.SetContext(testApp.ToContext(context.Background()))
147
132
  cmd.ParseFlags([]string{"--name", "Test Board"})
148
133
 
149
- boardName = "Test Board"
150
-
151
134
  err := handleCreateBoard(cmd)
152
135
  if err == nil {
153
136
  t.Errorf("expected error when client not available")
@@ -9,16 +9,6 @@ import (
9
9
  "github.com/spf13/cobra"
10
10
  )
11
11
 
12
- var (
13
- cardTitle string
14
- cardDescription string
15
- cardStatus string
16
- cardImageURL string
17
- cardTagIDs []string
18
- cardCreatedAt string
19
- cardLastActiveAt string
20
- )
21
-
22
12
  var cardCreateCmd = &cobra.Command{
23
13
  Use: "create",
24
14
  Short: "Create a new card",
@@ -40,14 +30,23 @@ func handleCreateCard(cmd *cobra.Command) error {
40
30
  return fmt.Errorf("no board selected")
41
31
  }
42
32
 
33
+ // Read flag values directly from command
34
+ title, _ := cmd.Flags().GetString("title")
35
+ description, _ := cmd.Flags().GetString("description")
36
+ status, _ := cmd.Flags().GetString("status")
37
+ imageURL, _ := cmd.Flags().GetString("image-url")
38
+ tagIDs, _ := cmd.Flags().GetStringSlice("tag-id")
39
+ createdAt, _ := cmd.Flags().GetString("created-at")
40
+ lastActiveAt, _ := cmd.Flags().GetString("last-active-at")
41
+
43
42
  payload := api.CreateCardPayload{
44
- Title: cardTitle,
45
- Description: cardDescription,
46
- Status: cardStatus,
47
- ImageURL: cardImageURL,
48
- TagIDS: cardTagIDs,
49
- CreatedAt: cardCreatedAt,
50
- LastActiveAt: cardLastActiveAt,
43
+ Title: title,
44
+ Description: description,
45
+ Status: status,
46
+ ImageURL: imageURL,
47
+ TagIDS: tagIDs,
48
+ CreatedAt: createdAt,
49
+ LastActiveAt: lastActiveAt,
51
50
  }
52
51
 
53
52
  _, err := a.Client.PostCards(context.Background(), payload)
@@ -55,19 +54,19 @@ func handleCreateCard(cmd *cobra.Command) error {
55
54
  return fmt.Errorf("creating card: %w", err)
56
55
  }
57
56
 
58
- fmt.Printf("✓ Card '%s' created successfully\n", cardTitle)
57
+ fmt.Printf("✓ Card '%s' created successfully\n", title)
59
58
  return nil
60
59
  }
61
60
 
62
61
  func init() {
63
- cardCreateCmd.Flags().StringVarP(&cardTitle, "title", "t", "", "Card title (required)")
62
+ cardCreateCmd.Flags().StringP("title", "t", "", "Card title (required)")
64
63
  cardCreateCmd.MarkFlagRequired("title")
65
- cardCreateCmd.Flags().StringVarP(&cardDescription, "description", "d", "", "Card description")
66
- cardCreateCmd.Flags().StringVar(&cardStatus, "status", "", "Card status")
67
- cardCreateCmd.Flags().StringVar(&cardImageURL, "image-url", "", "Card image URL")
68
- cardCreateCmd.Flags().StringSliceVar(&cardTagIDs, "tag-id", []string{}, "Tag ID (can be used multiple times)")
69
- cardCreateCmd.Flags().StringVar(&cardCreatedAt, "created-at", "", "Creation timestamp")
70
- cardCreateCmd.Flags().StringVar(&cardLastActiveAt, "last-active-at", "", "Last active timestamp")
64
+ cardCreateCmd.Flags().StringP("description", "d", "", "Card description")
65
+ cardCreateCmd.Flags().String("status", "", "Card status")
66
+ cardCreateCmd.Flags().String("image-url", "", "Card image URL")
67
+ cardCreateCmd.Flags().StringSlice("tag-id", []string{}, "Tag ID (can be used multiple times)")
68
+ cardCreateCmd.Flags().String("created-at", "", "Creation timestamp")
69
+ cardCreateCmd.Flags().String("last-active-at", "", "Last active timestamp")
71
70
 
72
71
  cardCmd.AddCommand(cardCreateCmd)
73
72
  }
@@ -58,14 +58,10 @@ func TestCardCreateCommandSuccess(t *testing.T) {
58
58
 
59
59
  cmd := cardCreateCmd
60
60
  cmd.SetContext(testApp.ToContext(context.Background()))
61
-
62
- cardTitle = "Implement feature"
63
- cardDescription = "A detailed description"
64
- cardStatus = ""
65
- cardImageURL = ""
66
- cardTagIDs = []string{}
67
- cardCreatedAt = ""
68
- cardLastActiveAt = ""
61
+ cmd.ParseFlags([]string{
62
+ "--title", "Implement feature",
63
+ "--description", "A detailed description",
64
+ })
69
65
 
70
66
  if err := handleCreateCard(cmd); err != nil {
71
67
  t.Fatalf("handleCreateCard failed: %v", err)
@@ -108,14 +104,13 @@ func TestCardCreateCommandWithAllFields(t *testing.T) {
108
104
 
109
105
  cmd := cardCreateCmd
110
106
  cmd.SetContext(testApp.ToContext(context.Background()))
111
-
112
- cardTitle = "Fix bug"
113
- cardDescription = ""
114
- cardStatus = "in_progress"
115
- cardImageURL = "https://example.com/image.jpg"
116
- cardTagIDs = []string{"tag-1", "tag-2"}
117
- cardCreatedAt = ""
118
- cardLastActiveAt = ""
107
+ cmd.ParseFlags([]string{
108
+ "--title", "Fix bug",
109
+ "--status", "in_progress",
110
+ "--image-url", "https://example.com/image.jpg",
111
+ "--tag-id", "tag-1",
112
+ "--tag-id", "tag-2",
113
+ })
119
114
 
120
115
  if err := handleCreateCard(cmd); err != nil {
121
116
  t.Fatalf("handleCreateCard failed: %v", err)
@@ -131,14 +126,9 @@ func TestCardCreateCommandNoBoard(t *testing.T) {
131
126
 
132
127
  cmd := cardCreateCmd
133
128
  cmd.SetContext(testApp.ToContext(context.Background()))
134
-
135
- cardTitle = "Test"
136
- cardDescription = ""
137
- cardStatus = ""
138
- cardImageURL = ""
139
- cardTagIDs = []string{}
140
- cardCreatedAt = ""
141
- cardLastActiveAt = ""
129
+ cmd.ParseFlags([]string{
130
+ "--title", "Test",
131
+ })
142
132
 
143
133
  err := handleCreateCard(cmd)
144
134
  if err == nil {
@@ -154,14 +144,9 @@ func TestCardCreateCommandNoClient(t *testing.T) {
154
144
 
155
145
  cmd := cardCreateCmd
156
146
  cmd.SetContext(testApp.ToContext(context.Background()))
157
-
158
- cardTitle = "Test"
159
- cardDescription = ""
160
- cardStatus = ""
161
- cardImageURL = ""
162
- cardTagIDs = []string{}
163
- cardCreatedAt = ""
164
- cardLastActiveAt = ""
147
+ cmd.ParseFlags([]string{
148
+ "--title", "Test",
149
+ })
165
150
 
166
151
  err := handleCreateCard(cmd)
167
152
  if err == nil {
@@ -187,14 +172,9 @@ func TestCardCreateCommandAPIError(t *testing.T) {
187
172
 
188
173
  cmd := cardCreateCmd
189
174
  cmd.SetContext(testApp.ToContext(context.Background()))
190
-
191
- cardTitle = "Test"
192
- cardDescription = ""
193
- cardStatus = ""
194
- cardImageURL = ""
195
- cardTagIDs = []string{}
196
- cardCreatedAt = ""
197
- cardLastActiveAt = ""
175
+ cmd.ParseFlags([]string{
176
+ "--title", "Test",
177
+ })
198
178
 
199
179
  err := handleCreateCard(cmd)
200
180
  if err == nil {
@@ -10,14 +10,6 @@ import (
10
10
  "github.com/spf13/cobra"
11
11
  )
12
12
 
13
- var (
14
- updateTitle string
15
- updateDescription string
16
- updateStatus string
17
- updateTagIDs []string
18
- updateLastActiveAt string
19
- )
20
-
21
13
  var cardUpdateCmd = &cobra.Command{
22
14
  Use: "update <card_number>",
23
15
  Short: "Update a card",
@@ -41,16 +33,23 @@ func handleUpdateCard(cmd *cobra.Command, cardNumber string) error {
41
33
  return fmt.Errorf("API client not available")
42
34
  }
43
35
 
44
- if updateTitle == "" && updateDescription == "" && updateStatus == "" && len(updateTagIDs) == 0 && updateLastActiveAt == "" {
36
+ // Read flag values directly from command
37
+ title, _ := cmd.Flags().GetString("title")
38
+ description, _ := cmd.Flags().GetString("description")
39
+ status, _ := cmd.Flags().GetString("status")
40
+ tagIDs, _ := cmd.Flags().GetStringSlice("tag-id")
41
+ lastActiveAt, _ := cmd.Flags().GetString("last-active-at")
42
+
43
+ if title == "" && description == "" && status == "" && len(tagIDs) == 0 && lastActiveAt == "" {
45
44
  return fmt.Errorf("must provide at least one flag to update (--title, --description, --status, --tag-id, or --last-active-at)")
46
45
  }
47
46
 
48
47
  payload := api.UpdateCardPayload{
49
- Title: updateTitle,
50
- Description: updateDescription,
51
- Status: updateStatus,
52
- TagIDS: updateTagIDs,
53
- LastActiveAt: updateLastActiveAt,
48
+ Title: title,
49
+ Description: description,
50
+ Status: status,
51
+ TagIDS: tagIDs,
52
+ LastActiveAt: lastActiveAt,
54
53
  }
55
54
 
56
55
  card, err := a.Client.PutCard(context.Background(), cardNum, payload)
@@ -63,11 +62,11 @@ func handleUpdateCard(cmd *cobra.Command, cardNumber string) error {
63
62
  }
64
63
 
65
64
  func init() {
66
- cardUpdateCmd.Flags().StringVarP(&updateTitle, "title", "t", "", "Card title")
67
- cardUpdateCmd.Flags().StringVarP(&updateDescription, "description", "d", "", "Card description")
68
- cardUpdateCmd.Flags().StringVar(&updateStatus, "status", "", "Card status")
69
- cardUpdateCmd.Flags().StringSliceVar(&updateTagIDs, "tag-id", []string{}, "Tag ID (can be used multiple times)")
70
- cardUpdateCmd.Flags().StringVar(&updateLastActiveAt, "last-active-at", "", "Last active timestamp")
65
+ cardUpdateCmd.Flags().StringP("title", "t", "", "Card title")
66
+ cardUpdateCmd.Flags().StringP("description", "d", "", "Card description")
67
+ cardUpdateCmd.Flags().String("status", "", "Card status")
68
+ cardUpdateCmd.Flags().StringSlice("tag-id", []string{}, "Tag ID (can be used multiple times)")
69
+ cardUpdateCmd.Flags().String("last-active-at", "", "Last active timestamp")
71
70
 
72
71
  cardCmd.AddCommand(cardUpdateCmd)
73
72
  }
@@ -10,6 +10,7 @@ import (
10
10
  "github.com/rogeriopvl/fizzy/internal/api"
11
11
  "github.com/rogeriopvl/fizzy/internal/app"
12
12
  "github.com/rogeriopvl/fizzy/internal/testutil"
13
+ "github.com/spf13/cobra"
13
14
  )
14
15
 
15
16
  func TestCardUpdateCommand(t *testing.T) {
@@ -48,11 +49,12 @@ func TestCardUpdateCommand(t *testing.T) {
48
49
 
49
50
  cmd := cardUpdateCmd
50
51
  cmd.SetContext(testApp.ToContext(context.Background()))
51
-
52
- updateTitle = "Updated card title"
53
- updateDescription = "Updated description"
54
- updateStatus = "published"
55
- updateTagIDs = []string{"updated-tag"}
52
+ cmd.ParseFlags([]string{
53
+ "--title", "Updated card title",
54
+ "--description", "Updated description",
55
+ "--status", "published",
56
+ "--tag-id", "updated-tag",
57
+ })
56
58
 
57
59
  if err := handleUpdateCard(cmd, "1"); err != nil {
58
60
  t.Fatalf("handleUpdateCard failed: %v", err)
@@ -71,8 +73,9 @@ func TestCardUpdateCommandAPIError(t *testing.T) {
71
73
 
72
74
  cmd := cardUpdateCmd
73
75
  cmd.SetContext(testApp.ToContext(context.Background()))
74
-
75
- updateTitle = "Updated card"
76
+ cmd.ParseFlags([]string{
77
+ "--title", "Updated card",
78
+ })
76
79
 
77
80
  err := handleUpdateCard(cmd, "999")
78
81
  if err == nil {
@@ -88,8 +91,9 @@ func TestCardUpdateCommandNoClient(t *testing.T) {
88
91
 
89
92
  cmd := cardUpdateCmd
90
93
  cmd.SetContext(testApp.ToContext(context.Background()))
91
-
92
- updateTitle = "Updated card"
94
+ cmd.ParseFlags([]string{
95
+ "--title", "Updated card",
96
+ })
93
97
 
94
98
  err := handleUpdateCard(cmd, "1")
95
99
  if err == nil {
@@ -105,8 +109,9 @@ func TestCardUpdateCommandInvalidCardNumber(t *testing.T) {
105
109
 
106
110
  cmd := cardUpdateCmd
107
111
  cmd.SetContext(testApp.ToContext(context.Background()))
108
-
109
- updateTitle = "Updated card"
112
+ cmd.ParseFlags([]string{
113
+ "--title", "Updated card",
114
+ })
110
115
 
111
116
  err := handleUpdateCard(cmd, "not-a-number")
112
117
  if err == nil {
@@ -118,22 +123,21 @@ func TestCardUpdateCommandInvalidCardNumber(t *testing.T) {
118
123
  }
119
124
 
120
125
  func TestCardUpdateCommandNoFlags(t *testing.T) {
121
- server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
122
- w.WriteHeader(http.StatusOK)
123
- }))
124
- defer server.Close()
125
-
126
- client := testutil.NewTestClient(server.URL, "", "", "test-token")
126
+ client := testutil.NewTestClient("http://localhost", "", "", "test-token")
127
127
  testApp := &app.App{Client: client}
128
128
 
129
- cmd := cardUpdateCmd
130
- cmd.SetContext(testApp.ToContext(context.Background()))
129
+ // Create a fresh command to avoid flag pollution from other tests
130
+ cmd := &cobra.Command{
131
+ Use: "update <card_number>",
132
+ Args: cobra.ExactArgs(1),
133
+ }
134
+ cmd.Flags().String("title", "", "Card title")
135
+ cmd.Flags().String("description", "", "Card description")
136
+ cmd.Flags().String("status", "", "Card status")
137
+ cmd.Flags().StringSlice("tag-id", []string{}, "Tag ID")
138
+ cmd.Flags().String("last-active-at", "", "Last active timestamp")
131
139
 
132
- updateTitle = ""
133
- updateDescription = ""
134
- updateStatus = ""
135
- updateTagIDs = []string{}
136
- updateLastActiveAt = ""
140
+ cmd.SetContext(testApp.ToContext(context.Background()))
137
141
 
138
142
  err := handleUpdateCard(cmd, "1")
139
143
  if err == nil {
@@ -11,11 +11,6 @@ import (
11
11
  "github.com/spf13/cobra"
12
12
  )
13
13
 
14
- var (
15
- columnName string
16
- columnColor string
17
- )
18
-
19
14
  func buildColorAliases() map[string]api.Color {
20
15
  aliases := make(map[string]api.Color)
21
16
  for _, colorDef := range colors.All {
@@ -49,15 +44,19 @@ func handleCreateColumn(cmd *cobra.Command) error {
49
44
  return fmt.Errorf("API client not available")
50
45
  }
51
46
 
47
+ // Read flag values directly from command
48
+ name, _ := cmd.Flags().GetString("name")
49
+ colorStr, _ := cmd.Flags().GetString("color")
50
+
52
51
  payload := api.CreateColumnPayload{
53
- Name: columnName,
52
+ Name: name,
54
53
  }
55
54
 
56
- if columnColor != "" {
55
+ if colorStr != "" {
57
56
  colorAliases := buildColorAliases()
58
- color, ok := colorAliases[columnColor]
57
+ color, ok := colorAliases[colorStr]
59
58
  if !ok {
60
- return fmt.Errorf("invalid color '%s'. Available colors: %s", columnColor, getAvailableColors())
59
+ return fmt.Errorf("invalid color '%s'. Available colors: %s", colorStr, getAvailableColors())
61
60
  }
62
61
  payload.Color = &color
63
62
  }
@@ -67,14 +66,14 @@ func handleCreateColumn(cmd *cobra.Command) error {
67
66
  return fmt.Errorf("creating column: %w", err)
68
67
  }
69
68
 
70
- fmt.Printf("✓ Column '%s' created successfully\n", columnName)
69
+ fmt.Printf("✓ Column '%s' created successfully\n", name)
71
70
  return nil
72
71
  }
73
72
 
74
73
  func init() {
75
- columnCreateCmd.Flags().StringVarP(&columnName, "name", "n", "", "Column name (required)")
74
+ columnCreateCmd.Flags().StringP("name", "n", "", "Column name (required)")
76
75
  columnCreateCmd.MarkFlagRequired("name")
77
- columnCreateCmd.Flags().StringVar(&columnColor, "color", "", fmt.Sprintf("Column color (optional). Available: %s", getAvailableColors()))
76
+ columnCreateCmd.Flags().String("color", "", fmt.Sprintf("Column color (optional). Available: %s", getAvailableColors()))
78
77
 
79
78
  columnCmd.AddCommand(columnCreateCmd)
80
79
  }
@@ -57,9 +57,6 @@ func TestColumnCreateCommandSuccess(t *testing.T) {
57
57
  cmd.SetContext(testApp.ToContext(context.Background()))
58
58
  cmd.ParseFlags([]string{"--name", "Todo"})
59
59
 
60
- columnName = "Todo"
61
- columnColor = ""
62
-
63
60
  if err := handleCreateColumn(cmd); err != nil {
64
61
  t.Fatalf("handleCreateColumn failed: %v", err)
65
62
  }
@@ -97,9 +94,6 @@ func TestColumnCreateCommandWithColor(t *testing.T) {
97
94
  cmd.SetContext(testApp.ToContext(context.Background()))
98
95
  cmd.ParseFlags([]string{"--name", "In Progress", "--color", "lime"})
99
96
 
100
- columnName = "In Progress"
101
- columnColor = "lime"
102
-
103
97
  if err := handleCreateColumn(cmd); err != nil {
104
98
  t.Fatalf("handleCreateColumn failed: %v", err)
105
99
  }
@@ -113,9 +107,6 @@ func TestColumnCreateCommandInvalidColor(t *testing.T) {
113
107
  cmd.SetContext(testApp.ToContext(context.Background()))
114
108
  cmd.ParseFlags([]string{"--name", "Todo", "--color", "invalid"})
115
109
 
116
- columnName = "Todo"
117
- columnColor = "invalid"
118
-
119
110
  err := handleCreateColumn(cmd)
120
111
  if err == nil {
121
112
  t.Errorf("expected error for invalid color")
@@ -136,10 +127,7 @@ func TestColumnCreateCommandNoBoard(t *testing.T) {
136
127
 
137
128
  cmd := columnCreateCmd
138
129
  cmd.SetContext(testApp.ToContext(context.Background()))
139
- cmd.ParseFlags([]string{"--name", "Todo"})
140
-
141
- columnName = "Todo"
142
- columnColor = ""
130
+ cmd.ParseFlags([]string{"--name", "Todo", "--color", ""})
143
131
 
144
132
  err := handleCreateColumn(cmd)
145
133
  if err == nil {
@@ -155,10 +143,7 @@ func TestColumnCreateCommandNoClient(t *testing.T) {
155
143
 
156
144
  cmd := columnCreateCmd
157
145
  cmd.SetContext(testApp.ToContext(context.Background()))
158
- cmd.ParseFlags([]string{"--name", "Todo"})
159
-
160
- columnName = "Todo"
161
- columnColor = ""
146
+ cmd.ParseFlags([]string{"--name", "Todo", "--color", ""})
162
147
 
163
148
  err := handleCreateColumn(cmd)
164
149
  if err == nil {
@@ -181,10 +166,7 @@ func TestColumnCreateCommandAPIError(t *testing.T) {
181
166
 
182
167
  cmd := columnCreateCmd
183
168
  cmd.SetContext(testApp.ToContext(context.Background()))
184
- cmd.ParseFlags([]string{"--name", "Todo"})
185
-
186
- columnName = "Todo"
187
- columnColor = ""
169
+ cmd.ParseFlags([]string{"--name", "Todo", "--color", ""})
188
170
 
189
171
  err := handleCreateColumn(cmd)
190
172
  if err == nil {
package/cmd/comment.go ADDED
@@ -0,0 +1,14 @@
1
+ // Package cmd
2
+ package cmd
3
+
4
+ import "github.com/spf13/cobra"
5
+
6
+ var commentCmd = &cobra.Command{
7
+ Use: "comment",
8
+ Short: "Manage card comments",
9
+ Long: `Manage comments on cards in Fizzy`,
10
+ }
11
+
12
+ func init() {
13
+ rootCmd.AddCommand(commentCmd)
14
+ }
@@ -0,0 +1,51 @@
1
+ package cmd
2
+
3
+ import (
4
+ "context"
5
+ "fmt"
6
+ "strconv"
7
+
8
+ "github.com/rogeriopvl/fizzy/internal/app"
9
+ "github.com/spf13/cobra"
10
+ )
11
+
12
+ var commentCreateCmd = &cobra.Command{
13
+ Use: "create <card_number>",
14
+ Short: "Create a new comment",
15
+ Long: `Create a new comment on a card`,
16
+ Args: cobra.ExactArgs(1),
17
+ Run: func(cmd *cobra.Command, args []string) {
18
+ if err := handleCreateComment(cmd, args[0]); err != nil {
19
+ fmt.Fprintf(cmd.OutOrStderr(), "Error: %v\n", err)
20
+ }
21
+ },
22
+ }
23
+
24
+ func handleCreateComment(cmd *cobra.Command, cardNumber string) error {
25
+ cardNum, err := strconv.Atoi(cardNumber)
26
+ if err != nil {
27
+ return fmt.Errorf("invalid card number: %w", err)
28
+ }
29
+
30
+ a := app.FromContext(cmd.Context())
31
+ if a == nil || a.Client == nil {
32
+ return fmt.Errorf("API client not available")
33
+ }
34
+
35
+ body, _ := cmd.Flags().GetString("body")
36
+
37
+ comment, err := a.Client.PostCardComment(context.Background(), cardNum, body)
38
+ if err != nil {
39
+ return fmt.Errorf("creating comment: %w", err)
40
+ }
41
+
42
+ fmt.Printf("✓ Comment created successfully (id: %s)\n", comment.ID)
43
+ return nil
44
+ }
45
+
46
+ func init() {
47
+ commentCreateCmd.Flags().StringP("body", "b", "", "Comment body (required)")
48
+ commentCreateCmd.MarkFlagRequired("body")
49
+
50
+ commentCmd.AddCommand(commentCreateCmd)
51
+ }