diff --git a/docs/content/config.md b/docs/content/config.md index 9e488e8a1..dbdc5ce0b 100644 --- a/docs/content/config.md +++ b/docs/content/config.md @@ -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 @@ -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 diff --git a/plugins.go b/plugins.go index 518f0142d..0c0560a3a 100644 --- a/plugins.go +++ b/plugins.go @@ -49,6 +49,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 @@ -74,6 +78,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, @@ -87,6 +92,7 @@ type plugin struct { ctx context.Context stderr io.Writer path string + args []string timeout time.Duration pipe bool } @@ -122,6 +128,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) diff --git a/plugins_test.go b/plugins_test.go index c38c57016..8a8eb18ab 100644 --- a/plugins_test.go +++ b/plugins_test.go @@ -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() {