1
0
mirror of https://github.com/go-task/task.git synced 2025-03-03 14:52:13 +02:00

Merge branch 'master' into aliases

This commit is contained in:
Andrey Nering 2022-10-14 18:44:56 -03:00
commit d2f2cba6d8
14 changed files with 148 additions and 7 deletions

View File

@ -8,6 +8,6 @@ charset = utf-8
trim_trailing_whitespace = true
indent_style = tab
[*.{md,yml,yaml,json,toml,htm,html,js,css,svg,sh,bash}]
[*.{md,yml,yaml,json,toml,htm,html,js,css,svg,sh,bash,fish}]
indent_style = space
indent_size = 2

1
.gitignore vendored
View File

@ -22,6 +22,7 @@ dist/
# editors
.idea/
.vscode/
.fleet/
# exuberant ctags
tags

View File

@ -3,6 +3,11 @@
## Unreleased
- Add ability to set `aliases` for tasks and namespaces ([#268](https://github.com/go-task/task/pull/268), [#340](https://github.com/go-task/task/pull/340), [#879](https://github.com/go-task/task/pull/879)).
- Improvements to Fish shell completion
([#897](https://github.com/go-task/task/pull/897)).
- Added ability to set a different watch interval by setting
`interval: '500ms'` or using the `--interval=500ms` flag
([#813](https://github.com/go-task/task/issues/813), [#865](https://github.com/go-task/task/pull/865)).
- Add colored output to `--list`, `--list-all` and `--summary` flags ([#845](https://github.com/go-task/task/pull/845), [#874](https://github.com/go-task/task/pull/874)).
- Fix unexpected behavior where `label:` was being shown instead of the task
name on `--list`

View File

@ -73,6 +73,7 @@ func main() {
entrypoint string
output taskfile.Output
color bool
interval string
)
pflag.BoolVar(&versionFlag, "version", false, "show Task version")
@ -96,6 +97,7 @@ func main() {
pflag.StringVar(&output.Group.End, "output-group-end", "", "message template to print after a task's grouped output")
pflag.BoolVarP(&color, "color", "c", true, "colored output. Enabled by default. Set flag to false or use NO_COLOR=1 to disable")
pflag.IntVarP(&concurrency, "concurrency", "C", 0, "limit number tasks to run concurrently")
pflag.StringVarP(&interval, "interval", "I", "5s", "interval to watch for changes")
pflag.Parse()
if versionFlag {
@ -151,6 +153,7 @@ func main() {
Parallel: parallel,
Color: color,
Concurrency: concurrency,
Interval: interval,
Stdin: os.Stdin,
Stdout: os.Stdout,

View File

@ -1,16 +1,24 @@
set GO_TASK_PROGNAME task
function __task_get_tasks --description "Prints all available tasks with their description"
set -l output ($GO_TASK_PROGNAME --list-all | sed '1d; s/\* \(.*\):\s*\(.*\)/\1\t\2/' | string split0)
# Read the list of tasks (and potential errors)
$GO_TASK_PROGNAME --list-all 2>&1 | read -lz rawOutput
# Return on non-zero exit code (for cases when there is no Taskfile found or etc.)
if test $status -ne 0
return
end
# Grab names and descriptions (if any) of the tasks
set -l output (echo $rawOutput | sed '1d; s/\* \(.*\):\s*\(.*\)/\1\t\2/' | string split0)
if test $output
echo $output
echo $output
end
end
complete -c $GO_TASK_PROGNAME -d 'Runs the specified task(s). Falls back to the "default" task if no task name was specified, or lists all tasks if an unknown task name was
specified.' -xa "(__task_get_tasks)"
complete -c $GO_TASK_PROGNAME -s c -l color -d 'colored output (default true)'
complete -c $GO_TASK_PROGNAME -s d -l dir -d 'sets directory of execution'
complete -c $GO_TASK_PROGNAME -l dry -d 'compiles and prints tasks in the order that they would be run, without executing them'

View File

@ -30,6 +30,7 @@ variable
| `-f` | `--force` | `bool` | `false` | Forces execution even when the task is up-to-date. |
| `-h` | `--help` | `bool` | `false` | Shows Task usage. |
| `-i` | `--init` | `bool` | `false` | Creates a new Taskfile.yaml in the current folder. |
| `-I` | `--interval` | `string` | `5s` | Sets a different watch interval when using `--watch`, the default being 5 seconds. This string should be a valid [Go Duration](https://pkg.go.dev/time#ParseDuration). |
| `-l` | `--list` | `bool` | `false` | Lists tasks with description of current Taskfile. |
| `-a` | `--list-all` | `bool` | `false` | Lists tasks with or without a description. |
| `-o` | `--output` | `string` | Default set in the Taskfile or `intervealed` | Sets output style: [`interleaved`/`group`/`prefixed`]. |
@ -84,6 +85,7 @@ Some environment variables can be overriden to adjust Task behavior.
| `method` | `string` | `checksum` | Default method in this Taskfile. Can be overriden in a task by task basis. Available options: `checksum`, `timestamp` and `none`. |
| `silent` | `bool` | `false` | Default "silent" options for this Taskfile. If `false`, can be overidden with `true` in a task by task basis. |
| `run` | `string` | `always` | Default "run" option for this Taskfile. Available options: `always`, `once` and `when_changed`. |
| `interval` | `string` | `5s` | Sets a different watch interval when using `--watch`, the default being 5 seconds. This string should be a valid [Go Duration](https://pkg.go.dev/time#ParseDuration). |
| `vars` | [`map[string]Variable`](#variable) | | Global variables. |
| `env` | [`map[string]Variable`](#variable) | | Global environment. |
| `dotenv` | `[]string` | | A list of `.env` file paths to be parsed. |

View File

@ -232,7 +232,9 @@ includes:
### Namespace aliases
When including a taskfile, you can give the namespace a list of `aliases`. This works in the same way as [task aliases](#task-aliases) and can be used together to create shorter and easier-to-type commands.
When including a Taskfile, you can give the namespace a list of `aliases`.
This works in the same way as [task aliases](#task-aliases) and can be used
together to create shorter and easier-to-type commands.
```yaml
version: '3'
@ -1284,5 +1286,9 @@ With the flags `--watch` or `-w` task will watch for file changes
and run the task again. This requires the `sources` attribute to be given,
so task knows which files to watch.
The default watch interval is 5 seconds, but it's possible to change it by
either setting `interval: '500ms'` in the root of the Taskfile passing it
as an argument like `--interval=500ms`.
[gotemplate]: https://golang.org/pkg/text/template/
[minify]: https://github.com/tdewolff/minify/tree/master/cmd/minify

View File

@ -42,6 +42,7 @@ type Executor struct {
Parallel bool
Color bool
Concurrency int
Interval string
Stdin io.Reader
Stdout io.Writer

View File

@ -10,6 +10,7 @@ import (
"runtime"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
@ -1532,3 +1533,64 @@ func TestEvaluateSymlinksInPaths(t *testing.T) {
err = os.RemoveAll(dir + "/.task")
assert.NoError(t, err)
}
func TestFileWatcherInterval(t *testing.T) {
const dir = "testdata/watcher_interval"
expectedOutput := strings.TrimSpace(`
task: Started watching for tasks: default
task: [default] echo "Hello, World!"
Hello, World!
task: [default] echo "Hello, World!"
Hello, World!
`)
var buff bytes.Buffer
e := &task.Executor{
Dir: dir,
Stdout: &buff,
Stderr: &buff,
Watch: true,
}
assert.NoError(t, e.Setup())
buff.Reset()
err := os.MkdirAll(filepathext.SmartJoin(dir, "src"), 0755)
assert.NoError(t, err)
err = os.WriteFile(filepathext.SmartJoin(dir, "src/a"), []byte("test"), 0644)
if err != nil {
t.Fatal(err)
}
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
default:
err := e.Run(ctx, taskfile.Call{Task: "default"})
if err != nil {
return
}
}
}
}(ctx)
time.Sleep(10 * time.Millisecond)
err = os.WriteFile(filepathext.SmartJoin(dir, "src/a"), []byte("test updated"), 0644)
if err != nil {
t.Fatal(err)
}
time.Sleep(700 * time.Millisecond)
cancel()
assert.Equal(t, expectedOutput, strings.TrimSpace(buff.String()))
buff.Reset()
err = os.RemoveAll(filepathext.SmartJoin(dir, ".task"))
assert.NoError(t, err)
err = os.RemoveAll(filepathext.SmartJoin(dir, "src"))
assert.NoError(t, err)
}

View File

@ -7,8 +7,8 @@ import (
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
"golang.org/x/exp/slices"
"golang.org/x/exp/slices"
"gopkg.in/yaml.v3"
)

View File

@ -18,6 +18,7 @@ type Taskfile struct {
Silent bool
Dotenv []string
Run string
Interval string
}
// UnmarshalYAML implements yaml.Unmarshaler interface
@ -34,10 +35,13 @@ func (tf *Taskfile) UnmarshalYAML(unmarshal func(interface{}) error) error {
Silent bool
Dotenv []string
Run string
Interval string
}
if err := unmarshal(&taskfile); err != nil {
return err
}
tf.Version = taskfile.Version
tf.Expansions = taskfile.Expansions
tf.Output = taskfile.Output
@ -49,6 +53,8 @@ func (tf *Taskfile) UnmarshalYAML(unmarshal func(interface{}) error) error {
tf.Silent = taskfile.Silent
tf.Dotenv = taskfile.Dotenv
tf.Run = taskfile.Run
tf.Interval = taskfile.Interval
if tf.Expansions <= 0 {
tf.Expansions = 2
}

1
testdata/watcher_interval/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
src/*

16
testdata/watcher_interval/Taskfile.yaml vendored Normal file
View File

@ -0,0 +1,16 @@
# https://taskfile.dev
version: '3'
vars:
GREETING: Hello, World!
interval: "500ms"
tasks:
default:
sources:
- "src/*"
cmds:
- echo "{{.GREETING}}"
silent: false

View File

@ -16,7 +16,7 @@ import (
"github.com/radovskyb/watcher"
)
const watchInterval = 5 * time.Second
const defaultWatchInterval = 5 * time.Second
// watchTasks start watching the given tasks
func (e *Executor) watchTasks(calls ...taskfile.Call) error {
@ -24,6 +24,7 @@ func (e *Executor) watchTasks(calls ...taskfile.Call) error {
for i, c := range calls {
tasks[i] = c.Task
}
e.Logger.Errf(logger.Green, "task: Started watching for tasks: %s", strings.Join(tasks, ", "))
ctx, cancel := context.WithCancel(context.Background())
@ -36,6 +37,27 @@ func (e *Executor) watchTasks(calls ...taskfile.Call) error {
}()
}
var watchIntervalString string
if e.Interval != "" {
watchIntervalString = e.Interval
} else if e.Taskfile.Interval != "" {
watchIntervalString = e.Taskfile.Interval
}
watchInterval := defaultWatchInterval
if watchIntervalString != "" {
var err error
watchInterval, err = parseWatchInterval(watchIntervalString)
if err != nil {
cancel()
return err
}
}
e.Logger.VerboseOutf(logger.Green, "task: Watching for changes every %v", watchInterval)
w := watcher.New()
defer w.Close()
w.SetMaxEvents(1)
@ -163,3 +185,11 @@ func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...taskfile.Ca
func shouldIgnoreFile(path string) bool {
return strings.Contains(path, "/.git") || strings.Contains(path, "/.task") || strings.Contains(path, "/node_modules")
}
func parseWatchInterval(watchInterval string) (time.Duration, error) {
v, err := time.ParseDuration(watchInterval)
if err != nil {
return 0, fmt.Errorf(`task: Could not parse watch interval "%s": %v`, watchInterval, err)
}
return v, nil
}