From 478d1466d9cfc3792dc5a314e5fcf05dc1cbdf5d Mon Sep 17 00:00:00 2001 From: Sascha Andres Date: Tue, 7 Mar 2017 20:07:03 +0100 Subject: [PATCH] First implementation of dynamic variables --- variable_handling.go | 59 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/variable_handling.go b/variable_handling.go index f6a14060..910092a1 100644 --- a/variable_handling.go +++ b/variable_handling.go @@ -5,10 +5,14 @@ import ( "encoding/json" "io/ioutil" "os" + "os/exec" + "regexp" "runtime" "strings" "text/template" + "fmt" + "github.com/BurntSushi/toml" "gopkg.in/yaml.v2" ) @@ -16,22 +20,71 @@ import ( var ( // TaskvarsFilePath file containing additional variables TaskvarsFilePath = "Taskvars" + // DynamicVariablePattern is a pattern to test if a variable should get filled from running the content. It must contain a command group + DynamicVariablePattern = "^@(?P.*)" // alternative proposal: ^$((?P.*))$ + // ErrCommandGroupNotFound returned when the command group is not present + ErrCommandGroupNotFound = fmt.Errorf("%s does not contain the command group", DynamicVariablePattern) ) +func handleDynamicVariableContent(value string) (string, error) { + if value == "" { + return value, nil + } + re := regexp.MustCompile(DynamicVariablePattern) + if !re.MatchString(value) { + return value, nil + } + subExpressionIndex := 0 + for index, value := range re.SubexpNames() { + if value == "command" { + subExpressionIndex = index + break + } + } + if subExpressionIndex == 0 { + return "", ErrCommandGroupNotFound + } + var cmd *exec.Cmd + if ShExists { + cmd = exec.Command(ShPath, "-c", re.FindStringSubmatch(value)[subExpressionIndex]) + } else { + cmd = exec.Command("cmd", "/C", re.FindStringSubmatch(value)[subExpressionIndex]) + } + 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 }