diff options
Diffstat (limited to 'vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/eval.go')
-rw-r--r-- | vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/eval.go | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/eval.go b/vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/eval.go new file mode 100644 index 000000000..0554cda4f --- /dev/null +++ b/vendor/github.com/hashicorp/go-sockaddr/cmd/sockaddr/command/eval.go @@ -0,0 +1,158 @@ +package command + +import ( + "bytes" + "flag" + "fmt" + "io" + "os" + "strings" + + "github.com/hashicorp/errwrap" + "github.com/hashicorp/go-sockaddr/template" + "github.com/mitchellh/cli" +) + +type EvalCommand struct { + Ui cli.Ui + + // debugOutput emits framed output vs raw output. + debugOutput bool + + // flags is a list of options belonging to this command + flags *flag.FlagSet + + // rawInput disables wrapping the string in the text/template {{ }} + // handlebars. + rawInput bool + + // suppressNewline changes whether or not there's a newline between each + // arg passed to the eval subcommand. + suppressNewline bool +} + +// Description is the long-form command help. +func (c *EvalCommand) Description() string { + return `Parse the sockaddr template and evaluates the output. + +` + "The `sockaddr` library has the potential to be very complex, which is why the " + + "`sockaddr` command supports an `eval` subcommand in order to test configurations " + + "from the command line. The `eval` subcommand automatically wraps its input with " + + "the `{{` and `}}` template delimiters unless the `-r` command is specified, in " + + "which case `eval` parses the raw input. If the `template` argument passed to " + + "`eval` is a dash (`-`), then `sockaddr eval` will read from stdin and " + + "automatically sets the `-r` flag." + +} + +// Help returns the full help output expected by `sockaddr -h cmd` +func (c *EvalCommand) Help() string { + return MakeHelp(c) +} + +// InitOpts is responsible for setup of this command's configuration via the +// command line. InitOpts() does not parse the arguments (see parseOpts()). +func (c *EvalCommand) InitOpts() { + c.flags = flag.NewFlagSet("eval", flag.ContinueOnError) + c.flags.Usage = func() { c.Ui.Output(c.Help()) } + c.flags.BoolVar(&c.debugOutput, "d", false, "Debug output") + c.flags.BoolVar(&c.suppressNewline, "n", false, "Suppress newlines between args") + c.flags.BoolVar(&c.rawInput, "r", false, "Suppress wrapping the input with {{ }} delimiters") +} + +// Run executes this command. +func (c *EvalCommand) Run(args []string) int { + if len(args) == 0 { + c.Ui.Error(c.Help()) + return 1 + } + + c.InitOpts() + tmpls, err := c.parseOpts(args) + if err != nil { + if errwrap.Contains(err, "flag: help requested") { + return 0 + } + return 1 + } + inputs, outputs := make([]string, len(tmpls)), make([]string, len(tmpls)) + var rawInput, readStdin bool + for i, in := range tmpls { + if readStdin { + break + } + + rawInput = c.rawInput + if in == "-" { + rawInput = true + var f io.Reader = os.Stdin + var buf bytes.Buffer + if _, err := io.Copy(&buf, f); err != nil { + c.Ui.Error(fmt.Sprintf("[ERROR]: Error reading from stdin: %v", err)) + return 1 + } + in = buf.String() + if len(in) == 0 { + return 0 + } + readStdin = true + } + inputs[i] = in + + if !rawInput { + in = `{{` + in + `}}` + inputs[i] = in + } + + out, err := template.Parse(in) + if err != nil { + c.Ui.Error(fmt.Sprintf("ERROR[%d] in: %q\n[%d] msg: %v\n", i, in, i, err)) + return 1 + } + outputs[i] = out + } + + if c.debugOutput { + for i, out := range outputs { + c.Ui.Output(fmt.Sprintf("[%d] in: %q\n[%d] out: %q\n", i, inputs[i], i, out)) + if i != len(outputs)-1 { + if c.debugOutput { + c.Ui.Output(fmt.Sprintf("---\n")) + } + } + } + } else { + sep := "\n" + if c.suppressNewline { + sep = "" + } + c.Ui.Output(strings.Join(outputs, sep)) + } + + return 0 +} + +// Synopsis returns a terse description used when listing sub-commands. +func (c *EvalCommand) Synopsis() string { + return `Evaluates a sockaddr template` +} + +// Usage is the one-line usage description +func (c *EvalCommand) Usage() string { + return `sockaddr eval [options] [template ...]` +} + +// VisitAllFlags forwards the visitor function to the FlagSet +func (c *EvalCommand) VisitAllFlags(fn func(*flag.Flag)) { + c.flags.VisitAll(fn) +} + +// parseOpts is responsible for parsing the options set in InitOpts(). Returns +// a list of non-parsed flags. +func (c *EvalCommand) parseOpts(args []string) ([]string, error) { + if err := c.flags.Parse(args); err != nil { + return nil, err + } + + return c.flags.Args(), nil +} |