// tasks is a tiny to-do list for the terminal. // // tasks add Buy milk add a task // tasks list open tasks // tasks done 2 mark task 2 as done // tasks all list every task, including done ones // tasks clear remove done tasks package main import ( "encoding/json" "fmt" "os" "path/filepath" "strconv" "strings" "time" ) type task struct { Text string `json:"text"` Done bool `json:"done"` Created time.Time `json:"created"` } func file() string { home, err := os.UserHomeDir() if err != nil { home = "." } return filepath.Join(home, ".tasks.json") } func load() []task { var ts []task if b, err := os.ReadFile(file()); err == nil { json.Unmarshal(b, &ts) } return ts } func save(ts []task) { b, _ := json.MarshalIndent(ts, "", " ") if err := os.WriteFile(file(), b, 0o644); err != nil { fmt.Fprintln(os.Stderr, "couldn't save tasks:", err) os.Exit(1) } } func list(ts []task, all bool) { shown := 0 for i, t := range ts { if t.Done && !all { continue } box := "[ ]" if t.Done { box = "[x]" } fmt.Printf("%3d. %s %s\n", i+1, box, t.Text) shown++ } if shown == 0 { fmt.Println("Nothing to do. Add a task with: tasks add ") } } func main() { ts := load() args := os.Args[1:] if len(args) == 0 { list(ts, false) return } switch args[0] { case "add": text := strings.TrimSpace(strings.Join(args[1:], " ")) if text == "" { fmt.Println("What should the task say? Example: tasks add Call mom") os.Exit(1) } ts = append(ts, task{Text: text, Created: time.Now()}) save(ts) fmt.Printf("Added task %d: %s\n", len(ts), text) case "done": if len(args) < 2 { fmt.Println("Which task? Example: tasks done 2") os.Exit(1) } n, err := strconv.Atoi(args[1]) if err != nil || n < 1 || n > len(ts) { fmt.Println("There's no task with that number.") os.Exit(1) } ts[n-1].Done = true save(ts) fmt.Printf("Nice! Finished: %s\n", ts[n-1].Text) case "all": list(ts, true) case "clear": var open []task for _, t := range ts { if !t.Done { open = append(open, t) } } save(open) fmt.Printf("Removed %d finished task(s).\n", len(ts)-len(open)) case "help", "-h", "--help": fmt.Println("Usage: tasks [add | done | all | clear]") default: fmt.Println("Unknown command. Try: tasks help") os.Exit(1) } }