package main import ( "bytes" "io" "io/ioutil" "os" "path" "sort" "strings" "gogs.inhome.blapointe.com/bel/pttodo/pttodo" "gopkg.in/yaml.v2" ) const ( DUMP_ALL = "all" DUMP_TODO = "todo" DUMP_SCHEDULED = "scheduled" DUMP_DONE = "done" ) func main() { if err := _main(); err != nil { panic(err) } } func _main() error { config := getConfig() if err := add(&config); err != nil { return err } if err := edit(&config); err != nil { return err } return dump(config) } func merge(filepath string, mergeTargetFilePath string) error { baseReader, err := filePathReader(filepath) if err != nil { return err } baseB, err := ioutil.ReadAll(baseReader) if err != nil { return err } mergingReader, err := filePathReader(mergeTargetFilePath) if err != nil { return err } mergingB, err := ioutil.ReadAll(mergingReader) if err != nil { return err } var base, merging pttodo.Root if err := yaml.Unmarshal(baseB, &base); err != nil { return err } if err := yaml.Unmarshal(mergingB, &merging); err != nil { return err } base.MergeIn(merging) tmppath, err := marshalRootToTempFile(base) if err != nil { return err } return os.Rename(tmppath, filepath) } func marshalRootToTempFile(root pttodo.Root) (string, error) { f, err := ioutil.TempFile(os.TempDir(), "tmp") if err != nil { return "", err } f.Close() os.Remove(f.Name()) b, err := yaml.Marshal(root) if err != nil { return "", err } filepath := f.Name() + ".yaml" err = ioutil.WriteFile(filepath, b, os.ModePerm) return filepath, err } func filePathReader(path string) (io.Reader, error) { if path == "-" { return os.Stdin, nil } b, err := ioutil.ReadFile(path) if os.IsNotExist(err) { return bytes.NewReader([]byte("{}")), nil } if err != nil { return nil, err } return bytes.NewReader(b), nil } func listDir(dname string) ([]string, error) { entries, err := os.ReadDir(dname) if err != nil { return nil, err } paths := make([]string, 0, len(entries)) for i := range entries { if entries[i].IsDir() { continue } if strings.HasPrefix(path.Base(entries[i].Name()), ".") { continue } paths = append(paths, path.Join(dname, entries[i].Name())) } sort.Slice(paths, func(i, j int) bool { if path.Base(paths[i]) == "root.yaml" { return true } return paths[i] < paths[j] }) return paths, nil }