Compare commits

...

42 Commits

Author SHA1 Message Date
Andrey Nering
f8545d4c61 v3.4.2 2021-04-23 18:11:31 -03:00
Oleg Butuzov
9b42ef5d46 "file does not exist" improving for watchers
Adds additional (initial missing) context to the go generic
`os.ErrNotExist` error, in addition to other errors that (possibly)
can be returned by `zglob.Glob`

Closes #472
2021-04-23 18:03:49 -03:00
Andrey Nering
05ddfc0495 Merge pull request #476 from Pix4D/fix-os-kill
signals: do not try to catch uncatchable signals
2021-04-23 17:45:56 -03:00
Andrey Nering
53b2cebb66 Updated the version output to use Go module build information if avalable. Enabled GoReleaser module proxying for verifiable builds.
Co-authored-by: Jamie Edge <JamieEdge@users.noreply.github.com>
Co-authored-by: Carlos Alexandro Becker <caarlos0@gmail.com>
2021-04-23 17:35:15 -03:00
Marco Molteni
837fb71a24 signals: do not try to catch uncatchable signals
os.Kill is SIGKILL (kill -9), cannot be intercepted.
(see https://github.com/golang/go/issues/13080)
2021-04-20 14:57:23 +02:00
Marco Molteni
2e13cf5f74 gitignore more editors 2021-04-20 14:54:24 +02:00
Andrey Nering
0ae1681d9c CHANGELOG: Fix typos 2021-04-17 17:57:08 -03:00
Andrey Nering
ebb66ba8fb v3.4.1 2021-04-17 17:48:36 -03:00
Andrey Nering
e79354a039 Revert "Updated the version output to use Go module build information if available. Enabled GoReleaser module proxying for verifiable builds."
This reverts commit 2a3f049336.
2021-04-17 17:47:24 -03:00
Andrey Nering
a57beb1de4 Website: Remove GitHub logo
The website that hosted the SVG file is offline for a while.
2021-04-17 17:34:00 -03:00
Andrey Nering
1648c44ee2 Website: Use dark theme 2021-04-17 17:34:00 -03:00
Andrey Nering
efe47a149e Website: Remove "Examples" page 2021-04-17 17:33:52 -03:00
Andrey Nering
2d66a2f0f3 Improve YAML parse error reporting
Fixes #467
2021-04-17 17:12:39 -03:00
Andrey Nering
43a1f1314e Website: Add a "Community" page 2021-04-17 11:59:24 -03:00
Andrey Nering
4f4b282d7c Merge pull request #471 from go-task/dependabot/go_modules/github.com/stretchr/testify-1.7.0
Bump github.com/stretchr/testify from 1.5.1 to 1.7.0
2021-04-17 10:53:03 -03:00
dependabot[bot]
d3d4da18e5 Bump github.com/stretchr/testify from 1.5.1 to 1.7.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.5.1 to 1.7.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.5.1...v1.7.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-17 13:51:37 +00:00
Andrey Nering
b8da583986 Merge pull request #470 from go-task/dependabot/go_modules/github.com/fatih/color-1.10.0
Bump github.com/fatih/color from 1.7.0 to 1.10.0
2021-04-17 10:51:01 -03:00
Andrey Nering
73f6b42715 Merge pull request #469 from go-task/dependabot/go_modules/github.com/radovskyb/watcher-1.0.7
Bump github.com/radovskyb/watcher from 1.0.5 to 1.0.7
2021-04-17 10:50:21 -03:00
dependabot[bot]
0e2a4efdaa Bump github.com/radovskyb/watcher from 1.0.5 to 1.0.7
Bumps [github.com/radovskyb/watcher](https://github.com/radovskyb/watcher) from 1.0.5 to 1.0.7.
- [Release notes](https://github.com/radovskyb/watcher/releases)
- [Commits](https://github.com/radovskyb/watcher/compare/1.0.5...v1.0.7)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-17 13:47:39 +00:00
dependabot[bot]
6798e16aaf Bump github.com/fatih/color from 1.7.0 to 1.10.0
Bumps [github.com/fatih/color](https://github.com/fatih/color) from 1.7.0 to 1.10.0.
- [Release notes](https://github.com/fatih/color/releases)
- [Commits](https://github.com/fatih/color/compare/v1.7.0...v1.10.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-17 13:47:38 +00:00
Andrey Nering
c9cc64ecfc Merge pull request #468 from go-task/dependabot/go_modules/github.com/mattn/go-zglob-0.0.3
Bump github.com/mattn/go-zglob from 0.0.1 to 0.0.3
2021-04-17 10:46:42 -03:00
dependabot[bot]
761f9045ac Bump github.com/mattn/go-zglob from 0.0.1 to 0.0.3
Bumps [github.com/mattn/go-zglob](https://github.com/mattn/go-zglob) from 0.0.1 to 0.0.3.
- [Release notes](https://github.com/mattn/go-zglob/releases)
- [Commits](https://github.com/mattn/go-zglob/compare/v0.0.1...v0.0.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-17 13:43:00 +00:00
Andrey Nering
dfae979287 Add .github/dependabot.yml 2021-04-17 10:42:18 -03:00
George Pollard
fe917affd2 Include task name in log output 2021-04-04 16:16:22 -03:00
Andrey Nering
d44207dd7f Merge pull request #463 from JamieEdge/update-install-docs
Update Go modules installation documentation for Go 1.16
2021-04-04 15:48:19 -03:00
Andrey Nering
ec8b1403bd Use early return and add CHANGELOG for #462 2021-04-04 15:40:34 -03:00
Jamie Edge
6f3d108c1e Updated the install script documentation. 2021-04-04 17:31:41 +01:00
Jamie Edge
c34ee9c1f9 Updated the Go modules installation documentation for Go 1.16. 2021-04-04 17:30:42 +01:00
Jamie Edge
2a3f049336 Updated the version output to use Go module build information if available. Enabled GoReleaser module proxying for verifiable builds. 2021-04-04 12:57:58 +01:00
Andrey Nering
0c91011e88 Merge pull request #460 from patrick-mota/patch-1
Fix typo default installation
2021-03-28 11:10:38 -03:00
Andrey Nering
8bcd8719aa Docs: Add GO111MODULE=on to go get command 2021-03-28 10:45:36 -03:00
Ganon
29a8af509b Fix typo default installation 2021-03-26 13:19:45 +01:00
Andrey Nering
d3cd9f17f9 Documentation: Update link 2021-03-20 13:30:38 -03:00
Andrey Nering
b9aea8c5ec v3.3.0 2021-03-20 13:21:00 -03:00
Andrey Nering
897619a961 Upgrade github.com/spf13/pflag to v1.0.5 2021-03-20 12:00:39 -03:00
Andrey Nering
e6c4706b73 Add support for delegating CLI arguments with "--" and a special CLI_ARGS variable
Closes #327
2021-03-20 11:58:45 -03:00
Andrey Nering
8994c50d34 Upgrade mvdan.cc/sh to v3.2.4 2021-03-20 10:38:13 -03:00
Andrey Nering
55b62e47eb Upgrade mvdan.cc/sh to v3.2.2 2021-03-07 15:32:22 -03:00
Ross Hammermeister
c6ecf70377 Adding a --concurrency (-C) flag 2021-03-07 09:49:57 -03:00
Andrey Nering
f0cd7d27fb Taskfile: Set CGO_ENABLED=0 globally
We want that also for running tests, and not only for building it.
2021-03-07 09:30:33 -03:00
Andrey Nering
f923bb499b CHANGELOG: Fix wrong year in release date 2021-02-16 17:53:28 -03:00
Andrey Nering
aa3a29fed2 CHANGELOG: Add missing release dates 2021-02-16 17:52:32 -03:00
27 changed files with 390 additions and 178 deletions

10
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: gomod
directory: /
schedule:
interval: weekly
day: saturday
time: '08:00'
timezone: America/Sao_Paulo

3
.gitignore vendored
View File

@@ -19,8 +19,9 @@ dist/
.DS_Store .DS_Store
# intellij idea/goland # editors
.idea/ .idea/
.vscode/
# exuberant ctags # exuberant ctags
tags tags

View File

@@ -1,6 +1,6 @@
build: build:
binary: task binary: task
main: cmd/task/task.go main: cmd/task
goos: goos:
- windows - windows
- darwin - darwin
@@ -17,6 +17,11 @@ build:
goarch: 386 goarch: 386
env: env:
- CGO_ENABLED=0 - CGO_ENABLED=0
ldflags:
- -s -w # Don't set main.version.
gomod:
proxy: true
archives: archives:
- name_template: "{{.Binary}}_{{.Os}}_{{.Arch}}" - name_template: "{{.Binary}}_{{.Os}}_{{.Arch}}"

View File

@@ -1,6 +1,36 @@
# Changelog # Changelog
## v3.2.2 ## v3.4.2 - 2021-04-23
- On watch, report which file failed to read
([#472](https://github.com/go-task/task/pull/472)).
- Do not try to catch SIGKILL signal, which are not actually possible
([#476](https://github.com/go-task/task/pull/476)).
- Improve version reporting when building Task from source using Go Modules
([#462](https://github.com/go-task/task/pull/462), [#473](https://github.com/go-task/task/pull/473)).
## v3.4.1 - 2021-04-17
- Improve error reporting when parsing YAML: in some situations where you
would just see an generic error, you'll now see the actual error with
more detail: the YAML line the failed to parse, for example
([#467](https://github.com/go-task/task/issues/467)).
- A JSON Schema was published [here](https://json.schemastore.org/taskfile.json)
and is automatically being used by some editors like Visual Studio Code
([#135](https://github.com/go-task/task/issues/135)).
- Print task name before the command in the log output
([#398](https://github.com/go-task/task/pull/398)).
## v3.3.0 - 2021-03-20
- Add support for delegating CLI arguments to commands with `--` and a
special `CLI_ARGS` variable
([#327](https://github.com/go-task/task/issues/327)).
- Add a `--concurrency` (alias `-C`) flag, to limit the number of tasks that
run concurrently. This is useful for heavy workloads.
([#345](https://github.com/go-task/task/pull/345)).
## v3.2.2 - 2021-01-12
- Improve performance of `--list` and `--summary` by skipping running shell - Improve performance of `--list` and `--summary` by skipping running shell
variables for these flags variables for these flags
@@ -13,14 +43,14 @@
- The install script is now working for ARM platforms - The install script is now working for ARM platforms
([#428](https://github.com/go-task/task/pull/428)). ([#428](https://github.com/go-task/task/pull/428)).
## v3.2.1 ## v3.2.1 - 2021-01-09
- Fixed some bugs and regressions regarding dynamic variables and directories - Fixed some bugs and regressions regarding dynamic variables and directories
([#426](https://github.com/go-task/task/issues/426)). ([#426](https://github.com/go-task/task/issues/426)).
- The [slim-sprig](https://github.com/go-task/slim-sprig) package was updated - The [slim-sprig](https://github.com/go-task/slim-sprig) package was updated
with the upstream [sprig](https://github.com/Masterminds/sprig). with the upstream [sprig](https://github.com/Masterminds/sprig).
## v3.2.0 ## v3.2.0 - 2021-01-07
- Fix the `.task` directory being created in the task directory instead of the - Fix the `.task` directory being created in the task directory instead of the
Taskfile directory Taskfile directory
@@ -33,7 +63,7 @@
should be more stable now should be more stable now
([#423](https://github.com/go-task/task/pull/423), [#365](https://github.com/go-task/task/issues/365)). ([#423](https://github.com/go-task/task/pull/423), [#365](https://github.com/go-task/task/issues/365)).
## v3.1.0 ## v3.1.0 - 2021-01-03
- Fix a bug when the checksum up-to-date resolution is used by a task - Fix a bug when the checksum up-to-date resolution is used by a task
with a custom `label:` attribute with a custom `label:` attribute
@@ -49,7 +79,7 @@
sentence was in the last line sentence was in the last line
([#403](https://github.com/go-task/task/issues/403)). ([#403](https://github.com/go-task/task/issues/403)).
## v3.0.1 ## v3.0.1 - 2020-12-26
- Allow use as a library by moving the required packages out of the `internal` - Allow use as a library by moving the required packages out of the `internal`
directory directory
@@ -59,7 +89,7 @@
- Fix panic when you have empty tasks in your Taskfile - Fix panic when you have empty tasks in your Taskfile
([#338](https://github.com/go-task/task/issues/338), [#362](https://github.com/go-task/task/pull/362)). ([#338](https://github.com/go-task/task/issues/338), [#362](https://github.com/go-task/task/pull/362)).
## v3.0.0 ## v3.0.0 - 2020-08-16
- On `v3`, all CLI variables will be considered global variables - On `v3`, all CLI variables will be considered global variables
([#336](https://github.com/go-task/task/issues/336), [#341](https://github.com/go-task/task/pull/341)) ([#336](https://github.com/go-task/task/issues/336), [#341](https://github.com/go-task/task/pull/341))
@@ -102,7 +132,7 @@
commands are green, errors are red, etc commands are green, errors are red, etc
([#207](https://github.com/go-task/task/pull/207)). ([#207](https://github.com/go-task/task/pull/207)).
## v2.8.1 - 2019-05-20 ## v2.8.1 - 2020-05-20
- Fix error code for the `--help` flag - Fix error code for the `--help` flag
([#300](https://github.com/go-task/task/issues/300), [#330](https://github.com/go-task/task/pull/330)). ([#300](https://github.com/go-task/task/issues/300), [#330](https://github.com/go-task/task/pull/330)).

View File

@@ -12,6 +12,9 @@ vars:
GO_PACKAGES: GO_PACKAGES:
sh: go list ./... sh: go list ./...
env:
CGO_ENABLED: '0'
tasks: tasks:
default: default:
cmds: cmds:
@@ -21,8 +24,6 @@ tasks:
desc: Installs Task desc: Installs Task
cmds: cmds:
- go install -v -ldflags="-w -s -X main.version={{.GIT_COMMIT}}" ./cmd/task - go install -v -ldflags="-w -s -X main.version={{.GIT_COMMIT}}" ./cmd/task
env:
CGO_ENABLED: '0'
mod: mod:
desc: Downloads and tidy Go modules desc: Downloads and tidy Go modules

View File

@@ -9,7 +9,7 @@ import (
// ParseV3 parses command line argument: tasks and global variables // ParseV3 parses command line argument: tasks and global variables
func ParseV3(args ...string) ([]taskfile.Call, *taskfile.Vars) { func ParseV3(args ...string) ([]taskfile.Call, *taskfile.Vars) {
var calls []taskfile.Call var calls []taskfile.Call
var globals *taskfile.Vars var globals = &taskfile.Vars{}
for _, arg := range args { for _, arg := range args {
if !strings.Contains(arg, "=") { if !strings.Contains(arg, "=") {
@@ -17,9 +17,6 @@ func ParseV3(args ...string) ([]taskfile.Call, *taskfile.Vars) {
continue continue
} }
if globals == nil {
globals = &taskfile.Vars{}
}
name, value := splitVar(arg) name, value := splitVar(arg)
globals.Set(name, taskfile.Var{Static: value}) globals.Set(name, taskfile.Var{Static: value})
} }
@@ -34,7 +31,7 @@ func ParseV3(args ...string) ([]taskfile.Call, *taskfile.Vars) {
// ParseV2 parses command line argument: tasks and vars of each task // ParseV2 parses command line argument: tasks and vars of each task
func ParseV2(args ...string) ([]taskfile.Call, *taskfile.Vars) { func ParseV2(args ...string) ([]taskfile.Call, *taskfile.Vars) {
var calls []taskfile.Call var calls []taskfile.Call
var globals *taskfile.Vars var globals = &taskfile.Vars{}
for _, arg := range args { for _, arg := range args {
if !strings.Contains(arg, "=") { if !strings.Contains(arg, "=") {
@@ -43,9 +40,6 @@ func ParseV2(args ...string) ([]taskfile.Call, *taskfile.Vars) {
} }
if len(calls) < 1 { if len(calls) < 1 {
if globals == nil {
globals = &taskfile.Vars{}
}
name, value := splitVar(arg) name, value := splitVar(arg)
globals.Set(name, taskfile.Var{Static: value}) globals.Set(name, taskfile.Var{Static: value})
} else { } else {

View File

@@ -96,7 +96,9 @@ func TestArgsV3(t *testing.T) {
t.Run(fmt.Sprintf("TestArgs%d", i+1), func(t *testing.T) { t.Run(fmt.Sprintf("TestArgs%d", i+1), func(t *testing.T) {
calls, globals := args.ParseV3(test.Args...) calls, globals := args.ParseV3(test.Args...)
assert.Equal(t, test.ExpectedCalls, calls) assert.Equal(t, test.ExpectedCalls, calls)
if test.ExpectedGlobals.Len() > 0 || globals.Len() > 0 {
assert.Equal(t, test.ExpectedGlobals, globals) assert.Equal(t, test.ExpectedGlobals, globals)
}
}) })
} }
} }
@@ -198,7 +200,10 @@ func TestArgsV2(t *testing.T) {
t.Run(fmt.Sprintf("TestArgs%d", i+1), func(t *testing.T) { t.Run(fmt.Sprintf("TestArgs%d", i+1), func(t *testing.T) {
calls, globals := args.ParseV2(test.Args...) calls, globals := args.ParseV2(test.Args...)
assert.Equal(t, test.ExpectedCalls, calls) assert.Equal(t, test.ExpectedCalls, calls)
if test.ExpectedGlobals.Len() > 0 || globals.Len() > 0 {
assert.Equal(t, test.ExpectedGlobals, globals) assert.Equal(t, test.ExpectedGlobals, globals)
}
}) })
} }
} }

View File

@@ -7,6 +7,8 @@ import (
"os" "os"
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"runtime/debug"
"strings"
"syscall" "syscall"
"github.com/spf13/pflag" "github.com/spf13/pflag"
@@ -18,7 +20,7 @@ import (
) )
var ( var (
version = "master" version = ""
) )
const usage = `Usage: task [-ilfwvsd] [--init] [--list] [--force] [--watch] [--verbose] [--silent] [--dir] [--taskfile] [--dry] [--summary] [task...] const usage = `Usage: task [-ilfwvsd] [--init] [--list] [--force] [--watch] [--verbose] [--silent] [--dir] [--taskfile] [--dry] [--summary] [task...]
@@ -65,6 +67,7 @@ func main() {
dry bool dry bool
summary bool summary bool
parallel bool parallel bool
concurrency int
dir string dir string
entrypoint string entrypoint string
output string output string
@@ -87,10 +90,11 @@ func main() {
pflag.StringVarP(&entrypoint, "taskfile", "t", "", `choose which Taskfile to run. Defaults to "Taskfile.yml"`) pflag.StringVarP(&entrypoint, "taskfile", "t", "", `choose which Taskfile to run. Defaults to "Taskfile.yml"`)
pflag.StringVarP(&output, "output", "o", "", "sets output style: [interleaved|group|prefixed]") pflag.StringVarP(&output, "output", "o", "", "sets output style: [interleaved|group|prefixed]")
pflag.BoolVarP(&color, "color", "c", true, "colored output") pflag.BoolVarP(&color, "color", "c", true, "colored output")
pflag.IntVarP(&concurrency, "concurrency", "C", 0, "limit number tasks to run concurrently")
pflag.Parse() pflag.Parse()
if versionFlag { if versionFlag {
fmt.Printf("Task version: %s\n", version) fmt.Printf("Task version: %s\n", getVersion())
return return
} }
@@ -132,6 +136,7 @@ func main() {
Summary: summary, Summary: summary,
Parallel: parallel, Parallel: parallel,
Color: color, Color: color,
Concurrency: concurrency,
Stdin: os.Stdin, Stdin: os.Stdin,
Stdout: os.Stdout, Stdout: os.Stdout,
@@ -156,12 +161,16 @@ func main() {
var ( var (
calls []taskfile.Call calls []taskfile.Call
globals *taskfile.Vars globals *taskfile.Vars
tasksAndVars, cliArgs = getArgs()
) )
if v >= 3.0 { if v >= 3.0 {
calls, globals = args.ParseV3(pflag.Args()...) calls, globals = args.ParseV3(tasksAndVars...)
} else { } else {
calls, globals = args.ParseV2(pflag.Args()...) calls, globals = args.ParseV2(tasksAndVars...)
} }
globals.Set("CLI_ARGS", taskfile.Var{Static: strings.Join(cliArgs, " ")})
e.Taskfile.Vars.Merge(globals) e.Taskfile.Vars.Merge(globals)
ctx := context.Background() ctx := context.Background()
@@ -182,9 +191,25 @@ func main() {
} }
} }
func getArgs() (tasksAndVars, cliArgs []string) {
var (
args = pflag.Args()
doubleDashPos = pflag.CommandLine.ArgsLenAtDash()
)
if doubleDashPos != -1 {
tasksAndVars = args[:doubleDashPos]
cliArgs = args[doubleDashPos:]
} else {
tasksAndVars = args
}
return
}
func getSignalContext() context.Context { func getSignalContext() context.Context {
ch := make(chan os.Signal, 1) ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt, os.Kill, syscall.SIGTERM) signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
go func() { go func() {
sig := <-ch sig := <-ch
@@ -193,3 +218,21 @@ func getSignalContext() context.Context {
}() }()
return ctx return ctx
} }
func getVersion() string {
if version != "" {
return version
}
info, ok := debug.ReadBuildInfo()
if !ok || info.Main.Version == "" {
return "unknown"
}
version = info.Main.Version
if info.Main.Sum != "" {
version += fmt.Sprintf(" (%s)", info.Main.Sum)
}
return version
}

25
concurrency.go Normal file
View File

@@ -0,0 +1,25 @@
package task
func (e *Executor) acquireConcurrencyLimit() func() {
if e.concurrencySemaphore == nil {
return emptyFunc
}
e.concurrencySemaphore <- struct{}{}
return func() {
<-e.concurrencySemaphore
}
}
func (e *Executor) releaseConcurrencyLimit() func() {
if e.concurrencySemaphore == nil {
return emptyFunc
}
<-e.concurrencySemaphore
return func() {
e.concurrencySemaphore <- struct{}{}
}
}
func emptyFunc() {}

View File

@@ -2,7 +2,7 @@
- [Usage](usage.md) - [Usage](usage.md)
- [Styleguide](styleguide.md) - [Styleguide](styleguide.md)
- [Taskfile Versions](taskfile_versions.md) - [Taskfile Versions](taskfile_versions.md)
- [Examples](examples.md) - [Community](community.md)
- [Releasing Task](releasing_task.md) - [Releasing Task](releasing_task.md)
- [Donate](donate.md) - [Donate](donate.md)
- [![GitHub](https://icongram.jgog.in/simple/github.svg?color=808080&size=16)GitHub](https://github.com/go-task/task) - [GitHub](https://github.com/go-task/task)

44
docs/community.md Normal file
View File

@@ -0,0 +1,44 @@
# Community
Some of the work to improve the Task ecosystem is done by the community, be
it installation methods or integrations with code editor. I (the author) am
thankful for everyone that helps me to improve the overall experience.
## Editor Integrations
### JSON Schema
[@KROSF](https://github.com/KROSF) worked on a JSON Schema [into this Gist](https://gist.github.com/KROSF/c5435acf590acd632f71bb720f685895),
which later was made officially available by [@Crandel](https://github.com/Crandel)
at [https://json.schemastore.org/taskfile.json](https://json.schemastore.org/taskfile.json).
Further improvements are possible by opening pull requests changing
[this file](https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/taskfile.json).
Some code editors, like Visual Studio Code, make use of Schema Store
automatically.
### Visual Studio Code extension
Additionally, there's also some work done by
[@paulvarache](https://github.com/paulvarache) in making an Visual Studio Code
extension, which has its code [here](https://github.com/paulvarache/vscode-taskfile)
and is published [here](https://marketplace.visualstudio.com/items?itemName=paulvarache.vscode-taskfile).
## Installation methods
Some installation methods are maintained by third party:
- [GitHub Actions](https://github.com/arduino/actions/tree/master/setup-taskfile)
by [@arduino](https://github.com/arduino)
- [AUR](https://aur.archlinux.org/packages/taskfile-git)
by [@kovetskiy](https://github.com/kovetskiy)
- [Scoop](https://github.com/lukesampson/scoop-extras/blob/master/bucket/task.json)
## More
Also, thanks for all the [code contributors](https://github.com/go-task/task/graphs/contributors),
[financial contributors](https://opencollective.com/task), all those who
[reported bugs](https://github.com/go-task/task/issues?q=is%3Aissue) and
[answered questions](https://github.com/go-task/task/discussions).
If you know something that is missing in this document, please submit a
pull request.

View File

@@ -1,7 +0,0 @@
# Examples
The [go-task/examples][examples] intends to be a collection of Taskfiles for
various use cases.
(It still lacks many examples, though. Contributions are welcome).
[examples]: https://github.com/go-task/examples

View File

@@ -6,7 +6,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="A task runner / simpler Make alternative written in Go"> <meta name="description" content="A task runner / simpler Make alternative written in Go">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify-themeable/dist/css/theme-simple.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsify-themeable@0/dist/css/theme-simple-dark.css">
<meta name="google-site-verification" content="VGAYkbdmuaciIDGkBe-eAg9yfZg0C6ostgonbGxxOa0" /> <meta name="google-site-verification" content="VGAYkbdmuaciIDGkBe-eAg9yfZg0C6ostgonbGxxOa0" />
<style> <style>
#logo { #logo {
@@ -20,6 +20,10 @@
.app-name-link img { .app-name-link img {
width: 125px; width: 125px;
} }
:root {
--base-font-size: 14px;
--theme-color: #29beb0;
}
</style> </style>
</head> </head>
<body> <body>

View File

@@ -68,12 +68,12 @@ The `task_checksums.txt` file contains the SHA-256 checksum for each file.
#### **Install Script** #### **Install Script**
We also have a [install script][installscript], which is very useful on We also have an [install script][installscript] which is very useful in
scenarios like CIs. Many thanks to [GoDownloader][godownloader] for allowing scenarios like CI. Many thanks to [GoDownloader][godownloader] for enabling the
easily generating this script. easy generation of this script.
```bash ```bash
# For Default Installion to ./bin with debug logging # For Default Installation to ./bin with debug logging
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d
# For Installation To /usr/local/bin for userwide access with debug logging # For Installation To /usr/local/bin for userwide access with debug logging
@@ -107,29 +107,27 @@ This installation method is community owned.
First, make sure you have [Go][go] properly installed and setup. First, make sure you have [Go][go] properly installed and setup.
You can easily install it globally by running: You can easily install the latest release globally by running:
```bash ```bash
go get -u github.com/go-task/task/v3/cmd/task go install github.com/go-task/task/v3/cmd/task@latest
``` ```
Or you can install into another directory: Or you can install into another directory:
```bash ```bash
git clone https://github.com/go-task/task env GOBIN=/bin go install github.com/go-task/task/v3/cmd/task@latest
cd task ```
# Compiling binary to $GOPATH/bin If using Go 1.15 or earlier, instead use:
go install -v ./cmd/task
# Compiling it to another location. ```bash
# Use -o ./task.exe on Windows. env GO111MODULE=on go get -u github.com/go-task/task/v3/cmd/task@latest
go build -v -o ./task ./cmd/task
``` ```
> For CI environments we recommend using the [Install Script](#get-the-binary) > For CI environments we recommend using the [Install Script](#get-the-binary)
> instead, which is faster and more stable, since it'll just download the latest > instead, which is faster and more stable, since it'll just download the latest
> released binary, instead of compiling the edge (master branch) version. > released binary.
<!-- tabs:end --> <!-- tabs:end -->

View File

@@ -36,4 +36,4 @@ If you think its Task version is outdated, open an issue to let us know.
[gotaskrb]: https://github.com/go-task/homebrew-tap/blob/master/Formula/go-task.rb [gotaskrb]: https://github.com/go-task/homebrew-tap/blob/master/Formula/go-task.rb
[snappackage]: https://github.com/go-task/snap [snappackage]: https://github.com/go-task/snap
[snapcraftyaml]: https://github.com/go-task/snap/blob/master/snap/snapcraft.yaml#L2 [snapcraftyaml]: https://github.com/go-task/snap/blob/master/snap/snapcraft.yaml#L2
[snapcraftdashboard]: https://dashboard.snapcraft.io/ [snapcraftdashboard]: https://snapcraft.io/task/releases

View File

@@ -520,6 +520,27 @@ tasks:
This works for all types of variables. This works for all types of variables.
## Forwarding CLI arguments to commands
If `--` is given in the CLI, all following paramaters are added to a
special `.CLI_ARGS` variable. This is useful to forward arguments to another
command.
The below example will run `yarn install`.
```bash
$ task yarn -- install
```
```yaml
version: '3'
tasks:
yarn:
cmds:
- yarn {{.CLI_ARGS}}
```
## Go's template engine ## Go's template engine
Task parse commands as [Go's template engine][gotemplate] before executing Task parse commands as [Go's template engine][gotemplate] before executing

13
go.mod
View File

@@ -1,17 +1,16 @@
module github.com/go-task/task/v3 module github.com/go-task/task/v3
require ( require (
github.com/fatih/color v1.7.0 github.com/fatih/color v1.10.0
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0
github.com/joho/godotenv v1.3.0 github.com/joho/godotenv v1.3.0
github.com/mattn/go-colorable v0.1.2 // indirect github.com/mattn/go-zglob v0.0.3
github.com/mattn/go-zglob v0.0.1 github.com/radovskyb/watcher v1.0.7
github.com/radovskyb/watcher v1.0.5 github.com/spf13/pflag v1.0.5
github.com/spf13/pflag v1.0.3 github.com/stretchr/testify v1.7.0
github.com/stretchr/testify v1.5.1
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
mvdan.cc/sh/v3 v3.2.1 mvdan.cc/sh/v3 v3.2.4
) )
go 1.13 go 1.13

38
go.sum
View File

@@ -6,57 +6,55 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-zglob v0.0.1 h1:xsEx/XUoVlI6yXjqBK062zYhRTZltCNmYPx6v+8DNaY= github.com/mattn/go-zglob v0.0.3 h1:6Ry4EYsScDyt5di4OI6xw1bYhOqfE5S33Z1OPy+d+To=
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/go-zglob v0.0.3/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28= github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/radovskyb/watcher v1.0.5 h1:wqt7gb+HjGacvFoLTKeT44C+XVPxu7bvHvKT1IvZ7rw= github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE=
github.com/radovskyb/watcher v1.0.5/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg= github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg=
github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 h1:HlFl4V6pEMziuLXyRkm5BIYq1y1GAbb02pRlWvI54OM= golang.org/x/sys v0.0.0-20201029080932-201ba4db2418 h1:HlFl4V6pEMziuLXyRkm5BIYq1y1GAbb02pRlWvI54OM=
golang.org/x/sys v0.0.0-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201029080932-201ba4db2418/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20191110171634-ad39bd3f0407 h1:5zh5atpUEdIc478E/ebrIaHLKcfVvG6dL/fGv7BcMoM= golang.org/x/term v0.0.0-20191110171634-ad39bd3f0407 h1:5zh5atpUEdIc478E/ebrIaHLKcfVvG6dL/fGv7BcMoM=
golang.org/x/term v0.0.0-20191110171634-ad39bd3f0407/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20191110171634-ad39bd3f0407/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
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/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
mvdan.cc/editorconfig v0.1.1-0.20200121172147-e40951bde157/go.mod h1:Ge4atmRUYqueGppvJ7JNrtqpqokoJEFxYbP0Z+WeKS8= mvdan.cc/editorconfig v0.1.1-0.20200121172147-e40951bde157/go.mod h1:Ge4atmRUYqueGppvJ7JNrtqpqokoJEFxYbP0Z+WeKS8=
mvdan.cc/sh/v3 v3.2.1 h1:uQBpiGM+rEuHse3Q+W7ajuJUeOtFVJUN/6GeX4/dUWE= mvdan.cc/sh/v3 v3.2.4 h1:+fZaWcXWRjYAvqzEKoDhDM3DkxdDUykU2iw0VMKFe9s=
mvdan.cc/sh/v3 v3.2.1/go.mod h1:fPQmabBpREM/XQ9YXSU5ZFZ/Sm+PmKP9/vkFHgYKJEI= mvdan.cc/sh/v3 v3.2.4/go.mod h1:fPQmabBpREM/XQ9YXSU5ZFZ/Sm+PmKP9/vkFHgYKJEI=

View File

@@ -63,7 +63,7 @@ func (r *Templater) ReplaceSlice(strs []string) []string {
} }
func (r *Templater) ReplaceVars(vars *taskfile.Vars) *taskfile.Vars { func (r *Templater) ReplaceVars(vars *taskfile.Vars) *taskfile.Vars {
if r.err != nil || vars == nil || len(vars.Keys) == 0 { if r.err != nil || vars.Len() == 0 {
return nil return nil
} }

19
task.go
View File

@@ -42,6 +42,7 @@ type Executor struct {
Summary bool Summary bool
Parallel bool Parallel bool
Color bool Color bool
Concurrency int
Stdin io.Reader Stdin io.Reader
Stdout io.Writer Stdout io.Writer
@@ -54,6 +55,7 @@ type Executor struct {
taskvars *taskfile.Vars taskvars *taskfile.Vars
concurrencySemaphore chan struct{}
taskCallCount map[string]*int32 taskCallCount map[string]*int32
mkdirMutexMap map[string]*sync.Mutex mkdirMutexMap map[string]*sync.Mutex
} }
@@ -247,6 +249,10 @@ func (e *Executor) Setup() error {
e.taskCallCount[k] = new(int32) e.taskCallCount[k] = new(int32)
e.mkdirMutexMap[k] = &sync.Mutex{} e.mkdirMutexMap[k] = &sync.Mutex{}
} }
if e.Concurrency > 0 {
e.concurrencySemaphore = make(chan struct{}, e.Concurrency)
}
return nil return nil
} }
@@ -260,6 +266,9 @@ func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error {
return &MaximumTaskCallExceededError{task: call.Task} return &MaximumTaskCallExceededError{task: call.Task}
} }
release := e.acquireConcurrencyLimit()
defer release()
if err := e.runDeps(ctx, t); err != nil { if err := e.runDeps(ctx, t); err != nil {
return err return err
} }
@@ -324,6 +333,9 @@ func (e *Executor) mkdir(t *taskfile.Task) error {
func (e *Executor) runDeps(ctx context.Context, t *taskfile.Task) error { func (e *Executor) runDeps(ctx context.Context, t *taskfile.Task) error {
g, ctx := errgroup.WithContext(ctx) g, ctx := errgroup.WithContext(ctx)
reacquire := e.releaseConcurrencyLimit()
defer reacquire()
for _, d := range t.Deps { for _, d := range t.Deps {
d := d d := d
@@ -344,6 +356,9 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi
switch { switch {
case cmd.Task != "": case cmd.Task != "":
reacquire := e.releaseConcurrencyLimit()
defer reacquire()
err := e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars}) err := e.RunTask(ctx, taskfile.Call{Task: cmd.Task, Vars: cmd.Vars})
if err != nil { if err != nil {
return err return err
@@ -351,7 +366,7 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi
return nil return nil
case cmd.Cmd != "": case cmd.Cmd != "":
if e.Verbose || (!cmd.Silent && !t.Silent && !e.Taskfile.Silent && !e.Silent) { if e.Verbose || (!cmd.Silent && !t.Silent && !e.Taskfile.Silent && !e.Silent) {
e.Logger.Errf(logger.Green, "task: %s", cmd.Cmd) e.Logger.Errf(logger.Green, "task: [%s] %s", t.Name(), cmd.Cmd)
} }
if e.Dry { if e.Dry {
@@ -382,7 +397,7 @@ func (e *Executor) runCommand(ctx context.Context, t *taskfile.Task, call taskfi
Stderr: stdErr, Stderr: stdErr,
}) })
if execext.IsExitError(err) && cmd.IgnoreError { if execext.IsExitError(err) && cmd.IgnoreError {
e.Logger.VerboseErrf(logger.Yellow, "task: command error ignored: %v", err) e.Logger.VerboseErrf(logger.Yellow, "task: [%s] command error ignored: %v", t.Name(), err)
return nil return nil
} }
return err return err

View File

@@ -171,6 +171,22 @@ func TestVarsInvalidTmpl(t *testing.T) {
assert.EqualError(t, e.Run(context.Background(), taskfile.Call{Task: target}), expectError, "e.Run(target)") assert.EqualError(t, e.Run(context.Background(), taskfile.Call{Task: target}), expectError, "e.Run(target)")
} }
func TestConcurrency(t *testing.T) {
const (
dir = "testdata/concurrency"
target = "default"
)
e := &task.Executor{
Dir: dir,
Stdout: ioutil.Discard,
Stderr: ioutil.Discard,
Concurrency: 1,
}
assert.NoError(t, e.Setup(), "e.Setup()")
assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: target}), "e.Run(target)")
}
func TestParams(t *testing.T) { func TestParams(t *testing.T) {
tt := fileContentTest{ tt := fileContentTest{
Dir: "testdata/params", Dir: "testdata/params",
@@ -610,7 +626,7 @@ func TestDry(t *testing.T) {
assert.NoError(t, e.Setup()) assert.NoError(t, e.Setup())
assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "build"})) assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "build"}))
assert.Equal(t, "task: touch file.txt", strings.TrimSpace(buff.String())) assert.Equal(t, "task: [build] touch file.txt", strings.TrimSpace(buff.String()))
if _, err := os.Stat(file); err == nil { if _, err := os.Stat(file); err == nil {
t.Errorf("File should not exist %s", file) t.Errorf("File should not exist %s", file)
} }

View File

@@ -1,7 +1,6 @@
package taskfile package taskfile
import ( import (
"errors"
"strings" "strings"
) )
@@ -20,13 +19,6 @@ type Dep struct {
Vars *Vars Vars *Vars
} }
var (
// ErrCantUnmarshalCmd is returned for invalid command YAML
ErrCantUnmarshalCmd = errors.New("task: can't unmarshal cmd value")
// ErrCantUnmarshalDep is returned for invalid dependency YAML
ErrCantUnmarshalDep = errors.New("task: can't unmarshal dep value")
)
// UnmarshalYAML implements yaml.Unmarshaler interface // UnmarshalYAML implements yaml.Unmarshaler interface
func (c *Cmd) UnmarshalYAML(unmarshal func(interface{}) error) error { func (c *Cmd) UnmarshalYAML(unmarshal func(interface{}) error) error {
var cmd string var cmd string
@@ -53,13 +45,13 @@ func (c *Cmd) UnmarshalYAML(unmarshal func(interface{}) error) error {
Task string Task string
Vars *Vars Vars *Vars
} }
if err := unmarshal(&taskCall); err == nil { if err := unmarshal(&taskCall); err != nil {
return err
}
c.Task = taskCall.Task c.Task = taskCall.Task
c.Vars = taskCall.Vars c.Vars = taskCall.Vars
return nil return nil
} }
return ErrCantUnmarshalCmd
}
// UnmarshalYAML implements yaml.Unmarshaler interface // UnmarshalYAML implements yaml.Unmarshaler interface
func (d *Dep) UnmarshalYAML(unmarshal func(interface{}) error) error { func (d *Dep) UnmarshalYAML(unmarshal func(interface{}) error) error {
@@ -72,10 +64,10 @@ func (d *Dep) UnmarshalYAML(unmarshal func(interface{}) error) error {
Task string Task string
Vars *Vars Vars *Vars
} }
if err := unmarshal(&taskCall); err == nil { if err := unmarshal(&taskCall); err != nil {
return err
}
d.Task = taskCall.Task d.Task = taskCall.Task
d.Vars = taskCall.Vars d.Vars = taskCall.Vars
return nil return nil
} }
return ErrCantUnmarshalDep
}

View File

@@ -6,11 +6,6 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
var (
// ErrCantUnmarshalIncludedTaskfile is returned for invalid var YAML.
ErrCantUnmarshalIncludedTaskfile = errors.New("task: can't unmarshal included value")
)
// IncludedTaskfile represents information about included tasksfile // IncludedTaskfile represents information about included tasksfile
type IncludedTaskfile struct { type IncludedTaskfile struct {
Taskfile string Taskfile string
@@ -98,12 +93,11 @@ func (it *IncludedTaskfile) UnmarshalYAML(unmarshal func(interface{}) error) err
Taskfile string Taskfile string
Dir string Dir string
} }
if err := unmarshal(&includedTaskfile); err == nil { if err := unmarshal(&includedTaskfile); err != nil {
return err
}
it.Dir = includedTaskfile.Dir it.Dir = includedTaskfile.Dir
it.Taskfile = includedTaskfile.Taskfile it.Taskfile = includedTaskfile.Taskfile
it.AdvancedImport = true it.AdvancedImport = true
return nil return nil
} }
return ErrCantUnmarshalIncludedTaskfile
}

View File

@@ -1,9 +1,5 @@
package taskfile package taskfile
import (
"errors"
)
// Tasks represents a group of tasks // Tasks represents a group of tasks
type Tasks map[string]*Task type Tasks map[string]*Task
@@ -28,11 +24,6 @@ type Task struct {
IgnoreError bool IgnoreError bool
} }
var (
// ErrCantUnmarshalTask is returned for invalid task YAML
ErrCantUnmarshalTask = errors.New("task: can't unmarshal task value")
)
func (t *Task) Name() string { func (t *Task) Name() string {
if t.Label != "" { if t.Label != "" {
return t.Label return t.Label
@@ -71,7 +62,9 @@ func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error {
Prefix string Prefix string
IgnoreError bool `yaml:"ignore_error"` IgnoreError bool `yaml:"ignore_error"`
} }
if err := unmarshal(&task); err == nil { if err := unmarshal(&task); err != nil {
return err
}
t.Cmds = task.Cmds t.Cmds = task.Cmds
t.Deps = task.Deps t.Deps = task.Deps
t.Label = task.Label t.Label = task.Label
@@ -88,9 +81,5 @@ func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error {
t.Method = task.Method t.Method = task.Method
t.Prefix = task.Prefix t.Prefix = task.Prefix
t.IgnoreError = task.IgnoreError t.IgnoreError = task.IgnoreError
return nil return nil
} }
return ErrCantUnmarshalTask
}

View File

@@ -7,11 +7,6 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
var (
// ErrCantUnmarshalVar is returned for invalid var YAML.
ErrCantUnmarshalVar = errors.New("task: can't unmarshal var value")
)
// Vars is a string[string] variables map. // Vars is a string[string] variables map.
type Vars struct { type Vars struct {
Keys []string Keys []string
@@ -75,7 +70,7 @@ func (vs *Vars) Range(yield func(key string, value Var) error) error {
// ToCacheMap converts Vars to a map containing only the static // ToCacheMap converts Vars to a map containing only the static
// variables // variables
func (vs *Vars) ToCacheMap() (m map[string]interface{}) { func (vs *Vars) ToCacheMap() (m map[string]interface{}) {
m = make(map[string]interface{}, len(vs.Keys)) m = make(map[string]interface{}, vs.Len())
vs.Range(func(k string, v Var) error { vs.Range(func(k string, v Var) error {
if v.Sh != "" { if v.Sh != "" {
// Dynamic variable is not yet resolved; trigger // Dynamic variable is not yet resolved; trigger
@@ -93,6 +88,14 @@ func (vs *Vars) ToCacheMap() (m map[string]interface{}) {
return return
} }
// Len returns the size of the map
func (vs *Vars) Len() int {
if vs == nil {
return 0
}
return len(vs.Keys)
}
// Var represents either a static or dynamic variable. // Var represents either a static or dynamic variable.
type Var struct { type Var struct {
Static string Static string
@@ -116,10 +119,9 @@ func (v *Var) UnmarshalYAML(unmarshal func(interface{}) error) error {
var sh struct { var sh struct {
Sh string Sh string
} }
if err := unmarshal(&sh); err == nil { if err := unmarshal(&sh); err != nil {
return err
}
v.Sh = sh.Sh v.Sh = sh.Sh
return nil return nil
} }
return ErrCantUnmarshalVar
}

32
testdata/concurrency/Taskfile.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
version: '2'
tasks:
default:
deps:
- t1
t1:
deps:
- t3
- t4
cmds:
- task: t2
- echo done 1
t2:
deps:
- t5
- t6
cmds:
- echo done 2
t3:
cmds:
- echo done 3
t4:
cmds:
- echo done 4
t5:
cmds:
- echo done 5
t6:
cmds:
- echo done 6

View File

@@ -2,6 +2,7 @@ package task
import ( import (
"context" "context"
"fmt"
"os" "os"
"os/signal" "os/signal"
"path/filepath" "path/filepath"
@@ -129,7 +130,7 @@ func (e *Executor) registerWatchedFiles(w *watcher.Watcher, calls ...taskfile.Ca
for _, s := range task.Sources { for _, s := range task.Sources {
files, err := zglob.Glob(s) files, err := zglob.Glob(s)
if err != nil { if err != nil {
return err return fmt.Errorf("task: %s: %w", s, err)
} }
for _, f := range files { for _, f := range files {
absFile, err := filepath.Abs(f) absFile, err := filepath.Abs(f)