Skip to content

Commit 9b54252

Browse files
committed
feat(cli): change list --channel accepts comma-separated IDs
Migrate from singular Int64Var to StringVar + parseIntSlice, routing through ListChangesInput.ChannelIDs []int64 to match the MCP surface and mirror the existing alert list --channel pattern.
1 parent f86006c commit 9b54252

2 files changed

Lines changed: 62 additions & 5 deletions

File tree

internal/cli/change.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func newChangeCmd() *cobra.Command {
2121
}
2222

2323
func newChangeListCmd() *cobra.Command {
24-
var channelID int64
24+
var channel string
2525
var since, until string
2626
var limit, page int
2727

@@ -39,13 +39,22 @@ func newChangeListCmd() *cobra.Command {
3939
return fmt.Errorf("invalid --until: %w", err)
4040
}
4141

42-
result, err := ctx.Client.ListChanges(cmdContext(ctx.Cmd), &flashduty.ListChangesInput{
43-
ChannelID: channelID,
42+
input := &flashduty.ListChangesInput{
4443
StartTime: startTime,
4544
EndTime: endTime,
4645
Limit: limit,
4746
Page: page,
48-
})
47+
}
48+
49+
if channel != "" {
50+
channelIDs, err := parseIntSlice(channel)
51+
if err != nil {
52+
return fmt.Errorf("invalid --channel: %w", err)
53+
}
54+
input.ChannelIDs = channelIDs
55+
}
56+
57+
result, err := ctx.Client.ListChanges(cmdContext(ctx.Cmd), input)
4958
if err != nil {
5059
return err
5160
}
@@ -63,7 +72,7 @@ func newChangeListCmd() *cobra.Command {
6372
},
6473
}
6574

66-
cmd.Flags().Int64Var(&channelID, "channel", 0, "Filter by channel ID")
75+
cmd.Flags().StringVar(&channel, "channel", "", "Comma-separated channel IDs")
6776
cmd.Flags().StringVar(&since, "since", "24h", "Start time")
6877
cmd.Flags().StringVar(&until, "until", "now", "End time")
6978
cmd.Flags().IntVar(&limit, "limit", 20, "Max results")

internal/cli/change_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package cli
2+
3+
import (
4+
"testing"
5+
)
6+
7+
// TestChangeListChannelFlag verifies that --channel is a string flag (comma-separated IDs),
8+
// not a singular int64 flag. Mirrors the alert list --channel pattern.
9+
func TestChangeListChannelFlag(t *testing.T) {
10+
cmd := newChangeListCmd()
11+
flags := cmd.Flags()
12+
13+
f := flags.Lookup("channel")
14+
if f == nil {
15+
t.Fatal("flag --channel not registered")
16+
}
17+
18+
// Must be a string flag (Value.Type() == "string"), not int64.
19+
if got := f.Value.Type(); got != "string" {
20+
t.Errorf("--channel flag type = %q, want %q", got, "string")
21+
}
22+
23+
// Default must be empty string (not "0").
24+
if got := f.DefValue; got != "" {
25+
t.Errorf("--channel default = %q, want %q", got, "")
26+
}
27+
}
28+
29+
// TestChangeListChannelParsing verifies that a comma-separated --channel value
30+
// is correctly parsed to []int64 via parseIntSlice — the same helper used by
31+
// alert list. Full comma-split semantics are covered by TestParseIntSlice in
32+
// helpers_test.go; this test only confirms the wiring is correct.
33+
func TestChangeListChannelParsing(t *testing.T) {
34+
// parseIntSlice is the shared helper; spot-check the three-value case.
35+
got, err := parseIntSlice("100,200,300")
36+
if err != nil {
37+
t.Fatalf("parseIntSlice(\"100,200,300\"): unexpected error: %v", err)
38+
}
39+
want := []int64{100, 200, 300}
40+
if len(got) != len(want) {
41+
t.Fatalf("length mismatch: got %d, want %d", len(got), len(want))
42+
}
43+
for i := range want {
44+
if got[i] != want[i] {
45+
t.Errorf("index %d: got %d, want %d", i, got[i], want[i])
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)