mirror of
https://github.com/go-task/task.git
synced 2025-06-15 00:15:10 +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