-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtodo.go
141 lines (131 loc) · 2.64 KB
/
todo.go
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package main
import (
"errors"
"flag"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/nf/todo/task"
)
var noAct = errors.New("didn't act")
var (
file = flag.String("file", defaultFile(".todo", "TODO"), "file in which to store tasks")
log = flag.String("log", defaultFile(".todo-log", "TODOLOG"), "file in which to log removed tasks")
now = flag.Bool("now", false, "when adding, insert at head")
done = flag.Bool("done", false, "don't actually add; just append to log file")
)
func defaultFile(name, env string) string {
if f := os.Getenv(env); f != "" {
return f
}
return filepath.Join(os.Getenv("HOME"), name)
}
const usage = `Usage:
todo
Show top task
todo ls
Show all tasks
todo N
Promote task N to top
todo rm
Remove top task
todo rm N
Remove task N
todo description...
Add task with given description
Flags:
`
func main() {
flag.Usage = func() {
fmt.Fprint(os.Stderr, usage)
flag.PrintDefaults()
}
flag.Parse()
list := task.NewList(*file)
a, n := flag.Arg(0), len(flag.Args())
err := noAct
switch {
case a == "ls" && n == 1:
// list tasks
var tasks []string
tasks, err = list.Get()
for i := len(tasks) - 1; i >= 0; i-- {
fmt.Printf("%2d: %s\n", i, tasks[i])
}
case a == "rm" && n <= 2:
// remove [latest] task
i, err2 := strconv.Atoi(flag.Arg(1))
if err2 != nil && n == 2 {
break
}
if n == 1 {
i = 0
}
var t string
t, err = list.GetTask(i)
if err != nil {
break
}
if err2 := logRemovedTask(t); err2 != nil {
fmt.Fprintln(os.Stderr, "logging:", err2)
}
err = list.RemoveTask(i)
if err != nil || n == 2 {
break
}
fallthrough
case n == 0:
// no arguments; show top task
var tasks []string
tasks, err = list.Get()
if len(tasks) > 0 {
fmt.Println(tasks[0])
}
case n == 1:
// single argument; might be shift-to-top
i, err2 := strconv.Atoi(flag.Arg(0))
if err2 != nil {
// not a number, probably just a single word todo
break
}
var t string
t, err = list.GetTask(i)
if err != nil {
break
}
err = list.RemoveTask(i)
if err != nil {
break
}
err = list.AddTask(t, true)
if err == nil {
fmt.Println(t)
}
}
if err == noAct {
// no action taken, assume add
t := strings.Join(flag.Args(), " ")
if *done {
err = logRemovedTask(t)
} else {
err = list.AddTask(t, *now)
}
}
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func logRemovedTask(t string) error {
f, err := os.OpenFile(*log, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
return err
}
defer f.Close()
now := time.Now().Format("2006-01-02")
_, err = fmt.Fprintf(f, "%s %s\n", now, t)
return err
}