diff options
| -rw-r--r-- | internal/askcli/command_complete_uuids.go | 2 | ||||
| -rw-r--r-- | internal/askcli/command_delete.go | 2 | ||||
| -rw-r--r-- | internal/askcli/command_dep.go | 6 | ||||
| -rw-r--r-- | internal/askcli/command_fish.go | 2 | ||||
| -rw-r--r-- | internal/askcli/command_info_add.go | 12 | ||||
| -rw-r--r-- | internal/askcli/command_list.go | 8 | ||||
| -rw-r--r-- | internal/askcli/command_urgency.go | 2 | ||||
| -rw-r--r-- | internal/askcli/command_write.go | 16 | ||||
| -rw-r--r-- | internal/askcli/dispatch.go | 6 | ||||
| -rw-r--r-- | internal/askcli/dispatch_test.go | 28 | ||||
| -rw-r--r-- | internal/askcli/task_selector.go | 2 |
11 files changed, 57 insertions, 29 deletions
diff --git a/internal/askcli/command_complete_uuids.go b/internal/askcli/command_complete_uuids.go index 8d37a80..3a2ef9e 100644 --- a/internal/askcli/command_complete_uuids.go +++ b/internal/askcli/command_complete_uuids.go @@ -7,7 +7,7 @@ import ( "io" ) -func (d Dispatcher) handleCompleteUUIDs(ctx context.Context, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleCompleteUUIDs(ctx context.Context, stdout, stderr io.Writer) (int, error) { var outBuf bytes.Buffer code, err := d.runner.Run(ctx, []string{"status:pending", "export"}, nil, &outBuf, stderr) if code != 0 { diff --git a/internal/askcli/command_delete.go b/internal/askcli/command_delete.go index 1efaad9..4e93add 100644 --- a/internal/askcli/command_delete.go +++ b/internal/askcli/command_delete.go @@ -6,7 +6,7 @@ import ( "io" ) -func (d Dispatcher) handleDelete(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleDelete(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) { if len(args) < 2 { io.WriteString(stderr, "error: ask delete requires an ID or UUID argument\n") return 1, nil diff --git a/internal/askcli/command_dep.go b/internal/askcli/command_dep.go index adfb232..83a4803 100644 --- a/internal/askcli/command_dep.go +++ b/internal/askcli/command_dep.go @@ -8,7 +8,7 @@ import ( "strings" ) -func (d Dispatcher) handleDep(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleDep(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 2 { io.WriteString(stderr, "error: ask dep requires an operation (add/rm/list) and arguments\n") return 1, nil @@ -25,7 +25,7 @@ func (d Dispatcher) handleDep(ctx context.Context, args []string, stdout, stderr } } -func (d Dispatcher) handleDepAddRm(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleDepAddRm(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 4 { io.WriteString(stderr, "error: ask dep add/rm requires <id|uuid> <dep-id|dep-uuid>\n") return 1, nil @@ -57,7 +57,7 @@ func (d Dispatcher) handleDepAddRm(ctx context.Context, args []string, stdout, s return 0, nil } -func (d Dispatcher) handleDepList(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleDepList(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 3 { io.WriteString(stderr, "error: ask dep list requires <id|uuid>\n") return 1, nil diff --git a/internal/askcli/command_fish.go b/internal/askcli/command_fish.go index 89a8457..3d3e709 100644 --- a/internal/askcli/command_fish.go +++ b/internal/askcli/command_fish.go @@ -6,7 +6,7 @@ import ( "os" ) -func (d Dispatcher) handleFish(args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleFish(args []string, stdout, stderr io.Writer) (int, error) { if len(args) != 1 { fmt.Fprintln(stderr, "usage: ask fish") return 1, nil diff --git a/internal/askcli/command_info_add.go b/internal/askcli/command_info_add.go index 737b0d0..3bb57fb 100644 --- a/internal/askcli/command_info_add.go +++ b/internal/askcli/command_info_add.go @@ -9,7 +9,7 @@ import ( "strings" ) -func (d Dispatcher) handleInfo(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleInfo(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { tasks, code, err := d.infoTasks(ctx, args, stderr) if err != nil { writeInfoError(stderr, err) @@ -35,7 +35,7 @@ func (d Dispatcher) handleInfo(ctx context.Context, args []string, stdout, stder return 0, nil } -func (d Dispatcher) infoTasks(ctx context.Context, args []string, stderr io.Writer) ([]TaskExport, int, error) { +func (d *Dispatcher) infoTasks(ctx context.Context, args []string, stderr io.Writer) ([]TaskExport, int, error) { if len(args) >= 2 { _, tasks, code, err := d.resolveTaskSelector(ctx, args[1], stderr) return tasks, code, err @@ -43,7 +43,7 @@ func (d Dispatcher) infoTasks(ctx context.Context, args []string, stderr io.Writ return d.startedInfoTasks(ctx, stderr) } -func (d Dispatcher) startedInfoTasks(ctx context.Context, stderr io.Writer) ([]TaskExport, int, error) { +func (d *Dispatcher) startedInfoTasks(ctx context.Context, stderr io.Writer) ([]TaskExport, int, error) { tasks, code, err := d.exportTasks(ctx, []string{"started", "export"}, stderr) if err != nil { return nil, code, err @@ -58,7 +58,7 @@ func (d Dispatcher) startedInfoTasks(ctx context.Context, stderr io.Writer) ([]T } } -func (d Dispatcher) exportTasks(ctx context.Context, args []string, stderr io.Writer) ([]TaskExport, int, error) { +func (d *Dispatcher) exportTasks(ctx context.Context, args []string, stderr io.Writer) ([]TaskExport, int, error) { var outBuf bytes.Buffer code, err := d.runner.Run(ctx, args, nil, &outBuf, stderr) if code != 0 { @@ -83,7 +83,7 @@ func writeInfoError(stderr io.Writer, err error) { fmt.Fprintf(stderr, "error: %v\n", err) } -func (d Dispatcher) handleAdd(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleAdd(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 2 { io.WriteString(stderr, "error: ask add requires a description\n") return 1, nil @@ -129,7 +129,7 @@ func (d Dispatcher) handleAdd(ctx context.Context, args []string, stdout, stderr return 0, nil } -func (d Dispatcher) resolveAddDependencyUUIDs(ctx context.Context, selectors []string, stderr io.Writer) ([]string, int, error) { +func (d *Dispatcher) resolveAddDependencyUUIDs(ctx context.Context, selectors []string, stderr io.Writer) ([]string, int, error) { dependencies := make([]string, 0, len(selectors)) for _, selector := range selectors { resolved, _, code, err := d.resolveTaskSelector(ctx, selector, stderr) diff --git a/internal/askcli/command_list.go b/internal/askcli/command_list.go index 2e5dfa2..76b5302 100644 --- a/internal/askcli/command_list.go +++ b/internal/askcli/command_list.go @@ -10,22 +10,22 @@ import ( "strings" ) -func (d Dispatcher) handleList(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleList(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { return d.handleListWithFilters(ctx, []string{"status:pending"}, args[1:], stdout, stderr) } -func (d Dispatcher) handleAll(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleAll(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { return d.handleListWithFilters(ctx, nil, args[1:], stdout, stderr) } -func (d Dispatcher) handleReady(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleReady(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { return d.handleListWithFilters(ctx, []string{"+READY"}, args[1:], stdout, stderr) } // handleListWithFilters is the shared implementation for list/all/ready. // initialFilters seeds the taskwarrior filter; extraArgs are user-supplied // filter modifiers (limit:, sort:, +tag, started). -func (d Dispatcher) handleListWithFilters(ctx context.Context, initialFilters, extraArgs []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleListWithFilters(ctx context.Context, initialFilters, extraArgs []string, stdout, stderr io.Writer) (int, error) { filterArgs := append([]string(nil), initialFilters...) for _, arg := range extraArgs { if strings.HasPrefix(arg, "limit:") || strings.HasPrefix(arg, "sort:") || diff --git a/internal/askcli/command_urgency.go b/internal/askcli/command_urgency.go index c1ec24c..a6f545c 100644 --- a/internal/askcli/command_urgency.go +++ b/internal/askcli/command_urgency.go @@ -9,7 +9,7 @@ import ( "sort" ) -func (d Dispatcher) handleUrgency(ctx context.Context, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleUrgency(ctx context.Context, stdout, stderr io.Writer) (int, error) { var outBuf bytes.Buffer code, err := d.runner.Run(ctx, []string{"export"}, nil, &outBuf, stderr) if code != 0 { diff --git a/internal/askcli/command_write.go b/internal/askcli/command_write.go index 477e097..efc634a 100644 --- a/internal/askcli/command_write.go +++ b/internal/askcli/command_write.go @@ -7,7 +7,7 @@ import ( "strings" ) -func (d Dispatcher) handleDenotate(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleDenotate(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 3 { io.WriteString(stderr, "error: ask denotate requires an ID or UUID and text argument\n") return 1, nil @@ -27,7 +27,7 @@ func (d Dispatcher) handleDenotate(ctx context.Context, args []string, stdout, s return 0, nil } -func (d Dispatcher) handleModify(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleModify(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 3 { io.WriteString(stderr, "error: ask modify requires an ID or UUID and modification args\n") return 1, nil @@ -47,7 +47,7 @@ func (d Dispatcher) handleModify(ctx context.Context, args []string, stdout, std return 0, nil } -func (d Dispatcher) handleAnnotate(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleAnnotate(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 3 { io.WriteString(stderr, "error: ask annotate requires an ID or UUID and note argument\n") return 1, nil @@ -67,7 +67,7 @@ func (d Dispatcher) handleAnnotate(ctx context.Context, args []string, stdout, s return 0, nil } -func (d Dispatcher) handleStart(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleStart(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 2 { io.WriteString(stderr, "error: ask start requires an ID or UUID argument\n") return 1, nil @@ -88,7 +88,7 @@ func (d Dispatcher) handleStart(ctx context.Context, args []string, stdout, stde return 0, nil } -func (d Dispatcher) handleStop(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleStop(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 2 { io.WriteString(stderr, "error: ask stop requires an ID or UUID argument\n") return 1, nil @@ -107,7 +107,7 @@ func (d Dispatcher) handleStop(ctx context.Context, args []string, stdout, stder return 0, nil } -func (d Dispatcher) handleDone(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleDone(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 2 { io.WriteString(stderr, "error: ask done requires an ID or UUID argument\n") return 1, nil @@ -126,7 +126,7 @@ func (d Dispatcher) handleDone(ctx context.Context, args []string, stdout, stder return 0, nil } -func (d Dispatcher) handlePriority(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handlePriority(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 3 { io.WriteString(stderr, "error: ask priority requires an ID or UUID and priority (H/M/L)\n") return 1, nil @@ -146,7 +146,7 @@ func (d Dispatcher) handlePriority(ctx context.Context, args []string, stdout, s return 0, nil } -func (d Dispatcher) handleTag(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) handleTag(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { if len(args) < 3 { io.WriteString(stderr, "error: ask tag requires an ID or UUID and +/-tag\n") return 1, nil diff --git a/internal/askcli/dispatch.go b/internal/askcli/dispatch.go index 510f2cd..5160abb 100644 --- a/internal/askcli/dispatch.go +++ b/internal/askcli/dispatch.go @@ -23,7 +23,7 @@ func NewDispatcher(runner Runner) *Dispatcher { return &Dispatcher{runner: runner} } -func (d Dispatcher) Dispatch(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) { +func (d *Dispatcher) Dispatch(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) { // Extract --json flag before dispatching. var jsonOutput bool var filtered []string @@ -85,7 +85,7 @@ func (d Dispatcher) Dispatch(ctx context.Context, args []string, stdin io.Reader } } -func (d Dispatcher) help(w io.Writer) (int, error) { +func (d *Dispatcher) help(w io.Writer) (int, error) { io.WriteString(w, "ask - task management CLI\n") io.WriteString(w, "\nSubcommands:\n") io.WriteString(w, " ask add [mods...] [depends:<id|uuid>,...] <description...> Create a new task and print its ID\n") @@ -110,7 +110,7 @@ func (d Dispatcher) help(w io.Writer) (int, error) { return 0, nil } -func (d Dispatcher) unknownCommand(w io.Writer, subcommand string) (int, error) { +func (d *Dispatcher) unknownCommand(w io.Writer, subcommand string) (int, error) { fmt.Fprintf(w, "ask: unknown subcommand %q\n", subcommand) return 1, nil } diff --git a/internal/askcli/dispatch_test.go b/internal/askcli/dispatch_test.go index cd83e48..48c3e55 100644 --- a/internal/askcli/dispatch_test.go +++ b/internal/askcli/dispatch_test.go @@ -123,6 +123,34 @@ func TestDispatcher_FishSubcommandRejectsExtraArgs(t *testing.T) { } } +func TestDispatcher_DispatchPersistsJSONFlagOnDispatcher(t *testing.T) { + d := NewDispatcher(&spyRunner{runFn: func(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) { + if strings.Join(args, " ") != "status:pending export" { + t.Fatalf("args = %v, want list export args", args) + } + _, _ = io.WriteString(stdout, `[]`) + return 0, nil + }}) + + var stdout, stderr bytes.Buffer + code, err := d.Dispatch(context.Background(), []string{"--json", "list"}, nil, &stdout, &stderr) + if err != nil { + t.Fatalf("Dispatch returned error: %v", err) + } + if code != 0 { + t.Fatalf("Dispatch code = %d, want 0", code) + } + if !d.jsonOutput { + t.Fatal("Dispatch did not persist jsonOutput on the dispatcher") + } + if got := stdout.String(); got != "[]\n" { + t.Fatalf("stdout = %q, want JSON output", got) + } + if stderr.Len() != 0 { + t.Fatalf("stderr = %q, want empty", stderr.String()) + } +} + func TestDispatcher_AllSubcommandsReachExecutor(t *testing.T) { subcommands := []string{} subcommandArgs := map[string][]string{ diff --git a/internal/askcli/task_selector.go b/internal/askcli/task_selector.go index 7702153..ccae234 100644 --- a/internal/askcli/task_selector.go +++ b/internal/askcli/task_selector.go @@ -14,7 +14,7 @@ type resolvedTaskSelector struct { UsedAlias bool } -func (d Dispatcher) resolveTaskSelector(ctx context.Context, selector string, stderr io.Writer) (resolvedTaskSelector, []TaskExport, int, error) { +func (d *Dispatcher) resolveTaskSelector(ctx context.Context, selector string, stderr io.Writer) (resolvedTaskSelector, []TaskExport, int, error) { normalized, requiresLookup, err := normalizeTaskSelectorInput(selector) if err != nil { return resolvedTaskSelector{}, nil, 1, err |
