summaryrefslogtreecommitdiff
path: root/internal/askcli/dispatch.go
blob: e828989893d3a273d19a59f7bc40725f3e3256d2 (plain)
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
package askcli

import (
	"context"
	"fmt"
	"io"
)

type Runner interface {
	Run(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error)
}

type Dispatcher struct {
	runner     Runner
	jsonOutput bool
}

func NewDispatcher(runner Runner) *Dispatcher {
	if runner == nil {
		e := NewExecutor("ask")
		runner = &e
	}
	return &Dispatcher{runner: runner}
}

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
	for _, a := range args {
		if a == "--json" {
			jsonOutput = true
		} else {
			filtered = append(filtered, a)
		}
	}
	args = filtered
	d.jsonOutput = jsonOutput

	if len(args) == 0 {
		return d.handleList(ctx, []string{"list"}, stdout, stderr)
	}
	subcommand := args[0]
	switch subcommand {
	case "info":
		return d.handleInfo(ctx, args, stdout, stderr)
	case "add":
		return d.handleAdd(ctx, args, stdout, stderr)
	case "list":
		return d.handleList(ctx, args, stdout, stderr)
	case "all":
		return d.handleAll(ctx, args, stdout, stderr)
	case "ready":
		return d.handleReady(ctx, args, stdout, stderr)
	case "dep":
		return d.handleDep(ctx, args, stdout, stderr)
	case "urgency":
		return d.handleUrgency(ctx, stdout, stderr)
	case "annotate":
		return d.handleAnnotate(ctx, args, stdout, stderr)
	case "start":
		return d.handleStart(ctx, args, stdout, stderr)
	case "stop":
		return d.handleStop(ctx, args, stdout, stderr)
	case "done":
		return d.handleDone(ctx, args, stdout, stderr)
	case "priority":
		return d.handlePriority(ctx, args, stdout, stderr)
	case "tag":
		return d.handleTag(ctx, args, stdout, stderr)
	case "modify":
		return d.handleModify(ctx, args, stdout, stderr)
	case "denotate":
		return d.handleDenotate(ctx, args, stdout, stderr)
	case "delete":
		return d.handleDelete(ctx, args, stdin, stdout, stderr)
	case "fish":
		return d.handleFish(args, stdout, stderr)
	case "help":
		return d.help(stdout)
	case "complete-uuids":
		return d.handleCompleteUUIDs(ctx, stdout, stderr)
	default:
		return d.unknownCommand(stderr, subcommand)
	}
}

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 \"description\"          Create a new task\n")
	io.WriteString(w, "  ask list [filters]           List active tasks (default)\n")
	io.WriteString(w, "  ask ready                   List READY tasks (not blocked)\n")
	io.WriteString(w, "  ask all [filters]            List all tasks including completed/deleted\n")
	io.WriteString(w, "  ask info <uuid>               Show task details\n")
	io.WriteString(w, "  ask annotate <uuid> \"note\"    Add annotation to task\n")
	io.WriteString(w, "  ask start <uuid>              Start working on task\n")
	io.WriteString(w, "  ask stop <uuid>               Stop working on task\n")
	io.WriteString(w, "  ask done <uuid>               Mark task complete\n")
	io.WriteString(w, "  ask priority <uuid> <P>        Set priority (H/M/L)\n")
	io.WriteString(w, "  ask tag <uuid> +/-<tag>       Add or remove tag\n")
	io.WriteString(w, "  ask dep add <uuid> <dep-uuid> Add dependency\n")
	io.WriteString(w, "  ask dep rm <uuid> <dep-uuid> Remove dependency\n")
	io.WriteString(w, "  ask dep list <uuid>           List dependencies\n")
	io.WriteString(w, "  ask urgency                   List tasks sorted by urgency\n")
	io.WriteString(w, "  ask modify <uuid> <args...>   Modify task fields\n")
	io.WriteString(w, "  ask denotate <uuid> \"text\"     Remove annotation\n")
	io.WriteString(w, "  ask delete <uuid>             Delete task\n")
	io.WriteString(w, "  ask fish                      Emit Fish shell completion script\n")
	return 0, nil
}

func (d Dispatcher) unknownCommand(w io.Writer, subcommand string) (int, error) {
	fmt.Fprintf(w, "ask: unknown subcommand %q\n", subcommand)
	return 1, nil
}