diff --git a/README.md b/README.md index db9e5da0..a0e5a4a4 100644 --- a/README.md +++ b/README.md @@ -1124,13 +1124,13 @@ mysetting: | The possibility is endless. Try importing values from your golang app, bash script, jsonnet, or anything! -Then `execEnvs` same as `exec`, but it can receive a dict as the envs. +Then `envExec` same as `exec`, but it can receive a dict as the envs. -A usual usage of `execEnvs` would look like this: +A usual usage of `envExec` would look like this: ```yaml mysetting: | -{{ execEnvs (dict "envkey" "envValue") "./mycmd" (list "arg1" "arg2" "--flag1") | indent 2 }} +{{ envExec (dict "envkey" "envValue") "./mycmd" (list "arg1" "arg2" "--flag1") | indent 2 }} ``` diff --git a/pkg/tmpl/context_funcs.go b/pkg/tmpl/context_funcs.go index c2f00159..d473c862 100644 --- a/pkg/tmpl/context_funcs.go +++ b/pkg/tmpl/context_funcs.go @@ -20,7 +20,7 @@ type Values = map[string]interface{} func (c *Context) createFuncMap() template.FuncMap { funcMap := template.FuncMap{ - "execEnvs": c.ExecEnvs, + "envExec": c.EnvExec, "exec": c.Exec, "isFile": c.IsFile, "readFile": c.ReadFile, @@ -50,7 +50,7 @@ func (c *Context) createFuncMap() template.FuncMap { } // TODO: in the next major version, remove this function. -func (c *Context) ExecEnvs(envs map[string]string, command string, args []interface{}, inputs ...string) (string, error) { +func (c *Context) EnvExec(envs map[string]interface{}, command string, args []interface{}, inputs ...string) (string, error) { var input string if len(inputs) > 0 { input = inputs[0] @@ -66,6 +66,18 @@ func (c *Context) ExecEnvs(envs map[string]string, command string, args []interf } } + envsLen := len(envs) + strEnvs := make(map[string]string, envsLen) + + for k, v := range envs { + switch v.(type) { + case string: + strEnvs[k] = fmt.Sprintf("%v", v) + default: + return "", fmt.Errorf("unexpected type of env \"%s\" in envs %v at index %s", reflect.TypeOf(v), envs, k) + } + } + cmd := exec.Command(command, strArgs...) cmd.Dir = c.basePath if envs != nil { @@ -128,7 +140,7 @@ func (c *Context) ExecEnvs(envs map[string]string, command string, args []interf } func (c *Context) Exec(command string, args []interface{}, inputs ...string) (string, error) { - return c.ExecEnvs(nil, command, args, inputs...) + return c.EnvExec(nil, command, args, inputs...) } func (c *Context) IsFile(filename string) (bool, error) { diff --git a/pkg/tmpl/context_funcs_test.go b/pkg/tmpl/context_funcs_test.go index ed1a2116..7806ddea 100644 --- a/pkg/tmpl/context_funcs_test.go +++ b/pkg/tmpl/context_funcs_test.go @@ -268,9 +268,9 @@ func TestExec(t *testing.T) { require.Error(t, err, "Expected error to be returned when executing command with non-zero exit code") } -// TestExecEnvs tests that ExecEnvs returns the expected output. +// TestEnvExec tests that EnvExec returns the expected output. // TODO: in the next major version, this test should be removed. -func TestExecEnvs(t *testing.T) { +func TestEnvExec(t *testing.T) { ctx := &Context{basePath: "."} expected := "foo" @@ -278,14 +278,20 @@ func TestExecEnvs(t *testing.T) { testKey := "testkey" // test that the command is executed with environment variables - output, err := ctx.ExecEnvs(map[string]string{testKey: "foo"}, "bash", []interface{}{"-c", fmt.Sprintf("echo -n $%s", testKey)}, "") + output, err := ctx.EnvExec(map[string]interface{}{testKey: "foo"}, "bash", []interface{}{"-c", fmt.Sprintf("echo -n $%s", testKey)}, "") require.Nilf(t, err, "Expected no error to be returned when executing command with environment variables") require.Equalf(t, expected, output, "Expected %s to be returned when executing command with environment variables", expected) + // test that the command is executed with invalid environment variables + output, err = ctx.EnvExec(map[string]interface{}{testKey: 123}, "bash", []interface{}{"-c", fmt.Sprintf("echo -n $%s", testKey)}, "") + + require.Errorf(t, err, "Expected error to be returned when executing command with invalid environment variables") + require.Emptyf(t, output, "Expected empty string to be returned when executing command with invalid environment variables") + // test that the command is executed with no environment variables - output, err = ctx.ExecEnvs(nil, "bash", []interface{}{"-c", fmt.Sprintf("echo -n $%s", testKey)}, "") + output, err = ctx.EnvExec(nil, "bash", []interface{}{"-c", fmt.Sprintf("echo -n $%s", testKey)}, "") require.Nilf(t, err, "Expected no error to be returned when executing command with no environment variables") require.Emptyf(t, output, "Expected empty string to be returned when executing command with no environment variables") @@ -293,7 +299,7 @@ func TestExecEnvs(t *testing.T) { // test that the command is executed with os environment variables os.Setenv(testKey, "foo") defer os.Unsetenv(testKey) - output, err = ctx.ExecEnvs(nil, "bash", []interface{}{"-c", fmt.Sprintf("echo -n $%s", testKey)}, "") + output, err = ctx.EnvExec(nil, "bash", []interface{}{"-c", fmt.Sprintf("echo -n $%s", testKey)}, "") require.Nilf(t, err, "Expected no error to be returned when executing command with environment variables")