task.go
140 lines1
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
//go:build cgo
package commands
import (
"encoding/json"
"flag"
"fmt"
"os"
"congo.gg/dev/models"
)
const taskUsage = `Manage tasks in the Congo Dev database
Usage:
congo task <subcommand> [arguments]
Subcommands:
list List tasks (JSON)
create <title> Create a task
update <id> --status X Update a task
get <id> Get a single task (JSON)
`
func Task() {
if len(os.Args) < 3 {
fmt.Print(taskUsage)
os.Exit(1)
}
switch os.Args[2] {
case "list":
taskList()
case "create":
taskCreate()
case "update":
taskUpdate()
case "get":
taskGet()
default:
fmt.Fprintf(os.Stderr, "unknown task subcommand %q\n", os.Args[2])
os.Exit(1)
}
}
func taskList() {
f := flag.NewFlagSet("task list", flag.ExitOnError)
status := f.String("status", "", "Filter by status (todo, in_progress, done, blocked)")
assignee := f.String("assignee", "", "Filter by assignee")
f.Parse(os.Args[3:])
query := "ORDER BY CASE Priority WHEN 'high' THEN 1 WHEN 'medium' THEN 2 ELSE 3 END"
var args []any
if *status != "" {
query = "WHERE Status = ? " + query
args = append(args, *status)
}
if *assignee != "" {
if len(args) > 0 {
query = "WHERE Status = ? AND Assignee = ? ORDER BY CASE Priority WHEN 'high' THEN 1 WHEN 'medium' THEN 2 ELSE 3 END"
args = append(args, *assignee)
} else {
query = "WHERE Assignee = ? " + query
args = append(args, *assignee)
}
}
tasks, _ := models.Tasks.Search(query, args...)
json.NewEncoder(os.Stdout).Encode(tasks)
}
func taskCreate() {
f := flag.NewFlagSet("task create", flag.ExitOnError)
priority := f.String("priority", "medium", "Priority (high, medium, low)")
assignee := f.String("assignee", "", "Assignee (twin, connor, etc)")
category := f.String("category", "", "Category")
description := f.String("description", "", "Description")
f.Parse(os.Args[3:])
title := f.Arg(0)
if title == "" {
fmt.Fprintln(os.Stderr, "usage: congo task create <title>")
os.Exit(1)
}
task := &models.Task{
Title: title,
Description: *description,
Priority: *priority,
Status: "todo",
Assignee: *assignee,
Category: *category,
}
id, _ := models.Tasks.Insert(task)
fmt.Println(id)
}
func taskUpdate() {
if len(os.Args) < 4 {
fmt.Fprintln(os.Stderr, "usage: congo task update <id> --status done")
os.Exit(1)
}
// ID is the first arg after "task update", flags follow
id := os.Args[3]
f := flag.NewFlagSet("task update", flag.ExitOnError)
status := f.String("status", "", "New status")
assignee := f.String("assignee", "", "New assignee")
f.Parse(os.Args[4:]) // parse flags after the ID
task, err := models.Tasks.Get(id)
if err != nil || task == nil {
fmt.Fprintf(os.Stderr, "task %s not found\n", id)
os.Exit(1)
}
if *status != "" {
task.Status = *status
}
if *assignee != "" {
task.Assignee = *assignee
}
models.Tasks.Update(task)
fmt.Println("updated")
}
func taskGet() {
if len(os.Args) < 4 {
fmt.Fprintln(os.Stderr, "usage: congo task get <id>")
os.Exit(1)
}
task, err := models.Tasks.Get(os.Args[3])
if err != nil || task == nil {
fmt.Fprintf(os.Stderr, "task not found\n")
os.Exit(1)
}
json.NewEncoder(os.Stdout).Encode(task)
}