diff --git a/yaml-parse/README.adoc b/yaml-parse/README.adoc index 592d8c9..9cc1081 100644 --- a/yaml-parse/README.adoc +++ b/yaml-parse/README.adoc @@ -32,7 +32,7 @@ bool: true .Print all contents ---- -$ yaml-parse -f test_data/test.yaml +$ yaml-parse test_data/test.yaml array: - element 1 - element 2 @@ -49,7 +49,7 @@ number: 123 .Print `array` ---- -$ yaml-parse -f test_data/test.yaml -k array +$ yaml-parse test_data/test.yaml -k array - element 1 - element 2 - element 3 @@ -57,13 +57,13 @@ $ yaml-parse -f test_data/test.yaml -k array .Print `array` first element ---- -$ yaml-parse -f test_data/test.yaml -k array -k 0 +$ yaml-parse test_data/test.yaml -k array -k 0 element 1 ---- .Print `array 2` ---- -$ yaml-parse -f test_data/test.yaml -k 'array 2' +$ yaml-parse test_data/test.yaml -k 'array 2' - key1: value1 - key2: value2 - key3: value3 @@ -71,19 +71,19 @@ $ yaml-parse -f test_data/test.yaml -k 'array 2' .Print `array 2` first element then map value ---- -$ yaml-parse -f test_data/test.yaml -k 'array 2' -k 0 -k key1 +$ yaml-parse test_data/test.yaml -k 'array 2' -k 0 -k key1 value1 ---- .Do the same with slash ---- -$ yaml-parse -f test_data/test.yaml -k 'array 2/0/key1' +$ yaml-parse test_data/test.yaml -k 'array 2/0/key1' value1 ---- .Add a json element to 'array 2' ---- -$ yaml-parse -f test_data/test.yaml --add '{ hola: mundo }' -k 'array 2' +$ yaml-parse test_data/test.yaml --add '{ hola: mundo }' -k 'array 2' array: - element 1 - element 2 @@ -101,7 +101,7 @@ number: 123 .Read the second document of a multi document YAML file ---- -$ yaml-parse -f test_data/multiple.yaml -d 2 +$ yaml-parse test_data/multiple.yaml -d 2 arreglo: - elemento 1 - elemento 2 diff --git a/yaml-parse/changelog.adoc b/yaml-parse/changelog.adoc new file mode 100644 index 0000000..507cfa8 --- /dev/null +++ b/yaml-parse/changelog.adoc @@ -0,0 +1,16 @@ += Changelog +:toc: + +== v0.2.0 Simplify usage + +* Remove -f option to read from file + +[source, diff] +---- +- yaml-parse -f test_data/test.yaml ++ yaml-parse test_data/test.yaml +---- + +* Remove replace directives in go.mod + +== v0.1.0 Initial release diff --git a/yaml-parse/main.go b/yaml-parse/main.go index 2056ed3..39c0b90 100644 --- a/yaml-parse/main.go +++ b/yaml-parse/main.go @@ -8,8 +8,10 @@ package main import ( + "context" + "errors" "fmt" - "io/ioutil" + "io" "log" "os" "strings" @@ -21,9 +23,9 @@ import ( // BuildMetadata - Provides the metadata part of the version information. var BuildMetadata = "dev" -const semVersion = "0.5.0" +const semVersion = "0.6.0" -var Logger = log.New(ioutil.Discard, "", log.LstdFlags) +var Logger = log.New(os.Stderr, "", log.LstdFlags) func main() { os.Exit(program(os.Args)) @@ -34,50 +36,65 @@ func program(args []string) int { opt.Self("", `Parses YAML input passed from file or piped to STDIN and filters it by key or index. Source: https://github.com/DavidGamba/dgtools`) - opt.Bool("help", false, opt.Alias("?")) - opt.Bool("debug", false) + opt.Bool("quiet", false, opt.GetEnv("QUIET")) opt.Bool("version", false, opt.Alias("V")) + opt.Bool("-", false, opt.Description("Read from STDIN")) opt.Bool("n", false, opt.Description("Remove trailing spaces.")) opt.Bool("silent", false, opt.Description("Don't print full context errors.")) opt.Bool("include", false, opt.Description("Include parent key if it is a map key.")) - opt.String("file", "", opt.Alias("f"), opt.ArgName("file"), opt.Description("YAML file to read.")) opt.String("add", "", opt.ArgName("yaml/json input"), opt.Description("Child input to add at the current location.")) opt.StringSlice("key", 1, 99, opt.Alias("k"), opt.ArgName("key/index"), opt.Description(`Key or index to descend to. Multiple keys allow to descend further. Indexes are positive integers.`)) opt.IntOptional("document", 1, opt.Description("Document number"), opt.Alias("d"), opt.ArgName("number")) - _, err := opt.Parse(os.Args[1:]) - if opt.Called("help") { - fmt.Println(opt.Help()) + opt.HelpSynopsisArgs("...") + opt.HelpCommand("help", opt.Alias("?")) + opt.SetCommandFn(Run) + remaining, err := opt.Parse(args[1:]) + if err != nil { + fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) return 1 } if opt.Called("version") { fmt.Printf("Version: %s+%s\n", semVersion, BuildMetadata) return 0 } - if err != nil { - fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) - return 1 - } - if opt.Called("debug") { - Logger.SetOutput(os.Stderr) - yamlutils.Logger.SetOutput(os.Stderr) + if opt.Called("quiet") { + Logger.SetOutput(io.Discard) } + Logger.Println(remaining) - err = realMain(opt) + ctx, cancel, done := getoptions.InterruptContext() + defer func() { cancel(); <-done }() + + err = opt.Dispatch(ctx, remaining) if err != nil { + if errors.Is(err, getoptions.ErrorHelpCalled) { + return 1 + } fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) return 1 } return 0 } -func realMain(opt *getoptions.GetOpt) error { - file := opt.Value("file").(string) +func Run(ctx context.Context, opt *getoptions.GetOpt, args []string) error { include := opt.Value("include").(bool) add := opt.Value("add").(string) keys := opt.Value("key").([]string) + useStdIn := opt.Value("-").(bool) + + if len(args) < 1 && !useStdIn { + fmt.Fprintf(os.Stderr, "ERROR: missing or STDIN input '-'\n") + fmt.Fprintf(os.Stderr, "%s", opt.Help(getoptions.HelpSynopsis)) + return getoptions.ErrorHelpCalled + } + + file := "-" + if len(args) > 0 && !useStdIn { + file = args[0] + } var xpath []string for _, k := range keys { @@ -86,29 +103,9 @@ func realMain(opt *getoptions.GetOpt) error { } Logger.Printf("path: '%s'\n", strings.Join(xpath, ",")) - // Check if stdin is pipe p or device D - statStdin, _ := os.Stdin.Stat() - stdinIsDevice := (statStdin.Mode() & os.ModeDevice) != 0 - - var err error - var ymlList []*yamlutils.YML - if !stdinIsDevice && !opt.Called("file") { - Logger.Printf("Reading from stdin\n") - reader := os.Stdin - ymlList, err = yamlutils.NewFromReader(reader) - if err != nil { - return fmt.Errorf("reading yaml from STDIN: %w", err) - } - } else { - Logger.Printf("Reading from file: %s\n", file) - if !opt.Called("file") { - return fmt.Errorf("missing argument '--file '") - } - ymlList, err = yamlutils.NewFromFile(file) - if err != nil { - fmt.Fprintf(os.Stderr, "ERROR: reading yaml file: %s\n", err) - os.Exit(1) - } + ymlList, err := readInput(ctx, useStdIn, file) + if err != nil { + return fmt.Errorf("failed to read input: %w", err) } if !opt.Called("document") && len(ymlList) > 1 { @@ -157,3 +154,27 @@ func realMain(opt *getoptions.GetOpt) error { fmt.Print(str) return nil } + +func readInput(ctx context.Context, useStdIn bool, file string) ([]*yamlutils.YML, error) { + // Check if stdin is pipe p or device D + statStdin, _ := os.Stdin.Stat() + stdinIsDevice := (statStdin.Mode() & os.ModeDevice) != 0 + + var err error + var ymlList []*yamlutils.YML + if !stdinIsDevice && useStdIn { + Logger.Printf("Reading from STDIN\n") + reader := os.Stdin + ymlList, err = yamlutils.NewFromReader(reader) + if err != nil { + return ymlList, fmt.Errorf("reading yaml from STDIN: %w", err) + } + } else { + Logger.Printf("Reading from file: %s\n", file) + ymlList, err = yamlutils.NewFromFile(file) + if err != nil { + return ymlList, fmt.Errorf("reading yaml file: %w", err) + } + } + return ymlList, nil +}