-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathchecklist.go
68 lines (56 loc) · 1.24 KB
/
checklist.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
package gdag
import (
"fmt"
"sort"
)
// CheckList outputs task check list.
func (start *Node) CheckList() (string, error) {
clg := newCheckListGenerator()
clg.makeUnique(start)
sorted := clg.sortComponents()
ret := ""
for _, node := range sorted {
ret += (*checkListGenerator)(nil).renderRow(node)
}
return ret, nil
}
type checkListGenerator struct {
unique map[int]*Node
}
func newCheckListGenerator() *checkListGenerator {
return &checkListGenerator{
unique: map[int]*Node{},
}
}
func (clg *checkListGenerator) makeUnique(node *Node) {
if _, ok := clg.unique[node.index]; ok {
return
}
clg.unique[node.index] = node
for _, d := range node.downstream {
clg.makeUnique(d)
}
}
func (clg *checkListGenerator) sortComponents() []*Node {
keys := make([]int, 0, len(clg.unique))
for k := range clg.unique {
keys = append(keys, k)
}
sort.Ints(keys)
sorted := make([]*Node, 0, len(keys))
for _, k := range keys {
v := clg.unique[k]
sorted = append(sorted, v)
}
return sorted
}
func (*checkListGenerator) renderRow(node *Node) string {
if node.isDAG() {
return fmt.Sprintf("### %s\n", node.text)
}
if node.isDone() {
return fmt.Sprintf("- [x] %s\n", node.text)
} else {
return fmt.Sprintf("- [ ] %s\n", node.text)
}
}