diff options
| author | Dave Henderson <dhenderson@gmail.com> | 2021-01-17 15:46:57 -0500 |
|---|---|---|
| committer | Dave Henderson <dhenderson@gmail.com> | 2021-01-17 16:48:48 -0500 |
| commit | d6c72218477357bc855f700ca6134d40cd96adf0 (patch) | |
| tree | 0eb5a3f593fde1aafac6988aafe5ffbe197c2568 /internal | |
| parent | 5835d0d688525716be902297193f78227994f5bf (diff) | |
Inject stdin/out/err instead of always using os.Stdin/out/err
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/cmd/config.go | 4 | ||||
| -rw-r--r-- | internal/cmd/config_test.go | 22 | ||||
| -rw-r--r-- | internal/cmd/main.go | 10 | ||||
| -rw-r--r-- | internal/cmd/main_test.go | 8 | ||||
| -rw-r--r-- | internal/config/configfile.go | 18 |
5 files changed, 46 insertions, 16 deletions
diff --git a/internal/cmd/config.go b/internal/cmd/config.go index 3db450af..f45f5ff1 100644 --- a/internal/cmd/config.go +++ b/internal/cmd/config.go @@ -48,6 +48,10 @@ func loadConfig(cmd *cobra.Command, args []string) (*config.Config, error) { return nil, err } + cfg.Stdin = cmd.InOrStdin() + cfg.Stdout = cmd.OutOrStdout() + cfg.Stderr = cmd.ErrOrStderr() + // reset defaults before validation cfg.ApplyDefaults() diff --git a/internal/cmd/config_test.go b/internal/cmd/config_test.go index aa5e09f3..1bc82e09 100644 --- a/internal/cmd/config_test.go +++ b/internal/cmd/config_test.go @@ -1,6 +1,7 @@ package cmd import ( + "bytes" "context" "fmt" "os" @@ -63,7 +64,12 @@ func TestLoadConfig(t *testing.T) { fs = afero.NewMemMapFs() defer func() { fs = afero.NewOsFs() }() + stdin, stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{} cmd := &cobra.Command{} + cmd.SetIn(stdin) + cmd.SetOut(stdout) + cmd.SetErr(stderr) + cmd.Args = optionalExecArgs cmd.Flags().StringSlice("file", []string{"-"}, "...") cmd.Flags().StringSlice("out", []string{"-"}, "...") @@ -80,9 +86,11 @@ func TestLoadConfig(t *testing.T) { OutputFiles: []string{"-"}, LDelim: "{{", RDelim: "}}", - PostExecInput: os.Stdin, - OutWriter: os.Stdout, + PostExecInput: stdin, PluginTimeout: 5 * time.Second, + Stdin: stdin, + Stdout: stdout, + Stderr: stderr, } assert.NoError(t, err) assert.EqualValues(t, expected, out) @@ -94,9 +102,11 @@ func TestLoadConfig(t *testing.T) { OutputFiles: []string{"-"}, LDelim: "{{", RDelim: "}}", - PostExecInput: os.Stdin, - OutWriter: os.Stdout, + PostExecInput: stdin, PluginTimeout: 5 * time.Second, + Stdin: stdin, + Stdout: out.Stdout, + Stderr: stderr, } assert.NoError(t, err) assert.EqualValues(t, expected, out) @@ -110,9 +120,11 @@ func TestLoadConfig(t *testing.T) { ExecPipe: true, PostExec: []string{"tr", "[a-z]", "[A-Z]"}, PostExecInput: out.PostExecInput, - OutWriter: out.PostExecInput, OutputFiles: []string{"-"}, PluginTimeout: 5 * time.Second, + Stdin: stdin, + Stdout: out.Stdout, + Stderr: stderr, } assert.NoError(t, err) assert.EqualValues(t, expected, out) diff --git a/internal/cmd/main.go b/internal/cmd/main.go index 3c7862d5..9217a725 100644 --- a/internal/cmd/main.go +++ b/internal/cmd/main.go @@ -18,7 +18,7 @@ import ( ) // postRunExec - if templating succeeds, the command following a '--' will be executed -func postRunExec(ctx context.Context, cfg *config.Config) error { +func postRunExec(ctx context.Context, cfg *config.Config, stdout, stderr io.Writer) error { args := cfg.PostExec if len(args) > 0 { log := zerolog.Ctx(ctx) @@ -29,8 +29,8 @@ func postRunExec(ctx context.Context, cfg *config.Config) error { // nolint: gosec c := exec.CommandContext(ctx, name, args...) c.Stdin = cfg.PostExecInput - c.Stderr = os.Stderr - c.Stdout = os.Stdout + c.Stderr = stderr + c.Stdout = stdout // make sure all signals are propagated sigs := make(chan os.Signal, 1) @@ -98,7 +98,7 @@ func NewGomplateCmd() *cobra.Command { // Note: once stdin/out/err are externalized we should only do this // if stdout isn't ending with its own newline! if len(cfg.OutputFiles) == 0 || (len(cfg.OutputFiles) == 1 && cfg.OutputFiles[0] == "-") && !cfg.ExecPipe { - fmt.Fprintf(os.Stderr, "\n") + fmt.Fprintf(cmd.ErrOrStderr(), "\n") } log.Debug().Int("templatesRendered", gomplate.Metrics.TemplatesProcessed). Int("errors", gomplate.Metrics.Errors). @@ -108,7 +108,7 @@ func NewGomplateCmd() *cobra.Command { if err != nil { return err } - return postRunExec(ctx, cfg) + return postRunExec(ctx, cfg, cmd.OutOrStdout(), cmd.ErrOrStderr()) }, Args: optionalExecArgs, } diff --git a/internal/cmd/main_test.go b/internal/cmd/main_test.go index 5c688443..678d5979 100644 --- a/internal/cmd/main_test.go +++ b/internal/cmd/main_test.go @@ -1,6 +1,7 @@ package cmd import ( + "bytes" "context" "testing" @@ -47,4 +48,11 @@ func TestRunMain(t *testing.T) { err = Main(ctx, []string{"--bogus"}, nil, nil, nil) assert.Error(t, err) + + stdin := &bytes.Buffer{} + stdout := &bytes.Buffer{} + stderr := &bytes.Buffer{} + err = Main(ctx, []string{"-i", "hello"}, stdin, stdout, stderr) + assert.NoError(t, err) + assert.Equal(t, "hello", stdout.String()) } diff --git a/internal/config/configfile.go b/internal/config/configfile.go index a20c95cb..9969648e 100644 --- a/internal/config/configfile.go +++ b/internal/config/configfile.go @@ -14,6 +14,7 @@ import ( "strings" "time" + "github.com/hairyhenderson/gomplate/v3/internal/iohelpers" "github.com/pkg/errors" "gopkg.in/yaml.v3" ) @@ -59,8 +60,11 @@ type Config struct { ExtraHeaders map[string]http.Header `yaml:"-"` // internal use only, can't be injected in YAML - PostExecInput io.ReadWriter `yaml:"-"` - OutWriter io.Writer `yaml:"-"` + PostExecInput io.Reader `yaml:"-"` + + Stdin io.Reader `yaml:"-"` + Stdout io.Writer `yaml:"-"` + Stderr io.Writer `yaml:"-"` } var cfgContextKey = struct{}{} @@ -452,12 +456,14 @@ func (c *Config) ApplyDefaults() { } if c.ExecPipe { - c.PostExecInput = &bytes.Buffer{} - c.OutWriter = c.PostExecInput + pipe := &bytes.Buffer{} + c.PostExecInput = pipe c.OutputFiles = []string{"-"} + + // --exec-pipe redirects standard out to the out pipe + c.Stdout = &iohelpers.NopCloser{Writer: pipe} } else { - c.PostExecInput = os.Stdin - c.OutWriter = os.Stdout + c.PostExecInput = c.Stdin } if c.PluginTimeout == 0 { |
