From 6022248a2feece93a2af7ec29cdde3d49ef973ec Mon Sep 17 00:00:00 2001 From: Paolo Donadeo Date: Tue, 25 Nov 2025 17:26:12 +0100 Subject: [PATCH] feat: add cobra CLI with input/output flags and debug option - Add --input/-i and --output/-o flags for file selection - Add --debug flag to print intermediate JSON to stderr - Print errors during parsing --- go.mod | 7 +++++ go.sum | 10 +++++++ main.go | 82 +++++++++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 82 insertions(+), 17 deletions(-) create mode 100644 go.sum diff --git a/go.mod b/go.mod index 04651c4..d15be14 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,10 @@ module git.donadeo.net/pdonadeo/todotxt2remind go 1.24.1 + +require github.com/spf13/cobra v1.10.1 + +require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/pflag v1.0.9 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e613680 --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= +github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index c9e7e38..cafdc88 100644 --- a/main.go +++ b/main.go @@ -3,29 +3,77 @@ package main import ( "encoding/json" "fmt" + "io" "os" "git.donadeo.net/pdonadeo/todotxt2remind/internal/parser" + "github.com/spf13/cobra" +) + +var ( + inputFile string + outputFile string + debug bool + version = "1" ) func main() { - if len(os.Args) < 2 { - fmt.Fprintf(os.Stderr, "usage: example /path/to/todo.txt\n") - os.Exit(2) - } - f, err := os.Open(os.Args[1]) - if err != nil { - panic(err) - } - defer func() { _ = f.Close() }() + rootCmd := &cobra.Command{ + Use: "todotxt2remind", + Short: "Convert a todo.txt file to Remind format", + Long: "Reads tasks from todo.txt format and outputs Remind-compatible entries.", + Run: func(cmd *cobra.Command, args []string) { + var in io.Reader = os.Stdin + if inputFile != "" { + f, err := os.Open(inputFile) + if err != nil { + fmt.Fprintf(os.Stderr, "error opening input file: %v\n", err) + os.Exit(2) + } + defer func() { _ = f.Close() }() + in = f + } - tasks, errors := parser.ParseReader(f) - if len(errors) > 0 { - fmt.Fprintf(os.Stderr, "errors while parsing:\n") - for _, e := range errors { - fmt.Fprintf(os.Stderr, " - %v\n", e) - } + tasks, errors := parser.ParseReader(in) + if len(errors) > 0 { + fmt.Fprintf(os.Stderr, "errors while parsing:\n") + for _, e := range errors { + fmt.Fprintf(os.Stderr, " - %v\n", e) + } + } + + if debug { + b, _ := json.MarshalIndent(tasks, "", " ") + fmt.Fprintf(os.Stderr, "%s\n", string(b)) + } + + var out io.Writer = os.Stdout + if outputFile != "" { + f, err := os.Create(outputFile) + if err != nil { + fmt.Fprintf(os.Stderr, "error opening output file: %v\n", err) + os.Exit(2) + } + defer func() { _ = f.Close() }() + out = f + } + + for _, t := range tasks { + rem := t.ToRemind() + if rem == "" { + continue + } + _, _ = fmt.Fprintf(out, "%s\n", rem) + } + }, } - b, _ := json.MarshalIndent(tasks, "", " ") - fmt.Println(string(b)) + + rootCmd.Flags().StringVarP(&inputFile, "input", "i", "", "Input file (default: stdin)") + rootCmd.Flags().StringVarP(&outputFile, "output", "o", "", "Output file (default: stdout)") + rootCmd.Flags().BoolVar(&debug, "debug", false, "Print intermediate JSON to stderr") + rootCmd.Version = version + rootCmd.Flags().BoolP("version", "v", false, "Show version and exit") + rootCmd.SetVersionTemplate(fmt.Sprintf("todotxt2remind version %s\n", version)) + + _ = rootCmd.Execute() }