ref: 0ef8293bced988566398b44feecf60d1bd1ffa67
parent: e721f80792486af6fe541f9326d2d322c72ec28a
author: halfwit <michaelmisch1985@gmail.com>
date: Thu Nov 28 11:27:52 PST 2019
Shifting around code to work with the new design
--- a/.todo
+++ /dev/null
@@ -1,48 +1,0 @@
-#1
-TODO(halfwit) - Create generate functions
-[ ] generate.go: WalkFunc check for any match
-[ ] generate.go: Create each file
-[ ] generate.go: Make sure file doesn't already exist
-
-#2: requires [#8]
-TODO(halfwit) - Create add function
-[ ] add.go: Add link to dag
-
-#3: requires [#9]
-TODO(halfwit) - Create rm function
-[ ] rm.go: Remove link from dag
-
-#4: requires [#10]
-TODO(halfwit) - Create dot function
-[ ] list.go: Use dag libraries' built in dot printer
-
-#5: requires [#10]
-TODO(halfwit) - Create list function
-[ ] list.go: Print each leaf to stdout
-
-#6: requires [#10]
-TODO(halfwit) - Create listAll function
-[ ] list.go: Print each node to stdout
-
-#7:
-TODO(halfwit) - Build graph function
-[ ] dag.go: Parse in .todo files
-[ ] dag.go: add edges/vertices into DAG
-
-#8:
-TODO(halfwit) - add Subcommand
-[ ] add.go: AddChild
-[ ] add.go: AddParent
-
-#9:
-TODO(halfwit) - rm Subcommands
-[ ] rm.go: RmChild
-[ ] rm.go: RmParent
-
-#10:
-TODO(halfwit) - walk nodes
-[ ] list.go: Walk each node in the dag
-
-#11:
-TODO(halfwit) - Write out to file
-[ ] write.go: write() func
--- a/add.go
+++ /dev/null
@@ -1,9 +1,0 @@
-package main
-
-// TODO(halfwit): [#2] Create add function
-// requires [#8]
-// [ ] Add link to our dag
-
-// TODO(halfwit): [#8] add Subcommand
-// [ ] AddChild
-// [ ] AddParent
\ No newline at end of file
--- a/command.go
+++ b/command.go
@@ -52,8 +52,6 @@
switch arg {
case "help":
c.runner = help
- case "init":
- c.runner = initFile
case "list":
c.runner = list
case "listall":
--- a/dag.go
+++ b/dag.go
@@ -1,5 +1,27 @@
package main
+// Take a layout and create a dag object from it
+
// TODO(halfwit): [#7] Build graph function
// [ ] Parse in .todo files
// [ ] add edges/vertices into DAG
+
+// TODO(halfwit): [#2] Create add function
+// requires [#8]
+// [ ] Add link to our dag
+
+// TODO(halfwit): [#8] add Subcommand
+// [ ] AddChild
+// [ ] AddParent
+
+// TODO(halfwit): [#3] Create rm function
+// requires [#9]
+// [ ] Remove link from dag
+
+// TODO(halfwit): [#9] rm Subcommands
+// [ ] RmChild
+// [ ] RmParent
+
+
+// TODO(halfwit): [#11] Write out to file
+// [ ] write() func
--- /dev/null
+++ b/layout.go
@@ -1,0 +1,204 @@
+package main
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "log"
+ "os"
+)
+
+/* This is what we want after parsing
+type Layout struct {
+ TaskList []*Tasks
+}
+
+type Tasks struct {
+ Tag string
+ Requires []string
+ Tasks []*Task
+}
+
+type Task struct {
+ Title string
+ Entries []*Entry
+}
+
+type Entry struct {
+ Desc string
+ Done bool
+}
+*/
+
+// Layout - Structure representing a given .todo file
+type Layout struct {
+ TaskList []*Entries
+}
+
+// Entries - set of todo items for a give task
+type Entries struct {
+ Title string
+ List []*Entry
+}
+
+// Entry - individual item of a set of tasks
+type Entry struct {
+ Desc string
+ Done bool
+}
+
+func layoutFromTodoFile() (*Layout, error) {
+ l := &Layout{
+ TaskList: []*Entries{},
+ }
+ fl, err := os.Open(".todo")
+ if err != nil {
+ return nil, err
+ }
+ sc := bufio.NewScanner(fl)
+ for sc.Scan() {
+ if sc.Text() == "" {
+ continue
+ }
+
+ tl := &Entries{
+ Title: sc.Text(),
+ List: parseEntries(sc),
+ }
+ l.TaskList = append(l.TaskList, tl)
+ }
+ if err := sc.Err(); err != nil {
+ return nil, err
+ }
+
+ return l, nil
+}
+
+func parseEntries(sc *bufio.Scanner) []*Entry {
+ sc.Scan()
+ en := []*Entry{}
+ for {
+ d := sc.Text()
+ if len(d) < 4 {
+ return en
+ }
+ if err := sc.Err(); err != nil {
+ log.Fatal(err)
+ }
+ switch d[:3] {
+ case "[ ]":
+ en = append(en, &Entry{
+ Desc: d[4:],
+ Done: false,
+ })
+ case "[x]":
+ en = append(en, &Entry{
+ Desc: d[4:],
+ Done: true,
+ })
+ default:
+ return en
+ }
+ sc.Scan()
+ }
+}
+
+func (l *Layout) destroy(title string) error {
+ if _, err := os.Stat(".todo"); err != nil {
+ return errors.New("Unable to locate .todo file")
+ }
+ for i, e := range l.TaskList {
+ if e.Title != title {
+ continue
+ }
+ if i < len(l.TaskList)-1 {
+ copy(l.TaskList[i:], l.TaskList[i+1:])
+ }
+ l.TaskList = l.TaskList[:len(l.TaskList)-1]
+ return nil
+ }
+ return errors.New("No such Entry")
+}
+
+func (l *Layout) create(title string) error {
+ if len(title) < 1 {
+ return errors.New("Unable to add nil Entry")
+ }
+ l.TaskList = append(l.TaskList, &Entries{
+ Title: title,
+ List: []*Entry{},
+ })
+ return nil
+}
+
+func (l *Layout) taskExists(Title, item string) bool {
+ for _, e := range l.TaskList {
+ if e.Title != Title {
+ continue
+ }
+ for _, t := range e.List {
+ if t.Desc == item {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func (l *Layout) addTask(Title, item string) error {
+ for _, e := range l.TaskList {
+ // Found existing task, append to List
+ if e.Title != Title {
+ continue
+ }
+ e.List = append(e.List, &Entry{
+ Desc: item,
+ Done: false,
+ })
+ return nil
+ }
+ line := &Entry{
+ Desc: item,
+ Done: false,
+ }
+ l.TaskList = append(l.TaskList, &Entries{
+ Title: Title,
+ List: []*Entry{line},
+ })
+ return nil
+}
+
+func (l *Layout) rmTask(Title, item string) error {
+ for _, e := range l.TaskList {
+ if e.Title != Title {
+ continue
+ }
+ for i, t := range e.List {
+ if t.Desc != item {
+ continue
+ }
+ if i < len(e.List)-1 {
+ copy(e.List[i:], e.List[i+1:])
+ }
+ e.List = e.List[:len(e.List)-1]
+ return nil
+ }
+ }
+ return fmt.Errorf("No such task/Entry")
+}
+
+func (l *Layout) toggleTask(Title, item string) error {
+ for _, e := range l.TaskList {
+ if e.Title != Title {
+ continue
+ }
+ for _, t := range e.List {
+ if t.Desc != item {
+ continue
+ }
+ t.Done = !t.Done
+ return nil
+ }
+ }
+ return fmt.Errorf("No such task/Entry")
+}
--- a/rm.go
+++ /dev/null
@@ -1,9 +1,0 @@
-package main
-
-// TODO(halfwit): [#3] Create rm function
-// requires [#9]
-// [ ] Remove link from dag
-
-// TODO(halfwit): [#9] rm Subcommands
-// [ ] RmChild
-// [ ] RmParent
--- a/runners.go
+++ b/runners.go
@@ -1,28 +1,5 @@
package main
-import (
- "os"
- "text/template"
-)
-
-var tmpl = template.Must(template.New("new").Parse("# {{.Name}} TODO"))
-
-type makefile struct {
- Name string
- //nodes []node
-}
-
-func initFile(c *command) error {
- wr, err := os.Create(c.mkfile)
- if err != nil {
- return err
- }
- defer wr.Close()
- //TODO(halfwit): Create a more useful type here
- data := &makefile{c.mkfile}
- return tmpl.Execute(os.Stdout, data)
-}
-
func list(c *command) error {
// Parse makefile into DAG
// Pretty print the leaves
--- a/task.go
+++ b/task.go
@@ -1,95 +1,15 @@
package main
import (
- "bufio"
"errors"
"fmt"
- "log"
- "os"
- "text/template"
)
-const tmplt = `{{range .TaskList}}{{.Title}}
-{{range .List}}{{if .Done}}[x] {{.Desc}}{{else}}[ ] {{.Desc}}{{end}}
-{{end}}
-{{end}}`
-
-type layout struct {
- TaskList []*entries
-}
-
-// Entries - set of todo items for a give task
-type entries struct {
- Title string
- List []*entry
-}
-
-// Entry - individual item of a set of tasks
-type entry struct {
- Desc string
- Done bool
-}
-
-func parse() (*layout, error) {
- l := &layout{
- TaskList: []*entries{},
- }
- fl, err := os.Open(".todo")
- if err != nil {
- return nil, err
- }
- sc := bufio.NewScanner(fl)
- for sc.Scan() {
- if sc.Text() == "" {
- continue
- }
- tl := &entries{
- Title: sc.Text(),
- List: parseEntries(sc),
- }
- l.TaskList = append(l.TaskList, tl)
- }
- if err := sc.Err(); err != nil {
- return nil, err
- }
-
- return l, nil
-}
-
-func parseEntries(sc *bufio.Scanner) []*entry {
- sc.Scan()
- en := []*entry{}
- for {
- d := sc.Text()
- if len(d) < 4 {
- return en
- }
- if err := sc.Err(); err != nil {
- log.Fatal(err)
- }
- switch d[:3] {
- case "[ ]":
- en = append(en, &entry{
- Desc: d[4:],
- Done: false,
- })
- case "[x]":
- en = append(en, &entry{
- Desc: d[4:],
- Done: true,
- })
- default:
- return en
- }
- sc.Scan()
- }
-}
-
func task(c *command) error {
if len(c.args) < 2 {
return errors.New("Too few arguments supplied")
}
- l, err := parse()
+ l, err := layoutFromTodoFile()
if err != nil && c.args[0] != "create" {
return err
}
@@ -96,14 +16,14 @@
switch c.args[0] {
case "create":
- l = &layout{
- TaskList: []*entries{},
+ l = &Layout{
+ TaskList: []*Entries{},
}
err = l.create(c.args[1])
if err != nil {
return err
}
- l.write()
+ writeTodo(l)
return nil
case "destroy":
err := l.destroy(c.args[1])
@@ -110,141 +30,28 @@
if err != nil {
return err
}
- l.write()
+ writeTodo(l)
return nil
case "add":
- if l.exists(c.args[1], c.args[2]) {
+ if l.taskExists(c.args[1], c.args[2]) {
return fmt.Errorf("Entry exists")
}
- l.add(c.args[1], c.args[2])
- l.write()
+ l.addTask(c.args[1], c.args[2])
+ writeTodo(l)
return nil
case "rm":
- if !l.exists(c.args[1], c.args[2]) {
+ if !l.taskExists(c.args[1], c.args[2]) {
return fmt.Errorf("No entry found")
}
- defer l.write()
- return l.rm(c.args[1], c.args[2])
+ defer writeTodo(l)
+ return l.rmTask(c.args[1], c.args[2])
case "toggle":
- if !l.exists(c.args[1], c.args[2]) {
+ if !l.taskExists(c.args[1], c.args[2]) {
return fmt.Errorf("No such task/entry")
}
- defer l.write()
- return l.toggle(c.args[1], c.args[2])
+ defer writeTodo(l)
+ return l.toggleTask(c.args[1], c.args[2])
default:
return fmt.Errorf("Command not supported: %v", c.args[0])
}
-}
-
-func (l *layout) destroy(title string) error {
- if _, err := os.Stat(".todo"); err != nil {
- return errors.New("Unable to locate .todo file")
- }
- for i, e := range l.TaskList {
- if e.Title != title {
- continue
- }
- if i < len(l.TaskList)-1 {
- copy(l.TaskList[i:], l.TaskList[i+1:])
- }
- l.TaskList = l.TaskList[:len(l.TaskList)-1]
- return nil
- }
- return errors.New("No such entry")
-}
-
-func (l *layout) create(title string) error {
- if len(title) < 1 {
- return errors.New("Unable to add nil entry")
- }
- l.TaskList = append(l.TaskList, &entries{
- Title: title,
- List: []*entry{},
- })
- return nil
-}
-
-func (l *layout) write() {
- wr, err := os.Create(".todo")
- defer wr.Close()
- if err != nil {
- log.Fatal(err)
- }
- t := template.Must(template.New("tmplt").Parse(tmplt))
- err = t.Execute(wr, l)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func (l *layout) exists(Title, item string) bool {
- for _, e := range l.TaskList {
- if e.Title != Title {
- continue
- }
- for _, t := range e.List {
- if t.Desc == item {
- return true
- }
- }
- }
- return false
-}
-
-func (l *layout) add(Title, item string) error {
- for _, e := range l.TaskList {
- // Found existing task, append to List
- if e.Title != Title {
- continue
- }
- e.List = append(e.List, &entry{
- Desc: item,
- Done: false,
- })
- return nil
- }
- line := &entry{
- Desc: item,
- Done: false,
- }
- l.TaskList = append(l.TaskList, &entries{
- Title: Title,
- List: []*entry{line},
- })
- return nil
-}
-
-func (l *layout) rm(Title, item string) error {
- for _, e := range l.TaskList {
- if e.Title != Title {
- continue
- }
- for i, t := range e.List {
- if t.Desc != item {
- continue
- }
- if i < len(e.List)-1 {
- copy(e.List[i:], e.List[i+1:])
- }
- e.List = e.List[:len(e.List)-1]
- return nil
- }
- }
- return fmt.Errorf("No such task/entry")
-}
-
-func (l *layout) toggle(Title, item string) error {
- for _, e := range l.TaskList {
- if e.Title != Title {
- continue
- }
- for _, t := range e.List {
- if t.Desc != item {
- continue
- }
- t.Done = !t.Done
- return nil
- }
- }
- return fmt.Errorf("No such task/entry")
}
--- a/write.go
+++ b/write.go
@@ -1,4 +1,32 @@
package main
-// TODO(halfwit): [#11] Write out to file
-// [ ] write() func
+import (
+ "log"
+ "os"
+ "text/template"
+)
+
+const tmplt = `{{range .TaskList}}{{.Title}}
+{{range .List}}{{if .Done}}[x] {{.Desc}}{{else}}[ ] {{.Desc}}{{end}}
+{{end}}
+{{end}}`
+
+// Writer that creates our normal file
+func writeTodo(l *Layout) {
+ wr, err := os.Create(".todo")
+ defer wr.Close()
+ if err != nil {
+ log.Fatal(err)
+ }
+ t := template.Must(template.New("tmplt").Parse(tmplt))
+ err = t.Execute(wr, l)
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+
+// Writer that outputs in dot format
+
+// Writer that outputs only leaves
+
+// Writer that outputs all nodes