ref: 51eb2ed06f13e1477ebe3ebf7675688c8f8e1246
parent: d19400c6e709f42f685c96c62426213fae4d91ec
author: Michael Misch <michaelmisch1985@gmail.com>
date: Wed Nov 27 17:58:37 PST 2019
Fix readme, find .todo files automatically, and implement destroy
--- a/README.md
+++ b/README.md
@@ -58,23 +58,22 @@
```
To add an entry into a particular task, such as the last line of BUG #92930 is trivial:
-`todo add entry 'BUG #92930' "polygon.go: Hand back better error info to the calling function"`
+`todo task add 'BUG #92930' "polygon.go: Hand back better error info to the calling function"`
You can also use stdin:
-`some function | todo add entry someentry`
+`some function | todo task add someentry`
If for some reason you wish to remove an entry, you can use the complement to `add`, `rm`.
-`todo remove entry 'BUG #92930'`
+`todo task rm 'BUG #92930' <index|string>`
Since .todo files are simply text files, you can also achieve any of the above by opening and editing the file by hand.
## Completing tasks in .todo files
-The following commands modify the state of a given entry's task:
+The following command modifies the state of a given entry's task:
- `todo task toggle <entry> <index|string>`
- - `todo task rm <entry> <index|string>`
For example, to toggle the completion of MyType implementing ReaderAt:
@@ -97,7 +96,7 @@
To add something as a child dependency, `todo add child <parent name> <child name>`. From the above examples, you would issue `todo add child 'BUG #01209' 'BUG #92930'`, or equivilently `todo add parent 'BUG #92930' 'BUG #01209'`.
-Arbitrarily many dependencies can be added between arbitrary pieces within the current working source tree.
+Arbitrarily many dependencies can be added between arbitrary pieces within the current working source tree.
## Commands of intrigue
- `todo init` will create, if none exists, the backing Makefile-like file used internally
--- a/task.go
+++ b/task.go
@@ -6,6 +6,9 @@
"fmt"
"log"
"os"
+ "path"
+ "path/filepath"
+ "strings"
"text/template"
)
@@ -87,24 +90,62 @@
}
}
+// We want to return any matched string for entry, otherwise return $dirname.todo of current directory
+func findEntry(entry string) string {
+ wd, _ := os.Getwd()
+ match := path.Base(wd) + ".todo"
+
+ filepath.Walk(".", func(p string, info os.FileInfo, err error) error {
+ if path.Ext(p) != ".todo" {
+ return nil
+ }
+ // Found a file! Search for entry
+ f, err := os.Open(p)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ if strings.Contains(scanner.Text(), entry) {
+ match = p
+ return filepath.SkipDir
+ }
+ }
+ return nil
+ })
+ return match
+}
+
func task(c *command) error {
if len(c.args) < 2 {
return errors.New("Too few arguments supplied")
}
- //fp, err := findEntry(c.args[1])
- //if err != nil {
- //return err
- //}
- fp := "test"
+ fp := findEntry(c.args[1])
l, err := parse(fp)
- if err != nil {
+ if err != nil && c.args[0] != "create" {
return err
}
switch c.args[0] {
case "create":
- defer l.write()
- return l.create(c.args[1])
+ l = &layout{
+ TaskList: []*entries{},
+ file: fp,
+ }
+ err = l.create(c.args[1])
+ if err != nil {
+ return err
+ }
+ l.write()
+ return nil
+ case "destroy":
+ err := l.destroy(c.args[1])
+ if err != nil {
+ return err
+ }
+ l.write()
+ return nil
case "add":
if l.exists(c.args[1], c.args[2]) {
return fmt.Errorf("Entry exists")
@@ -127,6 +168,23 @@
default:
return fmt.Errorf("Command not supported: %v", c.args[0])
}
+}
+
+func (l *layout) destroy(title string) error {
+ if _, err := os.Stat(l.file); 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 {
--- a/test
+++ /dev/null
@@ -1,9 +1,0 @@
-TODO #92930
-[x] Be awesome
-[ ] Make a cool demo
-[x] Impress everyone
-
-TODO #91210
-[ ] Watch Baywatch
-[ ] Learn To Swim
-