From bf10c00708ca0862f404e46ee341b88fb29d44d7 Mon Sep 17 00:00:00 2001 From: Bel LaPointe Date: Sun, 2 Jan 2022 20:07:52 -0500 Subject: [PATCH] add cli -g to merge in a file --- cmd/pttodo-cli/cli.go | 118 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 105 insertions(+), 13 deletions(-) diff --git a/cmd/pttodo-cli/cli.go b/cmd/pttodo-cli/cli.go index 7e21ecc..557e886 100644 --- a/cmd/pttodo-cli/cli.go +++ b/cmd/pttodo-cli/cli.go @@ -36,12 +36,18 @@ func _main() error { defaultFilepath = "-" } filepath := flag.String("f", defaultFilepath, "($PTTODO_FILE) path to yaml file") + filepathToMergeIn := flag.String("g", "", "path to yaml file to merge into -f") root := flag.String("root", DUMP_TODO, "path to pretty print ("+fmt.Sprint([]string{DUMP_ALL, DUMP_TODO, DUMP_SCHEDULED, DUMP_DONE})+")") tags := flag.String("tags", "", "csv of all tags to find") search := flag.String("search", "", "fts case insensitive") e := flag.Bool("e", false, "edit file") dry := flag.Bool("dry", false, "dry run") flag.Parse() + if *filepathToMergeIn != "" { + if err := merge(*dry, *filepath, *filepathToMergeIn); err != nil { + return err + } + } if *e { if err := edit(*dry, *filepath); err != nil { return err @@ -54,6 +60,28 @@ func _main() error { return dump(*dry, os.Stdout, *filepath, tagslist, *search, *root) } +func verifyRoot(root pttodo.Root) error { + f, err := ioutil.TempFile(os.TempDir(), "tmp") + if err != nil { + return err + } + f.Close() + tempFile := f.Name() + b, err := yaml.Marshal(root) + if err != nil { + return err + } + if err := ioutil.WriteFile(tempFile, b, os.ModePerm); err != nil { + return err + } + defer os.Remove(tempFile) + return verifyFile(tempFile) +} + +func verifyFile(path string) error { + return dump(true, io.Discard, path, nil, "", DUMP_ALL) +} + func edit(dry bool, filepath string) error { var tempFile string cp := func() error { @@ -115,10 +143,7 @@ func edit(dry bool, filepath string) error { return nil } verify := func() error { - if err := dump(true, io.Discard, tempFile, nil, "", DUMP_ALL); err != nil { - return fmt.Errorf("failed to verify %s: %v", tempFile, err) - } - return nil + return verifyFile(tempFile) } save := func() error { if dry { @@ -140,16 +165,69 @@ func edit(dry bool, filepath string) error { return nil } +func merge(dry bool, 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) + + if err := verifyRoot(base); err != nil { + return err + } + tmppath, err := marshalRootToTempFile(base) + if err != nil { + return err + } + if dry { + log.Printf("would've moved %s to %s when adding %s", tmppath, filepath, mergeTargetFilePath) + return nil + } + 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 dump(dry bool, writer io.Writer, filepath string, tags []string, search, rootDisplay string) error { - var reader io.Reader - if filepath == "-" { - reader = os.Stdin - } else { - b, err := ioutil.ReadFile(filepath) - if err != nil { - return err - } - reader = bytes.NewReader(b) + reader, err := filePathReader(filepath) + if err != nil { + return err } b, err := ioutil.ReadAll(reader) @@ -214,3 +292,17 @@ func dump(dry bool, writer io.Writer, filepath string, tags []string, search, ro } return os.WriteFile(filepath, b3, os.ModePerm) } + +func filePathReader(path string) (io.Reader, error) { + var reader io.Reader + if path == "-" { + reader = os.Stdin + } else { + b, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + reader = bytes.NewReader(b) + } + return reader, nil +}