forked from basecamp/fizzy-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomment.go
More file actions
306 lines (258 loc) · 8.59 KB
/
Copy pathcomment.go
File metadata and controls
306 lines (258 loc) · 8.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
package commands
import (
"fmt"
"os"
"strconv"
"github.com/basecamp/fizzy-sdk/go/pkg/generated"
"github.com/spf13/cobra"
)
var commentCmd = &cobra.Command{
Use: "comment",
Short: "Manage comments",
Long: "Commands for managing card comments.",
}
// Comment list flags
var commentListCard string
var commentListPage int
var commentListAll bool
var commentListCmd = &cobra.Command{
Use: "list",
Short: "List comments for a card",
Long: "Lists all comments for a specific card.",
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAuthAndAccount(); err != nil {
return err
}
if err := checkLimitAll(commentListAll); err != nil {
return err
}
if commentListCard == "" {
return newRequiredFlagError("card")
}
ac := getSDK()
var items any
var linkNext string
path := "/cards/" + commentListCard + "/comments.json"
if commentListPage > 0 {
path += "?page=" + strconv.Itoa(commentListPage)
}
if commentListAll {
pages, err := ac.GetAll(cmd.Context(), path)
if err != nil {
return convertSDKError(err)
}
items = jsonAnySlice(pages)
} else {
listPath := ""
if commentListPage > 0 {
listPath = path
}
data, resp, err := ac.Comments().List(cmd.Context(), commentListCard, listPath)
if err != nil {
return convertSDKError(err)
}
items = normalizeAny(data)
linkNext = parseSDKLinkNext(resp)
}
// Build summary
count := dataCount(items)
summary := fmt.Sprintf("%d comments on card #%s", count, commentListCard)
if commentListAll {
summary += " (all)"
} else if commentListPage > 0 {
summary += fmt.Sprintf(" (page %d)", commentListPage)
}
// Build breadcrumbs
breadcrumbs := []Breadcrumb{
breadcrumb("add", fmt.Sprintf("fizzy comment create --card %s --body \"text\"", commentListCard), "Add comment"),
breadcrumb("react", fmt.Sprintf("fizzy reaction create --card %s --comment <id> --content \"👍\"", commentListCard), "Add reaction"),
breadcrumb("show", fmt.Sprintf("fizzy card show %s", commentListCard), "View card"),
}
hasNext := linkNext != ""
printListPaginated(items, commentColumns, hasNext, linkNext, commentListAll, summary, breadcrumbs)
return nil
},
}
// Comment show flags
var commentShowCard string
var commentShowCmd = &cobra.Command{
Use: "show COMMENT_ID",
Short: "Show a comment",
Long: "Shows details of a specific comment.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAuthAndAccount(); err != nil {
return err
}
if commentShowCard == "" {
return newRequiredFlagError("card")
}
commentID := args[0]
cardNumber := commentShowCard
data, _, err := getSDK().Comments().Get(cmd.Context(), cardNumber, commentID)
if err != nil {
return convertSDKError(err)
}
// Build breadcrumbs
breadcrumbs := []Breadcrumb{
breadcrumb("update", fmt.Sprintf("fizzy comment update %s --card %s", commentID, cardNumber), "Edit comment"),
breadcrumb("react", fmt.Sprintf("fizzy reaction create --card %s --comment %s --content \"👍\"", cardNumber, commentID), "Add reaction"),
breadcrumb("comments", fmt.Sprintf("fizzy comment list --card %s", cardNumber), "List comments"),
}
printDetail(normalizeAny(data), "", breadcrumbs)
return nil
},
}
// Comment create flags
var commentCreateCard string
var commentCreateBody string
var commentCreateBodyFile string
var commentCreateCreatedAt string
var commentCreateCmd = &cobra.Command{
Use: "create",
Short: "Create a comment",
Long: "Creates a new comment on a card.",
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAuthAndAccount(); err != nil {
return err
}
if commentCreateCard == "" {
return newRequiredFlagError("card")
}
// Determine body content
var body string
if commentCreateBodyFile != "" {
content, err := os.ReadFile(commentCreateBodyFile)
if err != nil {
return err
}
body = markdownToHTML(resolveMentions(string(content), getClient()))
} else if commentCreateBody != "" {
body = markdownToHTML(resolveMentions(commentCreateBody, getClient()))
} else {
return newRequiredFlagError("body or body_file")
}
cardNumber := commentCreateCard
ac := getSDK()
// Build breadcrumbs
breadcrumbs := []Breadcrumb{
breadcrumb("comments", fmt.Sprintf("fizzy comment list --card %s", cardNumber), "List comments"),
breadcrumb("show", fmt.Sprintf("fizzy card show %s", cardNumber), "View card"),
}
req := &generated.CreateCommentRequest{Body: body}
if commentCreateCreatedAt != "" {
req.CreatedAt = commentCreateCreatedAt
}
data, resp, err := ac.Comments().Create(cmd.Context(), cardNumber, req)
if err != nil {
return convertSDKError(err)
}
items := normalizeAny(data)
if location := resp.Headers.Get("Location"); location != "" {
printMutationWithLocation(items, location, breadcrumbs)
} else {
printMutation(items, "", breadcrumbs)
}
return nil
},
}
// Comment update flags
var commentUpdateCard string
var commentUpdateBody string
var commentUpdateBodyFile string
var commentUpdateCmd = &cobra.Command{
Use: "update COMMENT_ID",
Short: "Update a comment",
Long: "Updates an existing comment.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAuthAndAccount(); err != nil {
return err
}
if commentUpdateCard == "" {
return newRequiredFlagError("card")
}
var body string
if commentUpdateBodyFile != "" {
content, err := os.ReadFile(commentUpdateBodyFile)
if err != nil {
return err
}
body = markdownToHTML(resolveMentions(string(content), getClient()))
} else if commentUpdateBody != "" {
body = markdownToHTML(resolveMentions(commentUpdateBody, getClient()))
}
commentID := args[0]
cardNumber := commentUpdateCard
req := &generated.UpdateCommentRequest{}
if body != "" {
req.Body = body
}
data, _, err := getSDK().Comments().Update(cmd.Context(), cardNumber, commentID, req)
if err != nil {
return convertSDKError(err)
}
// Build breadcrumbs
breadcrumbs := []Breadcrumb{
breadcrumb("show", fmt.Sprintf("fizzy comment show %s --card %s", commentID, cardNumber), "View comment"),
breadcrumb("comments", fmt.Sprintf("fizzy comment list --card %s", cardNumber), "List comments"),
}
printMutation(normalizeAny(data), "", breadcrumbs)
return nil
},
}
// Comment delete flags
var commentDeleteCard string
var commentDeleteCmd = &cobra.Command{
Use: "delete COMMENT_ID",
Short: "Delete a comment",
Long: "Deletes a comment from a card.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAuthAndAccount(); err != nil {
return err
}
if commentDeleteCard == "" {
return newRequiredFlagError("card")
}
cardNumber := commentDeleteCard
_, err := getSDK().Comments().Delete(cmd.Context(), cardNumber, args[0])
if err != nil {
return convertSDKError(err)
}
// Build breadcrumbs
breadcrumbs := []Breadcrumb{
breadcrumb("comments", fmt.Sprintf("fizzy comment list --card %s", cardNumber), "List comments"),
breadcrumb("show", fmt.Sprintf("fizzy card show %s", cardNumber), "View card"),
}
printMutation(map[string]any{
"deleted": true,
}, "", breadcrumbs)
return nil
},
}
func init() {
rootCmd.AddCommand(commentCmd)
// List
commentListCmd.Flags().StringVar(&commentListCard, "card", "", "Card number (required)")
commentListCmd.Flags().IntVar(&commentListPage, "page", 0, "Page number")
commentListCmd.Flags().BoolVar(&commentListAll, "all", false, "Fetch all pages")
commentCmd.AddCommand(commentListCmd)
// Show
commentShowCmd.Flags().StringVar(&commentShowCard, "card", "", "Card number (required)")
commentCmd.AddCommand(commentShowCmd)
// Create
commentCreateCmd.Flags().StringVar(&commentCreateCard, "card", "", "Card number (required)")
commentCreateCmd.Flags().StringVar(&commentCreateBody, "body", "", "Comment body (HTML)")
commentCreateCmd.Flags().StringVar(&commentCreateBodyFile, "body_file", "", "Read body from file")
commentCreateCmd.Flags().StringVar(&commentCreateCreatedAt, "created-at", "", "Custom created_at timestamp")
commentCmd.AddCommand(commentCreateCmd)
// Update
commentUpdateCmd.Flags().StringVar(&commentUpdateCard, "card", "", "Card number (required)")
commentUpdateCmd.Flags().StringVar(&commentUpdateBody, "body", "", "Comment body (HTML)")
commentUpdateCmd.Flags().StringVar(&commentUpdateBodyFile, "body_file", "", "Read body from file")
commentCmd.AddCommand(commentUpdateCmd)
// Delete
commentDeleteCmd.Flags().StringVar(&commentDeleteCard, "card", "", "Card number (required)")
commentCmd.AddCommand(commentDeleteCmd)
}