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:
commit
b5fff68351
49
README.md
49
README.md
@ -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
40
task.go
@ -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
82
variableHandling.go
Normal 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user