Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New plugin args option #1698

Merged
merged 1 commit into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ COPY --from=build /bin/gomplate_${TARGETOS}-${TARGETARCH}${TARGETVARIANT} /gompl

ENTRYPOINT [ "/gomplate" ]

FROM alpine:3.17 AS gomplate-alpine
FROM alpine:3.17.3 AS gomplate-alpine

ARG VCS_REF
ARG TARGETOS
Expand Down
37 changes: 34 additions & 3 deletions docs/content/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,15 +304,19 @@ See [`--plugin`](../usage/#plugin).
A map that configures custom functions for use in the templates. The key is the
name of the function, and the value configures the plugin. The value is a map
containing the command (`cmd`) and the options `pipe` (boolean) and `timeout`
(duration).
(duration). A list of optional arguments to always pass to the plugin can be set
with `args` (array of strings).

Alternatively, the value can be a string, which sets `cmd`.
Alternatively, the value can be a string, which sets only `cmd`.

```yaml
in: '{{ "hello world" | figlet | lolcat }}'
in: '{{ "world" | figlet | lolcat }}'
plugins:
figlet:
cmd: /usr/local/bin/figlet
args:
- oh
- hello
pipe: true
timeout: 1s
lolcat: /home/hairyhenderson/go/bin/lolcat
Expand All @@ -322,6 +326,33 @@ plugins:

The path to the plugin executable (or script) to run.

### `args`

An array of optional arguments to always pass to the plugin. These arguments
will be passed _before_ any arguments provided in the template.

For example:

```yaml
plugins:
echo:
cmd: /bin/echo
args:
- foo
- bar
```

With this template:
```
{{ echo "baz" }}
```

Will result the command being called like this:

```console
$ /bin/echo foo bar baz
```

### `pipe`

Whether to pipe the final argument of the template function to the plugin's
Expand Down
6 changes: 4 additions & 2 deletions internal/config/configfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ func (d DataSource) mergeFrom(o DataSource) DataSource {

type PluginConfig struct {
Cmd string
Timeout time.Duration
Pipe bool
Args []string `yaml:"args,omitempty"`
Timeout time.Duration `yaml:"timeout,omitempty"`
Pipe bool `yaml:"pipe,omitempty"`
}

// UnmarshalYAML - satisfy the yaml.Umarshaler interface - plugin configs can
Expand All @@ -178,6 +179,7 @@ func (p *PluginConfig) UnmarshalYAML(value *yaml.Node) error {

type raw struct {
Cmd string
Args []string
Timeout time.Duration
Pipe bool
}
Expand Down
7 changes: 4 additions & 3 deletions internal/config/configfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -626,16 +626,17 @@ pluginTimeout: 500ms
c = &Config{
Plugins: map[string]PluginConfig{
"foo": {
Cmd: "bar",
Pipe: true,
Cmd: "bar",
Timeout: 1 * time.Second,
Pipe: true,
},
},
}
expected = `---
plugins:
foo:
cmd: bar
timeout: 0s
timeout: 1s
pipe: true
`

Expand Down
14 changes: 14 additions & 0 deletions internal/tests/integration/plugins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,17 @@ plugins:
assert.Equal(t, "", e)
assert.Equal(t, "=hi=thZrZ", o)
}

func TestPlugins_Args(t *testing.T) {
tmpDir := setupPluginsTest(t)

writeConfig(t, tmpDir, `in: '{{ echo "world" }}'
plugins:
echo:
cmd: echo
args: [ oh, hello ]
`)

o, e, err := cmd(t).withDir(tmpDir.Path()).run()
assertSuccess(t, o, e, err, "oh hello world\n")
}
8 changes: 8 additions & 0 deletions plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func bindPlugins(ctx context.Context, cfg *config.Config, funcMap template.FuncM
Timeout: timeout,
Pipe: v.Pipe,
Stderr: cfg.Stderr,
Args: v.Args,
})
}

Expand All @@ -49,6 +50,10 @@ type PluginOpts struct {
// Defaults to os.Stderr.
Stderr io.Writer

// Args are additional arguments to pass to the plugin. These precede any
// arguments passed to the plugin function at runtime.
Args []string

// Timeout is the maximum amount of time to wait for the plugin to complete.
// Defaults to 5 seconds.
Timeout time.Duration
Expand All @@ -74,6 +79,7 @@ func PluginFunc(ctx context.Context, cmd string, opts PluginOpts) func(...interf
plugin := &plugin{
ctx: ctx,
path: cmd,
args: opts.Args,
timeout: timeout,
pipe: opts.Pipe,
stderr: stderr,
Expand All @@ -87,6 +93,7 @@ type plugin struct {
ctx context.Context
stderr io.Writer
path string
args []string
timeout time.Duration
pipe bool
}
Expand Down Expand Up @@ -122,6 +129,7 @@ func findPowershell() string {

func (p *plugin) run(args ...interface{}) (interface{}, error) {
a := conv.ToStrings(args...)
a = append(p.args, a...)

name, a := p.buildCommand(a)

Expand Down
24 changes: 24 additions & 0 deletions plugins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,30 @@ func TestRun(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, "", stderr.String())
assert.Equal(t, "foo", strings.TrimSpace(out.(string)))

p = &plugin{
ctx: ctx,
timeout: 500 * time.Millisecond,
stderr: stderr,
path: "echo",
args: []string{"foo", "bar"},
}
out, err = p.run()
require.NoError(t, err)
assert.Equal(t, "", stderr.String())
assert.Equal(t, "foo bar", strings.TrimSpace(out.(string)))

p = &plugin{
ctx: ctx,
timeout: 500 * time.Millisecond,
stderr: stderr,
path: "echo",
args: []string{"foo", "bar"},
}
out, err = p.run("baz", "qux")
require.NoError(t, err)
assert.Equal(t, "", stderr.String())
assert.Equal(t, "foo bar baz qux", strings.TrimSpace(out.(string)))
}

func ExamplePluginFunc() {
Expand Down