summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorDave Henderson <dhenderson@gmail.com>2021-01-17 15:46:57 -0500
committerDave Henderson <dhenderson@gmail.com>2021-01-17 16:48:48 -0500
commitd6c72218477357bc855f700ca6134d40cd96adf0 (patch)
tree0eb5a3f593fde1aafac6988aafe5ffbe197c2568 /internal
parent5835d0d688525716be902297193f78227994f5bf (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.go4
-rw-r--r--internal/cmd/config_test.go22
-rw-r--r--internal/cmd/main.go10
-rw-r--r--internal/cmd/main_test.go8
-rw-r--r--internal/config/configfile.go18
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 {