mirror of
				https://github.com/go-task/task.git
				synced 2025-10-30 23:58:01 +02:00 
			
		
		
		
	Changes per feedback
This commit is contained in:
		| @@ -266,6 +266,8 @@ The above syntax is also supported in `deps`. | |||||||
|  |  | ||||||
| ## Prevent unnecessary work | ## Prevent unnecessary work | ||||||
|  |  | ||||||
|  | ### By fingerprinting locally generated files and their sources | ||||||
|  |  | ||||||
| If a task generates something, you can inform Task the source and generated | If a task generates something, you can inform Task the source and generated | ||||||
| files, so Task will prevent to run them if not necessary. | files, so Task will prevent to run them if not necessary. | ||||||
|  |  | ||||||
| @@ -321,6 +323,9 @@ tasks: | |||||||
|  |  | ||||||
| > TIP: method `none` skips any validation and always run the task. | > TIP: method `none` skips any validation and always run the task. | ||||||
|  |  | ||||||
|  | ### Using programmatic checks to indicate a task is up to date. | ||||||
|  |  | ||||||
|  |  | ||||||
| Alternatively, you can inform a sequence of tests as `status`. If no error | Alternatively, you can inform a sequence of tests as `status`. If no error | ||||||
| is returned (exit status 0), the task is considered up-to-date: | is returned (exit status 0), the task is considered up-to-date: | ||||||
|  |  | ||||||
| @@ -340,7 +345,8 @@ tasks: | |||||||
|       - test -f directory/file2.txt |       - test -f directory/file2.txt | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Normally, you would use either `status` or `sources` in combination with |  | ||||||
|  | Normally, you would use `sources` in combination with | ||||||
| `generates` - but for tasks that generate remote artifacts (Docker images, | `generates` - but for tasks that generate remote artifacts (Docker images, | ||||||
| deploys, CD releases) the checksum source and timestamps require either | deploys, CD releases) the checksum source and timestamps require either | ||||||
| access to the artifact or for an out-of-band refresh of the `.checksum` | access to the artifact or for an out-of-band refresh of the `.checksum` | ||||||
| @@ -356,9 +362,13 @@ up-to-date. | |||||||
| Also, `task --status [tasks]...` will exit with a non-zero exit code if any of | Also, `task --status [tasks]...` will exit with a non-zero exit code if any of | ||||||
| the tasks are not up-to-date. | the tasks are not up-to-date. | ||||||
|  |  | ||||||
| If you need a certain set of conditions to be _true_ you can use the | ### Using programmatic checks to cancel execution of an task and it's dependencies | ||||||
| `preconditions` stanza.  `preconditions` are very similar to `status` |  | ||||||
| lines except they support `sh` expansion and they SHOULD all return 0. | In addition to `status` checks, there are also `preconditions` checks, which are | ||||||
|  | the logical inverse of `status` checks.  That is, if you need a certain set of | ||||||
|  | conditions to be _true_ you can use the `preconditions` stanza. | ||||||
|  | `preconditions` are similar to `status` lines except they support `sh` | ||||||
|  | expansion and they SHOULD all return 0. | ||||||
|  |  | ||||||
| ```yaml | ```yaml | ||||||
| version: '2' | version: '2' | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.mod
									
									
									
									
									
								
							| @@ -14,10 +14,8 @@ require ( | |||||||
| 	github.com/radovskyb/watcher v1.0.5 | 	github.com/radovskyb/watcher v1.0.5 | ||||||
| 	github.com/spf13/pflag v1.0.3 | 	github.com/spf13/pflag v1.0.3 | ||||||
| 	github.com/stretchr/testify v1.3.0 | 	github.com/stretchr/testify v1.3.0 | ||||||
| 	golang.org/x/crypto v0.0.0-20180830192347-182538f80094 // indirect | 	golang.org/x/sync v0.0.0-20190423024810-112230192c58 | ||||||
| 	golang.org/x/net v0.0.0-20180826012351-8a410e7b638d // indirect | 	golang.org/x/tools/gopls v0.1.3 // indirect | ||||||
| 	golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f |  | ||||||
| 	golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789 // indirect |  | ||||||
| 	gopkg.in/yaml.v2 v2.2.1 | 	gopkg.in/yaml.v2 v2.2.1 | ||||||
| 	mvdan.cc/sh v2.6.4+incompatible | 	mvdan.cc/sh v2.6.4+incompatible | ||||||
| ) | ) | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								go.sum
									
									
									
									
									
								
							| @@ -33,12 +33,24 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 | |||||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||||
| golang.org/x/crypto v0.0.0-20180830192347-182538f80094 h1:rVTAlhYa4+lCfNxmAIEOGQRoD23UqP72M3+rSWVGDTg= | golang.org/x/crypto v0.0.0-20180830192347-182538f80094 h1:rVTAlhYa4+lCfNxmAIEOGQRoD23UqP72M3+rSWVGDTg= | ||||||
| golang.org/x/crypto v0.0.0-20180830192347-182538f80094/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | golang.org/x/crypto v0.0.0-20180830192347-182538f80094/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||||
|  | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= | ||||||
|  | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||||
| golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I= | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d h1:g9qWBGx4puODJTMVyoPrpoxPFgVGd+z1DZwjfRu4d0I= | ||||||
| golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||||
|  | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||||
| golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= | ||||||
| golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
|  | golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= | ||||||
|  | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||||
| golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789 h1:T8D7l6WB3tLu+VpKvw06ieD/OhBi1XpJmG1U/FtttZg= | golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789 h1:T8D7l6WB3tLu+VpKvw06ieD/OhBi1XpJmG1U/FtttZg= | ||||||
| golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | golang.org/x/sys v0.0.0-20180831094639-fa5fdf94c789/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
|  | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= | ||||||
|  | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||||
|  | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||||
|  | golang.org/x/tools v0.0.0-20190710153321-831012c29e42 h1:4IOeC7p+OItq3+O5BWkcmVu2uBe3jekXau5S4QZX9DU= | ||||||
|  | golang.org/x/tools v0.0.0-20190710153321-831012c29e42/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= | ||||||
|  | golang.org/x/tools/gopls v0.1.3 h1:CB5ECiPysqZrwxcyRjN+exyZpY0gODTZvNiqQi3lpeo= | ||||||
|  | golang.org/x/tools/gopls v0.1.3/go.mod h1:vrCQzOKxvuiZLjCKSmbbov04oeBQQOb4VQqwYK2PWIY= | ||||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||||
| gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= | gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= | ||||||
|   | |||||||
| @@ -46,10 +46,6 @@ func (c *Checksum) IsUpToDate() (bool, error) { | |||||||
| 	return oldMd5 == newMd5, nil | 	return oldMd5 == newMd5, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (t *Checksum) Kind() string { |  | ||||||
| 	return "checksum" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Checksum) checksum(files ...string) (string, error) { | func (c *Checksum) checksum(files ...string) (string, error) { | ||||||
| 	h := md5.New() | 	h := md5.New() | ||||||
|  |  | ||||||
| @@ -77,7 +73,7 @@ func (c *Checksum) checksum(files ...string) (string, error) { | |||||||
| 	return fmt.Sprintf("%x", h.Sum(nil)), nil | 	return fmt.Sprintf("%x", h.Sum(nil)), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // Value implements the Chcker Interface | // Value implements the Checker Interface | ||||||
| func (c *Checksum) Value() (string, error) { | func (c *Checksum) Value() (string, error) { | ||||||
| 	return c.checksum() | 	return c.checksum() | ||||||
| } | } | ||||||
| @@ -87,6 +83,11 @@ func (c *Checksum) OnError() error { | |||||||
| 	return os.Remove(c.checksumFilePath()) | 	return os.Remove(c.checksumFilePath()) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Kind implements the Checker Interface | ||||||
|  | func (t *Checksum) Kind() string { | ||||||
|  | 	return "checksum" | ||||||
|  | } | ||||||
|  |  | ||||||
| func (c *Checksum) checksumFilePath() string { | func (c *Checksum) checksumFilePath() string { | ||||||
| 	return filepath.Join(c.Dir, ".task", "checksum", c.normalizeFilename(c.Task)) | 	return filepath.Join(c.Dir, ".task", "checksum", c.normalizeFilename(c.Task)) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -18,6 +18,10 @@ type Templater struct { | |||||||
| 	err    error | 	err    error | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (r *Templater) RefreshStringMap() { | ||||||
|  | 	r.strMap = r.Vars.ToStringMap() | ||||||
|  | } | ||||||
|  |  | ||||||
| func (r *Templater) Replace(str string) string { | func (r *Templater) Replace(str string) string { | ||||||
| 	if r.err != nil || str == "" { | 	if r.err != nil || str == "" { | ||||||
| 		return "" | 		return "" | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ func (e *Executor) isTaskUpToDate(ctx context.Context, t *taskfile.Task) (bool, | |||||||
| 		return e.isTaskUpToDateStatus(ctx, t) | 		return e.isTaskUpToDateStatus(ctx, t) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	checker, err := e.GetStatusChecker(t) | 	checker, err := e.getStatusChecker(t) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
| @@ -41,14 +41,14 @@ func (e *Executor) isTaskUpToDate(ctx context.Context, t *taskfile.Task) (bool, | |||||||
| } | } | ||||||
|  |  | ||||||
| func (e *Executor) statusOnError(t *taskfile.Task) error { | func (e *Executor) statusOnError(t *taskfile.Task) error { | ||||||
| 	checker, err := e.GetStatusChecker(t) | 	checker, err := e.getStatusChecker(t) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return checker.OnError() | 	return checker.OnError() | ||||||
| } | } | ||||||
|  |  | ||||||
| func (e *Executor) GetStatusChecker(t *taskfile.Task) (status.Checker, error) { | func (e *Executor) getStatusChecker(t *taskfile.Task) (status.Checker, error) { | ||||||
| 	switch t.Method { | 	switch t.Method { | ||||||
| 	case "", "timestamp": | 	case "", "timestamp": | ||||||
| 		return &status.Timestamp{ | 		return &status.Timestamp{ | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								variables.go
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								variables.go
									
									
									
									
									
								
							| @@ -1,7 +1,6 @@ | |||||||
| package task | package task | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"io/ioutil" |  | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| @@ -64,30 +63,6 @@ func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) { | |||||||
| 		new.Env[k] = taskfile.Var{Static: static} | 		new.Env[k] = taskfile.Var{Static: static} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(origTask.Status) > 0 { |  | ||||||
| 		e := &Executor{ |  | ||||||
| 			Dir:    new.Dir, |  | ||||||
| 			Stdout: ioutil.Discard, |  | ||||||
| 			Stderr: ioutil.Discard, |  | ||||||
| 			Dry:    true, |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		checker, err := e.GetStatusChecker(&new) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		value, err := checker.Value() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		vars[strings.ToUpper(checker.Kind())] = taskfile.Var{Static: value} |  | ||||||
|  |  | ||||||
| 		statusTemplater := templater.Templater{Vars: vars} |  | ||||||
| 		new.Status = statusTemplater.ReplaceSlice(origTask.Status) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if len(origTask.Cmds) > 0 { | 	if len(origTask.Cmds) > 0 { | ||||||
| 		new.Cmds = make([]*taskfile.Cmd, len(origTask.Cmds)) | 		new.Cmds = make([]*taskfile.Cmd, len(origTask.Cmds)) | ||||||
| 		for i, cmd := range origTask.Cmds { | 		for i, cmd := range origTask.Cmds { | ||||||
| @@ -120,5 +95,24 @@ func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if len(origTask.Status) > 0 { | ||||||
|  | 		checker, err := e.getStatusChecker(&new) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		value, err := checker.Value() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		vars[strings.ToUpper(checker.Kind())] = taskfile.Var{Static: value} | ||||||
|  | 		// Adding new static variables, requires us to refresh the templaters | ||||||
|  | 		// cache of the the static values | ||||||
|  | 		r.RefreshStringMap() | ||||||
|  |  | ||||||
|  | 		new.Status = r.ReplaceSlice(origTask.Status) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return &new, r.Err() | 	return &new, r.Err() | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user