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:
commit
d2f2cba6d8
@ -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
1
.gitignore
vendored
@ -22,6 +22,7 @@ dist/
|
||||
# editors
|
||||
.idea/
|
||||
.vscode/
|
||||
.fleet/
|
||||
|
||||
# exuberant ctags
|
||||
tags
|
||||
|
@ -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`
|
||||
|
@ -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,
|
||||
|
@ -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'
|
||||
|
@ -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. |
|
||||
|
@ -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
|
||||
|
1
task.go
1
task.go
@ -42,6 +42,7 @@ type Executor struct {
|
||||
Parallel bool
|
||||
Color bool
|
||||
Concurrency int
|
||||
Interval string
|
||||
|
||||
Stdin io.Reader
|
||||
Stdout io.Writer
|
||||
|
62
task_test.go
62
task_test.go
@ -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)
|
||||
}
|
||||
|
@ -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"
|
||||
)
|
||||
|
||||
|
@ -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
1
testdata/watcher_interval/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
src/*
|
16
testdata/watcher_interval/Taskfile.yaml
vendored
Normal file
16
testdata/watcher_interval/Taskfile.yaml
vendored
Normal 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
|
32
watch.go
32
watch.go
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user