1
0
mirror of https://github.com/go-task/task.git synced 2025-01-26 05:27:15 +02:00

Merge branch 'develop'

This commit is contained in:
Sascha Andres 2017-03-03 08:55:19 +01:00
commit b5fff68351
3 changed files with 161 additions and 10 deletions

View File

@ -39,6 +39,55 @@ task assets build
If Bash is available (Linux and Windows while on Git Bash), the commands will
run in Bash, otherwise will fallback to `cmd` (on Windows).
### Variables
```yml
build:
deps: [setvar]
cmds:
- echo "{{prefix}} {{THEVAR}}"
variables:
prefix: "Path:"
setvar:
cmds:
- echo "{{PATH}}"
set: THEVAR
```
The above sample saves the path into a new variable which is then again echoed.
You can use environment variables, task level variables and a file called `Variables` as source of variables.
They are evaluated in the following order:
Task local variables are overwritten by variables found in `Variables`. Variables found in `Variables` are overwritten with variables from the environment. The output of the last command is stored in the environment. So you can do something like this:
```yml
build:
deps: [setvar]
cmds:
- echo "{{prefix}} '{{THEVAR}}'"
variables:
prefix: "Result: "
setvar:
cmds:
- echo -n "a"
- echo -n "{{THEVAR}}b"
- echo -n "{{THEVAR}}c"
set: THEVAR
```
The result of a run of build would be:
```
a
ab
abc
Result: 'abc'
```
### Task dependencies
You may have tasks that depends on others. Just pointing them on `deps` will

40
task.go
View File

@ -43,6 +43,8 @@ type Task struct {
Sources []string
Generates []string
Dir string
Variables map[string]string
Set string
}
type taskNotFoundError struct {
@ -100,17 +102,32 @@ func RunTask(name string) error {
log.Printf(`Task "%s" is up to date`, name)
return nil
}
vars, err := t.handleVariables()
if err != nil {
return &taskRunError{name, err}
}
for _, d := range t.Deps {
if err := RunTask(d); err != nil {
if err := RunTask(ReplaceVariables(d, vars)); err != nil {
return err
}
}
for _, c := range t.Cmds {
if err := runCommand(c, t.Dir); err != nil {
// read in a each time, as a command could change a variable or it has been changed by a dependency
vars, err = t.handleVariables()
if err != nil {
return &taskRunError{name, err}
}
var (
output string
err error
)
if output, err = runCommand(ReplaceVariables(c, vars), ReplaceVariables(t.Dir, vars)); err != nil {
return &taskRunError{name, err}
}
fmt.Println(output)
if t.Set != "" {
os.Setenv(t.Set, output)
}
}
return nil
}
@ -133,8 +150,12 @@ func isTaskUpToDate(t *Task) bool {
return generatesMinTime.After(sourcesMaxTime)
}
func runCommand(c, path string) error {
var cmd *exec.Cmd
func runCommand(c, path string) (string, error) {
var (
cmd *exec.Cmd
b []byte
err error
)
if ShExists {
cmd = exec.Command(ShPath, "-c", c)
} else {
@ -143,12 +164,11 @@ func runCommand(c, path string) error {
if path != "" {
cmd.Dir = path
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
if b, err = cmd.Output(); err != nil {
return "", err
}
return nil
return string(b), nil
}
func readTaskfile() (tasks map[string]*Task, err error) {

82
variableHandling.go Normal file
View File

@ -0,0 +1,82 @@
package task
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/BurntSushi/toml"
yaml "gopkg.in/yaml.v2"
)
var (
// VariableFilePath file containing additional variables
VariableFilePath = "Variables"
)
func (t Task) handleVariables() (map[string]string, error) {
localVariables := make(map[string]string)
for key, value := range t.Variables {
localVariables[key] = value
}
if fileVariables, err := readVariablefile(); err == nil {
for key, value := range fileVariables {
localVariables[key] = value
}
} else {
return nil, err
}
for key, value := range getEnvironmentVariables() {
localVariables[key] = value
}
return localVariables, nil
}
// ReplaceVariables writes variables into initial string
func ReplaceVariables(initial string, variables map[string]string) string {
replaced := initial
for name, val := range variables {
replaced = strings.Replace(replaced, fmt.Sprintf("{{%s}}", name), val, -1)
}
return replaced
}
// GetEnvironmentVariables returns environment variables as map
func getEnvironmentVariables() map[string]string {
getenvironment := func(data []string, getkeyval func(item string) (key, val string)) map[string]string {
items := make(map[string]string)
for _, item := range data {
key, val := getkeyval(item)
items[key] = val
}
return items
}
return getenvironment(os.Environ(), func(item string) (key, val string) {
splits := strings.Split(item, "=")
key = splits[0]
val = splits[1]
return
})
}
func readVariablefile() (map[string]string, error) {
var variables map[string]string
if b, err := ioutil.ReadFile(VariableFilePath + ".yml"); err == nil {
if err := yaml.Unmarshal(b, &variables); err != nil {
return nil, err
}
}
if b, err := ioutil.ReadFile(VariableFilePath + ".json"); err == nil {
if err := json.Unmarshal(b, &variables); err != nil {
return nil, err
}
}
if b, err := ioutil.ReadFile(VariableFilePath + ".toml"); err == nil {
if err := toml.Unmarshal(b, &variables); err != nil {
return nil, err
}
}
return variables, nil
}