Skip to content

Commit

Permalink
yaml-parse: remove --file and read from args
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidGamba committed Feb 15, 2023
1 parent 60269cd commit 5ff8d8b
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 50 deletions.
16 changes: 8 additions & 8 deletions yaml-parse/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -49,41 +49,41 @@ 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
----

.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
----

.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
Expand All @@ -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
Expand Down
16 changes: 16 additions & 0 deletions yaml-parse/changelog.adoc
Original file line number Diff line number Diff line change
@@ -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
105 changes: 63 additions & 42 deletions yaml-parse/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
package main

import (
"context"
"errors"
"fmt"
"io/ioutil"
"io"
"log"
"os"
"strings"
Expand All @@ -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))
Expand All @@ -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("<file>...")
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 <file> 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 {
Expand All @@ -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 <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 {
Expand Down Expand Up @@ -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
}

0 comments on commit 5ff8d8b

Please sign in to comment.