From 478d1466d9cfc3792dc5a314e5fcf05dc1cbdf5d Mon Sep 17 00:00:00 2001 From: Sascha Andres Date: Tue, 7 Mar 2017 20:07:03 +0100 Subject: [PATCH 1/5] 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 } From fa936a54c07b9aa71430addc6a0095c51229061c Mon Sep 17 00:00:00 2001 From: Sascha Andres Date: Wed, 8 Mar 2017 08:20:07 +0100 Subject: [PATCH 2/5] Replaced regex with easier code --- variable_handling.go | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/variable_handling.go b/variable_handling.go index 910092a1..b5609dd3 100644 --- a/variable_handling.go +++ b/variable_handling.go @@ -6,13 +6,10 @@ import ( "io/ioutil" "os" "os/exec" - "regexp" "runtime" "strings" "text/template" - "fmt" - "github.com/BurntSushi/toml" "gopkg.in/yaml.v2" ) @@ -20,35 +17,20 @@ 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) { + if value[0] != '@' { 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]) + cmd = exec.Command(ShPath, "-c", value[1:]) } else { - cmd = exec.Command("cmd", "/C", re.FindStringSubmatch(value)[subExpressionIndex]) + cmd = exec.Command("cmd", "/C", value[1:]) } cmd.Stdin = os.Stdin cmd.Stderr = os.Stderr From d55eb984774c68d5aa1d037ffcc73a74b20322f8 Mon Sep 17 00:00:00 2001 From: Sascha Andres Date: Wed, 8 Mar 2017 08:22:52 +0100 Subject: [PATCH 3/5] Updated README for dynamic variables Solves #11 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index de09cb54..ca733f16 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,10 @@ abc Result: 'abc' ``` +#### Dynamic variables + +If you prefix a variable with `@`, then the variable is considered a dynamic variable. The value after the @-synbol will be treated as a command and the output assigned. + ### Go's template engine Task parse commands as [Go's template engine][gotemplate] before executing From 3078a3ee684736b7d0c6d9f3199985144aa6d534 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Wed, 8 Mar 2017 18:32:32 -0300 Subject: [PATCH 4/5] Change "@" for "$" as dynamic var identifier --- README.md | 12 +++++++++++- variable_handling.go | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ca733f16..a7d07281 100644 --- a/README.md +++ b/README.md @@ -229,7 +229,17 @@ Result: 'abc' #### Dynamic variables -If you prefix a variable with `@`, then the variable is considered a dynamic variable. The value after the @-synbol will be treated as a command and the output assigned. +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 diff --git a/variable_handling.go b/variable_handling.go index b5609dd3..30b38014 100644 --- a/variable_handling.go +++ b/variable_handling.go @@ -23,7 +23,7 @@ func handleDynamicVariableContent(value string) (string, error) { if value == "" { return value, nil } - if value[0] != '@' { + if value[0] != '$' { return value, nil } var cmd *exec.Cmd From c3f3eb5f512e639f0ec0941234ffb1afc544454d Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Wed, 8 Mar 2017 18:34:44 -0300 Subject: [PATCH 5/5] Unify ifs --- variable_handling.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/variable_handling.go b/variable_handling.go index 30b38014..684f593f 100644 --- a/variable_handling.go +++ b/variable_handling.go @@ -20,10 +20,7 @@ var ( ) func handleDynamicVariableContent(value string) (string, error) { - if value == "" { - return value, nil - } - if value[0] != '$' { + if value == "" || value[0] != '$' { return value, nil } var cmd *exec.Cmd