diff --git a/basher.go b/basher.go index b30e12e..c729142 100644 --- a/basher.go +++ b/basher.go @@ -2,6 +2,7 @@ package basher import ( + "fmt" "io" "io/ioutil" "log" @@ -223,6 +224,14 @@ func (c *Context) buildEnvfile() (string, error) { continue } + if isBashFunc(pair[0], pair[1]) { + bash_function_name := strings.TrimPrefix(pair[0], "BASH_FUNC_") + bash_function_name = strings.TrimSuffix(bash_function_name, "%%") + file.Write([]byte(fmt.Sprintf("%s%s\n", bash_function_name, pair[1]))) + file.Write([]byte(fmt.Sprintf("export -f %s\n", bash_function_name))) + continue + } + file.Write([]byte("export " + strings.Replace( strings.Replace(kvp, "'", "\\'", -1), "=", "=$'", 1) + "'\n")) } @@ -237,6 +246,10 @@ func (c *Context) buildEnvfile() (string, error) { return file.Name(), nil } +func isBashFunc(key string, value string) bool { + return strings.HasPrefix(key, "BASH_FUNC_") && strings.HasPrefix(value, "()") +} + // Runs a command in Bash from this Context. With each call, a temporary file // is generated used as BASH_ENV when calling Bash that includes all variables, // sourced scripts, and exported functions from the Context. Standard I/O by diff --git a/basher_test.go b/basher_test.go index baf88ae..2f8e47e 100644 --- a/basher_test.go +++ b/basher_test.go @@ -138,3 +138,24 @@ func TestOddArgs(t *testing.T) { t.Fatal("unexpected stdout:", stdout.String()) } } + +func TestIsBashFunc(t *testing.T) { + if isBashFunc("", "") { + t.Fatal("empty string is not a bash func") + } + + if isBashFunc("key", "value") { + t.Fatal("key=value is not a bash func") + } + + if isBashFunc("BASH_FUNC_readlinkf", "value") { + t.Fatal("key does not end with %%") + } + + if isBashFunc("BASH_FUNC_readlinkf%%", "value") { + t.Fatal("value does not begin with ()") + } + if !isBashFunc("BASH_FUNC_readlinkf%%", "() { true }") { + t.Fatal("bash func should be detected") + } +}