diff --git a/README.md b/README.md index de09cb54..a7d07281 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,20 @@ abc Result: 'abc' ``` +#### Dynamic variables + +If you prefix a variable with `$`, then the variable is considered a dynamic +variable. The value after the $-symbol will be treated as a command and the +output assigned. + +```yml +build: + cmds: + - go build -ldflags="-X main.Version={{.LAST_GIT_COMMIT}}" main.go + vars: + LAST_GIT_COMMIT: $git log -n 1 --format=%h +``` + ### Go's template engine Task parse commands as [Go's template engine][gotemplate] before executing diff --git a/variable_handling.go b/variable_handling.go index f6a14060..684f593f 100644 --- a/variable_handling.go +++ b/variable_handling.go @@ -5,6 +5,7 @@ import ( "encoding/json" "io/ioutil" "os" + "os/exec" "runtime" "strings" "text/template" @@ -18,20 +19,51 @@ var ( TaskvarsFilePath = "Taskvars" ) +func handleDynamicVariableContent(value string) (string, error) { + if value == "" || value[0] != '$' { + return value, nil + } + var cmd *exec.Cmd + if ShExists { + cmd = exec.Command(ShPath, "-c", value[1:]) + } else { + cmd = exec.Command("cmd", "/C", value[1:]) + } + cmd.Stdin = os.Stdin + cmd.Stderr = os.Stderr + bytes, err := cmd.Output() + if err != nil { + return "", err + } + return strings.TrimSpace(string(bytes)), nil +} + func (t Task) handleVariables() (map[string]string, error) { localVariables := make(map[string]string) for key, value := range t.Vars { - localVariables[key] = value + val, err := handleDynamicVariableContent(value) + if err != nil { + return nil, err + } + localVariables[key] = val } if fileVariables, err := readTaskvarsFile(); err == nil { for key, value := range fileVariables { - localVariables[key] = value + val, err := handleDynamicVariableContent(value) + if err != nil { + return nil, err + } + localVariables[key] = val } } else { return nil, err } for key, value := range getEnvironmentVariables() { - localVariables[key] = value + val, err := handleDynamicVariableContent(value) + if err != nil { + return nil, err + } + localVariables[key] = val } return localVariables, nil }