Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions cmd/dispatch/notes.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,36 @@ func runNotes(w io.Writer, args []string) error {
func runNotesList(w io.Writer, args []string) error {
jsonOut := false
csvOut := false
tag := ""
if len(args) > 0 && args[0] == "list" {
args = args[1:]
}
for _, arg := range args {
switch arg {
for i := 0; i < len(args); i++ {
arg := args[i]
name, inline, hasInline := splitFlag(arg)
switch name {
case "--json":
jsonOut = true
case "--csv":
csvOut = true
case "--tag":
if hasInline {
tag = inline
continue
}
if i+1 >= len(args) {
return fmt.Errorf("--tag requires a value")
}
tag = args[i+1]
i++
default:
return fmt.Errorf("notes list does not take arguments, got %q", arg)
}
}
if jsonOut && csvOut {
return fmt.Errorf("--json and --csv cannot be combined")
}
tag = normalizeNotesTag(tag)

cfg, err := configLoadFn()
if err != nil {
Expand All @@ -85,6 +99,9 @@ func runNotesList(w io.Writer, args []string) error {
if err != nil {
return err
}
if tag != "" {
sessions = filterNotesSessionsByTag(cfg, sessions, tag)
}
report := buildNotesReport(cfg, sessions)
if jsonOut {
enc := json.NewEncoder(w)
Expand All @@ -98,6 +115,27 @@ func runNotesList(w io.Writer, args []string) error {
return nil
}

func normalizeNotesTag(tag string) string {
parts := config.ParseTags(tag)
if len(parts) == 0 {
return ""
}
return parts[0]
}

func filterNotesSessionsByTag(cfg *config.Config, sessions []data.Session, tag string) []data.Session {
if cfg == nil || tag == "" {
return sessions
}
filtered := make([]data.Session, 0, len(sessions))
for _, s := range sessions {
if cfg.HasTag(s.ID, tag) {
filtered = append(filtered, s)
}
}
return filtered
}

func runNotesGet(w io.Writer, args []string) error {
if len(args) != 1 {
return fmt.Errorf("notes get requires a session ID")
Expand Down
39 changes: 39 additions & 0 deletions cmd/dispatch/notes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ func notedConfig() *config.Config {
"b": "ready to ship",
"z": "orphan note",
}
cfg.SessionTags = map[string][]string{
"a": {"bug", "work"},
"b": {"docs"},
}
return cfg
}

Expand Down Expand Up @@ -82,6 +86,40 @@ func TestRunNotesListJSON(t *testing.T) {
}
}

func TestRunNotesListTagFilterText(t *testing.T) {
withConfigSeams(t, notedConfig())
withNotesList(t, func(data.FilterOptions) ([]data.Session, error) { return notedSessions(), nil })

var buf bytes.Buffer
if err := runNotes(&buf, []string{"notes", "list", "--tag", "bug"}); err != nil {
t.Fatalf("runNotes tag filter: %v", err)
}
out := buf.String()
if !strings.Contains(out, "follow up") {
t.Fatalf("tagged note missing:\n%s", out)
}
if strings.Contains(out, "ready to ship") {
t.Fatalf("untagged note should be filtered out:\n%s", out)
}
}

func TestRunNotesListTagFilterJSON(t *testing.T) {
withConfigSeams(t, notedConfig())
withNotesList(t, func(data.FilterOptions) ([]data.Session, error) { return notedSessions(), nil })

var buf bytes.Buffer
if err := runNotes(&buf, []string{"notes", "--json", "--tag=missing"}); err != nil {
t.Fatalf("runNotes json tag filter: %v", err)
}
var report notesReport
if err := json.Unmarshal(buf.Bytes(), &report); err != nil {
t.Fatalf("invalid JSON: %v\n%s", err, buf.String())
}
if report.TotalNotes != 0 || len(report.Notes) != 0 {
t.Fatalf("report = %+v, want no notes", report)
}
}

func TestRunNotesListCSV(t *testing.T) {
withConfigSeams(t, notedConfig())
withNotesList(t, func(data.FilterOptions) ([]data.Session, error) { return notedSessions(), nil })
Expand Down Expand Up @@ -166,6 +204,7 @@ func TestRunNotesErrors(t *testing.T) {
{"notes", "set", "ses-1", "--stdin", "extra"},
{"notes", "clear"},
{"notes", "list", "extra"},
{"notes", "list", "--tag"},
{"notes", "list", "--json", "--csv"},
} {
if err := runNotes(&bytes.Buffer{}, args); err == nil {
Expand Down