Task
Task is a task runner / build tool that aims to be simpler and easier to use than, for example, GNU Make.
See taskfile.dev for documentation.
Category: Golang / Miscellaneous |
Watchers: 69 |
Star: 5.1k |
Fork: 316 |
Last update: May 13, 2022 |
Task is a task runner / build tool that aims to be simpler and easier to use than, for example, GNU Make.
See taskfile.dev for documentation.
Hi,
Add the possibility to use import
or includes
to imports some others tasks.
With the default strategy as namespace
.
File: docker/v1.0/Taskfile.yaml
version: "2"
task:
build:
cmds:
- docker build...
File: go/v1.0/Taskfile.yaml
version: "2"
task:
build:
cmds:
- go build ...
File (in my project): Taskfile.yaml
imports:
docker: https://.../docker/v1.0/Taskfile.yaml
go: file://.../go/v1.0/Taskfile.yaml
— or —
includes:
docker: https://.../docker/v1.0/Taskfile.yaml
go: file://.../go/v1.0/Taskfile.yaml
task:
build:
- task: "docker:build"
- task: "go:build"
task go:build go:docker
— or —
task build
What do you think?
UPDATE: This is a general feature request to not run equal dependencies more than once. E.g. if task A
and task B
both depend on taskC
, running both task A
and task B
in parallel (witin one instance of task), should be able to resolve the dependencies so that taskC
is only run once, and this is the interesting port, if it's equal, which we will get to next.
Since you can pass variables to tasks, it's not enough to just look at the name. The best option is probably to rely on a hash of the name + sorted and resolved input variables. A close second could be to rely on unresolved but still sorted input variables, which is not perfect, but could be an acceptable trade-off if it's somehow easier in code.
I have multiple tasks in my Taskfile
that depend on a single task called go-dep
that runs the command glide install
. When I run task
to build multiple targets, I would expect go-dep to be called at most 1 time (zero if it's found to be up-to-date). Instead, I see it's called once for each task that depend on it:
$ task
task: No argument given, trying default task
glide install
glide install
glide install
glide install
PS! go-deps
in this case is called with no vars, but the rule should really apply to run a dep at most 1 time when the vars are exactly the same.
This is a general issue to track proposals with small or big breaking changes, that could be released in the next major version.
This list is a work in progress and can change at any time.
Development is happening on the v3 branch.
github.com/go-task/task/v2
to v3
Taskvars.yml
and Taskfile_{{OS}}.yml
. This was done before we had a generic inclusion of Taskfiles implemented. We should add options to
vendor
directory? (#214)method:
option. Default changed from timestamp
to checksum
(#246).TIMESTAMP
and .CHECKSUM
to status:
(#216)method:
(shouldn't also check the main guide)There are more issues and feature request that could be added to this release.
For some startup tasks or cleanup paths commands could run in parallel while others should be run in order. Add a Parallel property to task to allow switching between modes
Hi everybody 👋
Once in a while, people ask me why the development is slow, questions got unanswered, bug reports are not responded, features not added, PRs not reviewed, etc.
The answer is simple: the project has grown to become bigger than I ever expected. With a full time job and a life outside work, I have limited time to dedicate to this project. More demand is generated from users than I could keep up even if I doubled the time I dedicate to this project.
So first of all I'd like to ask for your patience and understanding.
Secondly, I'd like to hear opinions and ideas on how to keep the project moving.
And lastly, I'ld like to ask for some help. I had two other people with write access to the repo in the past, but they quickly lost interest in the project. Other than that short period, I've being alone. You could help:
Adding a --summary
flag for task to get more a summary of the task
See #107
New field in task called summary
version: '2'
tasks:
release:
deps: [build]
summary: |
Release your project to github
It will build your project before starting the release it.
Please make sure that you have set GITHUB_TOKEN before starting.
cmds:
- your-release-tool
build:
cmds:
- your-build-tool
Output for task --summary release
:
task: release
Release your project to github
It will build your project before starting the release it.
Please make sure that you have set GITHUB_TOKEN before starting.
dependencies:
- build
commands:
- your-release-tool
Behaviour:
--summary
will not execute the task--summary
will display the summary of a task (see above)--summary
will use description as fallback, if summary does not exist--summary
will output a warning (or information), if no description/summary is present--summary
will output the dependencies if there are any--summary
will output the commands if there are anyTests:
task_test.go
Documentation is present for that feature
It's possible to control how many tasks that task
itself runs concurrently via -C
. A problem however is that the command(s) of a task may spawn any number of threads or processes, meaning one task actually represents several "tasks". One example is calling make -j
which tells make to use one process per available CPU. Assume we have a machine with eight cores and we run eight tasks in parallel, each calling make -j
, that would mean 64(!) processes running at the same time. I'm hitting a similar situation in my CI environment and it totally tanks my runner.
My suggestion is to allow a weight
value (or similar) for a task which is used to calculate number of running tasks. An simple example:
version: "3"
tasks:
a:
weight: 2
cmds:
- make -j
b:
weight: 2
cmds:
- make -j
default:
deps: [a, b]
Running task -C 2
would run either a
or b
but not both concurrently. I would say that it should be OK to over schedule once, e.g. if task a
above had a weight value of 1, then both would run concurrently even if total weight would be three (but no other task would scheduled until one of them finishes). This could however be a hard vs soft limit setting too.
I have a quite large project where I manage to end up in a deadlock every time I try to run task. It seems to be related to a run: once
task that other tasks depend on. This happens when I run with -C X
where X < 4 in my case. I suspect that If I add more "apps" I will eventually end up in this situation when running with all my cores as well.
I've managed to condense my layout into this:
version: "3"
tasks:
do_something:
run: once
status:
- "true"
prepare_env:
cmds:
- task: do_something
app1:
deps: [prepare_env]
app2:
deps: [prepare_env]
default:
deps: [app1, app2]
Running this example ends up in deadlock about one in ten times I run it (my larger repo ends up in deadlock every time, as I mentioned). I'm pretty sure it has to do with timing.
Example of a successful run:
$ ../work/task -v -C 1
task: "default" started
task: "app2" started
task: "app1" started
task: "prepare_env" started
task: "prepare_env" started
task: "do_something" started
task: status command true exited zero
task: Task "do_something" is up to date
task: skipping execution of task: do_something
task: "prepare_env" finished
task: "prepare_env" finished
task: "app2" finished
task: "app1" finished
task: "default" finished
And with deadlock:
$ ../work/task -v -C 1
task: "default" started
task: "app1" started
task: "app2" started
task: "prepare_env" started
task: "prepare_env" started
task: "do_something" started
task: skipping execution of task: do_something
Like described in #495 - I too have used tasks like functions, and would like some functionality to declare certain vars as required vs optional.
Like described here: https://github.com/go-task/task/issues/524#issuecomment-1112900798
There's a very interesting use case to have what may be referred to is "uncacheable variables". Essentially a variable that is re-evaluated everytime it's used. In a way, this is acts like a function.
As related to #179
version: '3'
tasks:
one:
vars:
FOO: '{{.FOO}}'
cmds:
- echo '{{.FOO}}'
two:
cmds:
- task: one
vars:
FOO: '{{`${{should be escaped}}`}}'
at 18:03:01 ❯ t --taskfile Taskfile.test.yml --dry two
task: Failed to run task "two": template: :1: function "should" not defined
The more upvoted answer in stackoverflow indicates that this should work:
{{`{{Your.Angular.Data}}`}}
As should the following which is syntax needed for templating github actions workflow yaml file.
{{`${{Your.Angular.Data}}`}}
Gomplate (A CLI tool for go template) handles this just fine:
at 18:09:37 ❯ gomplate --in '{{`${{should be escaped}}`}}'
${{should be escaped}}%
**Note that the trailing %
is the shell's way of telling you there's no trailing newline character at the end of this output.
Also reproducible on go playground: https://go.dev/play/p/JkgDIrUs3RQ
It's almost as if the task
is double evaluating things?
Sometimes it's very nice to be able to store variables in 1 location (such as in a taskfile), and be able to re-use them programmatically else where. Currently, if I wanted to manage a variable in task, and use it in another script or github action or something, I'd write this:
vars:
FOO: bar
tasks:
vars:get:foo:
cmds:
- echo '{{.FOO}}'
and call with task vars:get:foo
I feel this could be simplified with something like
task -var foo