From 85ce86b778b9318580b952394e9de8c29c20100b Mon Sep 17 00:00:00 2001 From: task-bot <106601941+task-bot@users.noreply.github.com> Date: Sat, 15 Apr 2023 19:15:26 +0000 Subject: [PATCH] deploy: 8026d8ddb3f0aa9f3ecb25394585b032a8ce29ee --- 404.html | 4 +- api/index.html | 11 +- ...71786.2e4dab92.js => 02371786.9481901e.js} | 2 +- assets/js/0afd354a.e8bad103.js | 1 - assets/js/0afd354a.fb40b428.js | 1 + assets/js/0e384e19.47884a35.js | 1 + assets/js/0e384e19.649e4736.js | 1 - ...6b476.63036b78.js => 1c56b476.7edac691.js} | 2 +- assets/js/3b8c55ea.151fc55e.js | 1 + assets/js/3b8c55ea.6a334942.js | 1 - ...4d076.63a4de28.js => 4d54d076.a2286968.js} | 2 +- assets/js/5ef0e9d6.537bbfb9.js | 1 + assets/js/5ef0e9d6.9579102c.js | 1 - assets/js/6476eba6.e90c30d8.js | 1 + assets/js/6476eba6.f5165ba7.js | 1 - assets/js/7d415946.6bf3701e.js | 1 - assets/js/7d415946.d2c60d0c.js | 1 + assets/js/935f2afb.8872dd05.js | 1 - assets/js/935f2afb.9bf38336.js | 1 + assets/js/f7fd502c.3c1fe589.js | 1 + assets/js/f7fd502c.4177ef6b.js | 1 - assets/js/runtime~main.b4a9f6f9.js | 1 + assets/js/runtime~main.e2e0a53c.js | 1 - changelog/index.html | 4 +- community/index.html | 51 ++-- contributing/index.html | 39 +-- donate/index.html | 14 +- faq/index.html | 4 +- index.html | 16 +- installation/index.html | 43 +-- releasing/index.html | 29 +- search/index.html | 4 +- styleguide/index.html | 4 +- taskfile-versions/index.html | 32 +- translate/index.html | 17 +- usage/index.html | 279 +++++++++--------- 36 files changed, 298 insertions(+), 277 deletions(-) rename assets/js/{02371786.2e4dab92.js => 02371786.9481901e.js} (87%) delete mode 100644 assets/js/0afd354a.e8bad103.js create mode 100644 assets/js/0afd354a.fb40b428.js create mode 100644 assets/js/0e384e19.47884a35.js delete mode 100644 assets/js/0e384e19.649e4736.js rename assets/js/{1c56b476.63036b78.js => 1c56b476.7edac691.js} (96%) create mode 100644 assets/js/3b8c55ea.151fc55e.js delete mode 100644 assets/js/3b8c55ea.6a334942.js rename assets/js/{4d54d076.63a4de28.js => 4d54d076.a2286968.js} (85%) create mode 100644 assets/js/5ef0e9d6.537bbfb9.js delete mode 100644 assets/js/5ef0e9d6.9579102c.js create mode 100644 assets/js/6476eba6.e90c30d8.js delete mode 100644 assets/js/6476eba6.f5165ba7.js delete mode 100644 assets/js/7d415946.6bf3701e.js create mode 100644 assets/js/7d415946.d2c60d0c.js delete mode 100644 assets/js/935f2afb.8872dd05.js create mode 100644 assets/js/935f2afb.9bf38336.js create mode 100644 assets/js/f7fd502c.3c1fe589.js delete mode 100644 assets/js/f7fd502c.4177ef6b.js create mode 100644 assets/js/runtime~main.b4a9f6f9.js delete mode 100644 assets/js/runtime~main.e2e0a53c.js diff --git a/404.html b/404.html index 84952dd3..7ae99d04 100644 --- a/404.html +++ b/404.html @@ -10,13 +10,13 @@ - +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/api/index.html b/api/index.html index 0d2d1b8c..6df0950b 100644 --- a/api/index.html +++ b/api/index.html @@ -10,17 +10,20 @@ - +
-
Skip to main content

API Reference

CLI

Task command line tool has the following syntax:

task [--flags] [tasks...] [-- CLI_ARGS...]
tip

If -- is given, all remaning arguments will be assigned to a special CLI_ARGS -variable

ShortFlagTypeDefaultDescription
-c--colorbooltrueColored output. Enabled by default. Set flag to false or use NO_COLOR=1 to disable.
-C--concurrencyint0Limit number tasks to run concurrently. Zero means unlimited.
-d--dirstringWorking directorySets directory of execution.
-n--dryboolfalseCompiles and prints tasks in the order that they would be run, without executing them.
-x--exit-codeboolfalsePass-through the exit code of the task command.
-f--forceboolfalseForces execution even when the task is up-to-date.
-g--globalboolfalseRuns global Taskfile, from $HOME/Taskfile.{yml,yaml}.
-h--helpboolfalseShows Task usage.
-i--initboolfalseCreates a new Taskfile.yml in the current folder.
-I--intervalstring5sSets a different watch interval when using --watch, the default being 5 seconds. This string should be a valid Go Duration.
-l--listboolfalseLists tasks with description of current Taskfile.
-a--list-allboolfalseLists tasks with or without a description.
--sortstringdefaultChanges the order of the tasks when listed.
--jsonboolfalseSee JSON Output
-o--outputstringDefault set in the Taskfile or intervealedSets output style: [interleaved/group/prefixed].
--output-group-beginstringMessage template to print before a task's grouped output.
--output-group-endstringMessage template to print after a task's grouped output.
--output-group-error-onlyboolfalseSwallow command output on zero exit code.
-p--parallelboolfalseExecutes tasks provided on command line in parallel.
-s--silentboolfalseDisables echoing.
--statusboolfalseExits with non-zero exit code if any of the given tasks is not up-to-date.
--summaryboolfalseShow summary about a task.
-t--taskfilestringTaskfile.yml or Taskfile.yaml
-v--verboseboolfalseEnables verbose mode.
--versionboolfalseShow Task version.
-w--watchboolfalseEnables watch of the given task.

JSON Output

When using the --json flag in combination with either the --list or --list-all flags, the output will be a JSON object with the following structure:

{
"tasks": [
{
"name": "",
"desc": "",
"summary": "",
"up_to_date": false,
"location": {
"line": 54,
"column": 3,
"taskfile": "/path/to/Taskfile.yml"
}
},
// ...
],
"location": "/path/to/Taskfile.yml"
}

Special Variables

There are some special variables that is available on the templating system:

VarDescription
CLI_ARGSContain all extra arguments passed after -- when calling Task through the CLI.
TASKThe name of the current task.
ROOT_DIRThe absolute path of the root Taskfile.
TASKFILE_DIRThe absolute path of the included Taskfile.
USER_WORKING_DIRThe absolute path of the directory task was called from.
CHECKSUMThe checksum of the files listed in sources. Only available within the status prop and if method is set to checksum.
TIMESTAMPThe date object of the greatest timestamp of the files listes in sources. Only available within the status prop and if method is set to timestamp.
TASK_VERSIONThe current version of task.

ENV

Some environment variables can be overriden to adjust Task behavior.

ENVDefaultDescription
TASK_TEMP_DIR.taskLocation of the temp dir. Can relative to the project like tmp/task or absolute like /tmp/.task or ~/.task.
TASK_COLOR_RESET0Color used for white.
TASK_COLOR_BLUE34Color used for blue.
TASK_COLOR_GREEN32Color used for green.
TASK_COLOR_CYAN36Color used for cyan.
TASK_COLOR_YELLOW33Color used for yellow.
TASK_COLOR_MAGENTA35Color used for magenta.
TASK_COLOR_RED31Color used for red.
FORCE_COLORForce color output usage.

Taskfile Schema

AttributeTypeDefaultDescription
versionstringVersion of the Taskfile. The current version is 3.
outputstringinterleavedOutput mode. Available options: interleaved, group and prefixed.
methodstringchecksumDefault method in this Taskfile. Can be overriden in a task by task basis. Available options: checksum, timestamp and none.
includesmap[string]IncludeAdditional Taskfiles to be included.
varsmap[string]VariableA set of global variables.
envmap[string]VariableA set of global environment variables.
tasksmap[string]TaskA set of task definitions.
silentboolfalseDefault 'silent' options for this Taskfile. If false, can be overidden with true in a task by task basis.
dotenv[]stringA list of .env file paths to be parsed.
runstringalwaysDefault 'run' option for this Taskfile. Available options: always, once and when_changed.
intervalstring5sSets a different watch interval when using --watch, the default being 5 seconds. This string should be a valid Go Duration.
set[]stringSpecify options for the set builtin.
shopt[]stringSpecify option for the shopt builtin.

Include

AttributeTypeDefaultDescription
taskfilestringThe path for the Taskfile or directory to be included. If a directory, Task will look for files named Taskfile.yml or Taskfile.yaml inside that directory. If a relative path, resolved relative to the directory containing the including Taskfile.
dirstringThe parent Taskfile directoryThe working directory of the included tasks when run.
optionalboolfalseIf true, no errors will be thrown if the specified file does not exist.
internalboolfalseStops any task in the included Taskfile from being callable on the command line. These commands will also be omitted from the output when used with --list.
aliases[]stringAlternative names for the namespace of the included Taskfile.
varsmap[string]VariableA set of variables to apply to the included Taskfile.
info

Informing only a string like below is equivalent to setting that value to the taskfile attribute.

includes:
foo: ./path

Variable

AttributeTypeDefaultDescription
itselfstringA static value that will be set to the variable.
shstringA shell command. The output (STDOUT) will be assigned to the variable.
info

Static and dynamic variables have different syntaxes, like below:

vars:
STATIC: static
DYNAMIC:
sh: echo "dynamic"

Task

AttributeTypeDefaultDescription
cmds[]CommandA list of shell commands to be executed.
deps[]DependencyA list of dependencies of this task. Tasks defined here will run in parallel before this task.
labelstringOverrides the name of the task in the output when a task is run. Supports variables.
descstringA short description of the task. This is displayed when calling task --list.
summarystringA longer description of the task. This is displayed when calling task --summary [task].
aliases[]stringA list of alternative names by which the task can be called.
sources[]stringA list of sources to check before running this task. Relevant for checksum and timestamp methods. Can be file paths or star globs.
generates[]stringA list of files meant to be generated by this task. Relevant for timestamp method. Can be file paths or star globs.
status[]stringA list of commands to check if this task should run. The task is skipped otherwise. This overrides method, sources and generates.
preconditions[]PreconditionA list of commands to check if this task should run. If a condition is not met, the task will error.
dirstringThe directory in which this task should run. Defaults to the current working directory.
varsmap[string]VariableA set of variables that can be used in the task.
envmap[string]VariableA set of environment variables that will be made available to shell commands.
dotenv[]stringA list of .env file paths to be parsed.
silentboolfalseHides task name and command from output. The command's output will still be redirected to STDOUT and STDERR. When combined with the --list flag, task descriptions will be hidden.
interactiveboolfalseTells task that the command is interactive.
internalboolfalseStops a task from being callable on the command line. It will also be omitted from the output when used with --list.
methodstringchecksumDefines which method is used to check the task is up-to-date. timestamp will compare the timestamp of the sources and generates files. checksum will check the checksum (You probably want to ignore the .task folder in your .gitignore file). none skips any validation and always run the task.
prefixstringDefines a string to prefix the output of tasks running in parallel. Only used when the output mode is prefixed.
ignore_errorboolfalseContinue execution if errors happen while executing commands.
runstringThe one declared globally in the Taskfile or alwaysSpecifies whether the task should run again or not if called more than once. Available options: always, once and when_changed.
platforms[]stringAll platformsSpecifies which platforms the task should be run on. Valid GOOS and GOARCH values allowed. Task will be skipped otherwise.
set[]stringSpecify options for the set builtin.
shopt[]stringSpecify option for the shopt builtin.
info

These alternative syntaxes are available. They will set the given values to +

API Reference

CLI

Task command line tool has the following syntax:

task [--flags] [tasks...] [-- CLI_ARGS...]
tip

If -- is given, all remaning arguments will be assigned to a special +CLI_ARGS variable

ShortFlagTypeDefaultDescription
-c--colorbooltrueColored output. Enabled by default. Set flag to false or use NO_COLOR=1 to disable.
-C--concurrencyint0Limit number tasks to run concurrently. Zero means unlimited.
-d--dirstringWorking directorySets directory of execution.
-n--dryboolfalseCompiles and prints tasks in the order that they would be run, without executing them.
-x--exit-codeboolfalsePass-through the exit code of the task command.
-f--forceboolfalseForces execution even when the task is up-to-date.
-g--globalboolfalseRuns global Taskfile, from $HOME/Taskfile.{yml,yaml}.
-h--helpboolfalseShows Task usage.
-i--initboolfalseCreates a new Taskfile.yml in the current folder.
-I--intervalstring5sSets a different watch interval when using --watch, the default being 5 seconds. This string should be a valid Go Duration.
-l--listboolfalseLists tasks with description of current Taskfile.
-a--list-allboolfalseLists tasks with or without a description.
--sortstringdefaultChanges the order of the tasks when listed.
--jsonboolfalseSee JSON Output
-o--outputstringDefault set in the Taskfile or intervealedSets output style: [interleaved/group/prefixed].
--output-group-beginstringMessage template to print before a task's grouped output.
--output-group-endstringMessage template to print after a task's grouped output.
--output-group-error-onlyboolfalseSwallow command output on zero exit code.
-p--parallelboolfalseExecutes tasks provided on command line in parallel.
-s--silentboolfalseDisables echoing.
--statusboolfalseExits with non-zero exit code if any of the given tasks is not up-to-date.
--summaryboolfalseShow summary about a task.
-t--taskfilestringTaskfile.yml or Taskfile.yaml
-v--verboseboolfalseEnables verbose mode.
--versionboolfalseShow Task version.
-w--watchboolfalseEnables watch of the given task.

JSON Output

When using the --json flag in combination with either the --list or +--list-all flags, the output will be a JSON object with the following +structure:

{
"tasks": [
{
"name": "",
"desc": "",
"summary": "",
"up_to_date": false,
"location": {
"line": 54,
"column": 3,
"taskfile": "/path/to/Taskfile.yml"
}
}
// ...
],
"location": "/path/to/Taskfile.yml"
}

Special Variables

There are some special variables that is available on the templating system:

VarDescription
CLI_ARGSContain all extra arguments passed after -- when calling Task through the CLI.
TASKThe name of the current task.
ROOT_DIRThe absolute path of the root Taskfile.
TASKFILE_DIRThe absolute path of the included Taskfile.
USER_WORKING_DIRThe absolute path of the directory task was called from.
CHECKSUMThe checksum of the files listed in sources. Only available within the status prop and if method is set to checksum.
TIMESTAMPThe date object of the greatest timestamp of the files listes in sources. Only available within the status prop and if method is set to timestamp.
TASK_VERSIONThe current version of task.

ENV

Some environment variables can be overriden to adjust Task behavior.

ENVDefaultDescription
TASK_TEMP_DIR.taskLocation of the temp dir. Can relative to the project like tmp/task or absolute like /tmp/.task or ~/.task.
TASK_COLOR_RESET0Color used for white.
TASK_COLOR_BLUE34Color used for blue.
TASK_COLOR_GREEN32Color used for green.
TASK_COLOR_CYAN36Color used for cyan.
TASK_COLOR_YELLOW33Color used for yellow.
TASK_COLOR_MAGENTA35Color used for magenta.
TASK_COLOR_RED31Color used for red.
FORCE_COLORForce color output usage.

Taskfile Schema

AttributeTypeDefaultDescription
versionstringVersion of the Taskfile. The current version is 3.
outputstringinterleavedOutput mode. Available options: interleaved, group and prefixed.
methodstringchecksumDefault method in this Taskfile. Can be overriden in a task by task basis. Available options: checksum, timestamp and none.
includesmap[string]IncludeAdditional Taskfiles to be included.
varsmap[string]VariableA set of global variables.
envmap[string]VariableA set of global environment variables.
tasksmap[string]TaskA set of task definitions.
silentboolfalseDefault 'silent' options for this Taskfile. If false, can be overidden with true in a task by task basis.
dotenv[]stringA list of .env file paths to be parsed.
runstringalwaysDefault 'run' option for this Taskfile. Available options: always, once and when_changed.
intervalstring5sSets a different watch interval when using --watch, the default being 5 seconds. This string should be a valid Go Duration.
set[]stringSpecify options for the set builtin.
shopt[]stringSpecify option for the shopt builtin.

Include

AttributeTypeDefaultDescription
taskfilestringThe path for the Taskfile or directory to be included. If a directory, Task will look for files named Taskfile.yml or Taskfile.yaml inside that directory. If a relative path, resolved relative to the directory containing the including Taskfile.
dirstringThe parent Taskfile directoryThe working directory of the included tasks when run.
optionalboolfalseIf true, no errors will be thrown if the specified file does not exist.
internalboolfalseStops any task in the included Taskfile from being callable on the command line. These commands will also be omitted from the output when used with --list.
aliases[]stringAlternative names for the namespace of the included Taskfile.
varsmap[string]VariableA set of variables to apply to the included Taskfile.
info

Informing only a string like below is equivalent to setting that value to the +taskfile attribute.

includes:
foo: ./path

Variable

AttributeTypeDefaultDescription
itselfstringA static value that will be set to the variable.
shstringA shell command. The output (STDOUT) will be assigned to the variable.
info

Static and dynamic variables have different syntaxes, like below:

vars:
STATIC: static
DYNAMIC:
sh: echo "dynamic"

Task

AttributeTypeDefaultDescription
cmds[]CommandA list of shell commands to be executed.
deps[]DependencyA list of dependencies of this task. Tasks defined here will run in parallel before this task.
labelstringOverrides the name of the task in the output when a task is run. Supports variables.
descstringA short description of the task. This is displayed when calling task --list.
summarystringA longer description of the task. This is displayed when calling task --summary [task].
aliases[]stringA list of alternative names by which the task can be called.
sources[]stringA list of sources to check before running this task. Relevant for checksum and timestamp methods. Can be file paths or star globs.
generates[]stringA list of files meant to be generated by this task. Relevant for timestamp method. Can be file paths or star globs.
status[]stringA list of commands to check if this task should run. The task is skipped otherwise. This overrides method, sources and generates.
preconditions[]PreconditionA list of commands to check if this task should run. If a condition is not met, the task will error.
dirstringThe directory in which this task should run. Defaults to the current working directory.
varsmap[string]VariableA set of variables that can be used in the task.
envmap[string]VariableA set of environment variables that will be made available to shell commands.
dotenv[]stringA list of .env file paths to be parsed.
silentboolfalseHides task name and command from output. The command's output will still be redirected to STDOUT and STDERR. When combined with the --list flag, task descriptions will be hidden.
interactiveboolfalseTells task that the command is interactive.
internalboolfalseStops a task from being callable on the command line. It will also be omitted from the output when used with --list.
methodstringchecksumDefines which method is used to check the task is up-to-date. timestamp will compare the timestamp of the sources and generates files. checksum will check the checksum (You probably want to ignore the .task folder in your .gitignore file). none skips any validation and always run the task.
prefixstringDefines a string to prefix the output of tasks running in parallel. Only used when the output mode is prefixed.
ignore_errorboolfalseContinue execution if errors happen while executing commands.
runstringThe one declared globally in the Taskfile or alwaysSpecifies whether the task should run again or not if called more than once. Available options: always, once and when_changed.
platforms[]stringAll platformsSpecifies which platforms the task should be run on. Valid GOOS and GOARCH values allowed. Task will be skipped otherwise.
set[]stringSpecify options for the set builtin.
shopt[]stringSpecify option for the shopt builtin.
info

These alternative syntaxes are available. They will set the given values to cmds and everything else will be set to their default values:

tasks:
foo: echo "foo"

foobar:
- echo "foo"
- echo "bar"

baz:
cmd: echo "baz"

Command

AttributeTypeDefaultDescription
cmdstringThe shell command to be executed.
silentboolfalseSkips some output for this command. Note that STDOUT and STDERR of the commands will still be redirected.
taskstringSet this to trigger execution of another task instead of running a command. This cannot be set together with cmd.
varsmap[string]VariableOptional additional variables to be passed to the referenced task. Only relevant when setting task instead of cmd.
ignore_errorboolfalseContinue execution if errors happen while executing the command.
deferstringAlternative to cmd, but schedules the command to be executed at the end of this task instead of immediately. This cannot be used together with cmd.
platforms[]stringAll platformsSpecifies which platforms the command should be run on. Valid GOOS and GOARCH values allowed. Command will be skipped otherwise.
set[]stringSpecify options for the set builtin.
shopt[]stringSpecify option for the shopt builtin.
info

If given as a a string, the value will be assigned to cmd:

tasks:
foo:
cmds:
- echo "foo"
- echo "bar"

Dependency

AttributeTypeDefaultDescription
taskstringThe task to be execute as a dependency.
varsmap[string]VariableOptional additional variables to be passed to this task.
tip

If you don't want to set additional variables, it's enough to declare the dependency as a list of strings (they will be assigned to task):

tasks:
foo:
deps: [foo, bar]

Precondition

AttributeTypeDefaultDescription
shstringCommand to be executed. If a non-zero exit code is returned, the task errors without executing its commands.
msgstringOptional message to print if the precondition isn't met.
tip

If you don't want to set a different message, you can declare a precondition like this and the value will be assigned to sh:

tasks:
foo:
precondition: test -f Taskfile.yml
- + \ No newline at end of file diff --git a/assets/js/02371786.2e4dab92.js b/assets/js/02371786.9481901e.js similarity index 87% rename from assets/js/02371786.2e4dab92.js rename to assets/js/02371786.9481901e.js index 517fb30a..602394eb 100644 --- a/assets/js/02371786.2e4dab92.js +++ b/assets/js/02371786.9481901e.js @@ -1 +1 @@ -"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[252],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return m}});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),d=o,m=p["".concat(c,".").concat(d)]||p[d]||f[d]||a;return n?r.createElement(m,i(i({ref:t},u),{},{components:n})):r.createElement(m,i({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var l=2;l=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),p=l(n),d=o,m=p["".concat(c,".").concat(d)]||p[d]||f[d]||a;return n?r.createElement(m,i(i({ref:t},u),{},{components:n})):r.createElement(m,i({ref:t},u))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[p]="string"==typeof e?e:o,i[1]=s;for(var l=2;l=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},u=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},k=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),c=p(t),k=r,m=c["".concat(s,".").concat(k)]||c[k]||d[k]||l;return t?a.createElement(m,i(i({ref:n},u),{},{components:t})):a.createElement(m,i({ref:n},u))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var l=t.length,i=new Array(l);i[0]=k;var o={};for(var s in n)hasOwnProperty.call(n,s)&&(o[s]=n[s]);o.originalType=e,o[c]="string"==typeof e?e:r,i[1]=o;for(var p=2;p= v3.0.0 anymore.")),(0,r.kt)("p",null,"In the first version of the ",(0,r.kt)("inlineCode",{parentName:"p"},"Taskfile"),", the ",(0,r.kt)("inlineCode",{parentName:"p"},"version:")," key was not available,\nbecause the tasks was in the root of the YAML document. Like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'echo:\n cmds:\n - echo "Hello, World!"\n')),(0,r.kt)("p",null,"The variable priority order was also different:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Call variables"),(0,r.kt)("li",{parentName:"ol"},"Environment"),(0,r.kt)("li",{parentName:"ol"},"Task variables"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"Taskvars.yml")," variables")),(0,r.kt)("h2",{id:"version-20"},"Version 2.0"),(0,r.kt)("p",null,"At version 2, we introduced the ",(0,r.kt)("inlineCode",{parentName:"p"},"version:")," key, to allow us to evolve Task\nwith new features without breaking existing Taskfiles. The new syntax is as\nfollows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\ntasks:\n echo:\n cmds:\n - echo \"Hello, World!\"\n")),(0,r.kt)("p",null,"Version 2 allows you to write global variables directly in the Taskfile,\nif you don't want to create a ",(0,r.kt)("inlineCode",{parentName:"p"},"Taskvars.yml"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\nvars:\n GREETING: Hello, World!\n\ntasks:\n greet:\n cmds:\n - echo \"{{.GREETING}}\"\n")),(0,r.kt)("p",null,"The variable priority order changed to the following:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Task variables"),(0,r.kt)("li",{parentName:"ol"},"Call variables"),(0,r.kt)("li",{parentName:"ol"},"Taskfile variables"),(0,r.kt)("li",{parentName:"ol"},"Taskvars file variables"),(0,r.kt)("li",{parentName:"ol"},"Environment variables")),(0,r.kt)("p",null,"A new global option was added to configure the number of variables expansions\n(which default to 2):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'version: \'2\'\n\nexpansions: 3\n\nvars:\n FOO: foo\n BAR: bar\n BAZ: baz\n FOOBAR: "{{.FOO}}{{.BAR}}"\n FOOBARBAZ: "{{.FOOBAR}}{{.BAZ}}"\n\ntasks:\n default:\n cmds:\n - echo "{{.FOOBARBAZ}}"\n')),(0,r.kt)("h2",{id:"version-21"},"Version 2.1"),(0,r.kt)("p",null,"Version 2.1 includes a global ",(0,r.kt)("inlineCode",{parentName:"p"},"output")," option, to allow having more control\nover how commands output are printed to the console\n(see ",(0,r.kt)("a",{parentName:"p",href:"/usage/#output-syntax"},"documentation")," for more info):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\noutput: prefixed\n\ntasks:\n server:\n cmds:\n - go run main.go\n prefix: server\n")),(0,r.kt)("p",null,"From this version it's also possible to ignore errors of a command or task\n(check documentation ",(0,r.kt)("a",{parentName:"p",href:"/usage/#ignore-errors"},"here"),"):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'version: \'2\'\n\ntasks:\n example-1:\n cmds:\n - cmd: exit 1\n ignore_error: true\n - echo "This will be print"\n\n example-2:\n cmds:\n - exit 1\n - echo "This will be print"\n ignore_error: true\n')),(0,r.kt)("h2",{id:"version-22"},"Version 2.2"),(0,r.kt)("p",null,"Version 2.2 comes with a global ",(0,r.kt)("inlineCode",{parentName:"p"},"includes")," options to include other\nTaskfiles:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\nincludes:\n docs: ./documentation # will look for ./documentation/Taskfile.yml\n docker: ./DockerTasks.yml\n")),(0,r.kt)("h2",{id:"version-26"},"Version 2.6"),(0,r.kt)("p",null,"Version 2.6 comes with ",(0,r.kt)("inlineCode",{parentName:"p"},"preconditions")," stanza in tasks."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\ntasks:\n upload_environment:\n preconditions:\n - test -f .env\n cmds:\n - aws s3 cp .env s3://myenvironment\n")),(0,r.kt)("p",null,"Please check the ",(0,r.kt)("a",{parentName:"p",href:"/usage/#including-other-taskfiles"},"documentation")),(0,r.kt)("h2",{id:"version-3"},"Version 3"),(0,r.kt)("p",null,"These are some major changes done on ",(0,r.kt)("inlineCode",{parentName:"p"},"v3"),":"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Task's output will now be colored"),(0,r.kt)("li",{parentName:"ul"},"Added support for ",(0,r.kt)("inlineCode",{parentName:"li"},".env")," like files"),(0,r.kt)("li",{parentName:"ul"},"Added ",(0,r.kt)("inlineCode",{parentName:"li"},"label:")," setting to task so one can override how the task name\nappear in the logs"),(0,r.kt)("li",{parentName:"ul"},"A global ",(0,r.kt)("inlineCode",{parentName:"li"},"method:")," was added to allow setting the default method,\nand Task's default changed to ",(0,r.kt)("inlineCode",{parentName:"li"},"checksum")),(0,r.kt)("li",{parentName:"ul"},"Two magic variables were added when using ",(0,r.kt)("inlineCode",{parentName:"li"},"status:"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"CHECKSUM")," and\n",(0,r.kt)("inlineCode",{parentName:"li"},"TIMESTAMP")," which contains, respectively, the md5 checksum and greatest\nmodification timestamp of the files listed on ",(0,r.kt)("inlineCode",{parentName:"li"},"sources:")),(0,r.kt)("li",{parentName:"ul"},"Also, the ",(0,r.kt)("inlineCode",{parentName:"li"},"TASK")," variable is always available with the current task name"),(0,r.kt)("li",{parentName:"ul"},"CLI variables are always treated as global variables"),(0,r.kt)("li",{parentName:"ul"},"Added ",(0,r.kt)("inlineCode",{parentName:"li"},"dir:")," option to ",(0,r.kt)("inlineCode",{parentName:"li"},"includes")," to allow choosing on which directory an\nincluded Taskfile will run:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"includes:\n docs:\n taskfile: ./docs\n dir: ./docs\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Implemented short task syntax. All below syntaxes are equivalent:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print:\n cmds:\n - echo \"Hello, World!\"\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print:\n - echo \"Hello, World!\"\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print: echo \"Hello, World!\"\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"There was a major refactor on how variables are handled. They're now easier\nto understand. The ",(0,r.kt)("inlineCode",{parentName:"li"},"expansions:")," setting was removed as it became unncessary.\nThis is the order in which Task will process variables, each level can see\nthe variables set by the previous one and override those.",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Environment variables"),(0,r.kt)("li",{parentName:"ul"},"Global + CLI variables"),(0,r.kt)("li",{parentName:"ul"},"Call variables"),(0,r.kt)("li",{parentName:"ul"},"Task variables")))))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0afd354a.fb40b428.js b/assets/js/0afd354a.fb40b428.js new file mode 100644 index 00000000..703f84b2 --- /dev/null +++ b/assets/js/0afd354a.fb40b428.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[552],{3905:function(e,n,t){t.d(n,{Zo:function(){return u},kt:function(){return m}});var a=t(7294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function l(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function i(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=a.createContext({}),p=function(e){var n=a.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},u=function(e){var n=p(e.components);return a.createElement(s.Provider,{value:n},e.children)},c="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},k=a.forwardRef((function(e,n){var t=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),c=p(t),k=r,m=c["".concat(s,".").concat(k)]||c[k]||d[k]||l;return t?a.createElement(m,i(i({ref:n},u),{},{components:t})):a.createElement(m,i({ref:n},u))}));function m(e,n){var t=arguments,r=n&&n.mdxType;if("string"==typeof e||r){var l=t.length,i=new Array(l);i[0]=k;var o={};for(var s in n)hasOwnProperty.call(n,s)&&(o[s]=n[s]);o.originalType=e,o[c]="string"==typeof e?e:r,i[1]=o;for(var p=2;p= v3.0.0 anymore.")),(0,r.kt)("p",null,"In the first version of the ",(0,r.kt)("inlineCode",{parentName:"p"},"Taskfile"),", the ",(0,r.kt)("inlineCode",{parentName:"p"},"version:")," key was not available,\nbecause the tasks was in the root of the YAML document. Like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'echo:\n cmds:\n - echo "Hello, World!"\n')),(0,r.kt)("p",null,"The variable priority order was also different:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Call variables"),(0,r.kt)("li",{parentName:"ol"},"Environment"),(0,r.kt)("li",{parentName:"ol"},"Task variables"),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"Taskvars.yml")," variables")),(0,r.kt)("h2",{id:"version-20"},"Version 2.0"),(0,r.kt)("p",null,"At version 2, we introduced the ",(0,r.kt)("inlineCode",{parentName:"p"},"version:")," key, to allow us to evolve Task with\nnew features without breaking existing Taskfiles. The new syntax is as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\ntasks:\n echo:\n cmds:\n - echo \"Hello, World!\"\n")),(0,r.kt)("p",null,"Version 2 allows you to write global variables directly in the Taskfile, if you\ndon't want to create a ",(0,r.kt)("inlineCode",{parentName:"p"},"Taskvars.yml"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\nvars:\n GREETING: Hello, World!\n\ntasks:\n greet:\n cmds:\n - echo \"{{.GREETING}}\"\n")),(0,r.kt)("p",null,"The variable priority order changed to the following:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Task variables"),(0,r.kt)("li",{parentName:"ol"},"Call variables"),(0,r.kt)("li",{parentName:"ol"},"Taskfile variables"),(0,r.kt)("li",{parentName:"ol"},"Taskvars file variables"),(0,r.kt)("li",{parentName:"ol"},"Environment variables")),(0,r.kt)("p",null,"A new global option was added to configure the number of variables expansions\n(which default to 2):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\nexpansions: 3\n\nvars:\n FOO: foo\n BAR: bar\n BAZ: baz\n FOOBAR: '{{.FOO}}{{.BAR}}'\n FOOBARBAZ: '{{.FOOBAR}}{{.BAZ}}'\n\ntasks:\n default:\n cmds:\n - echo \"{{.FOOBARBAZ}}\"\n")),(0,r.kt)("h2",{id:"version-21"},"Version 2.1"),(0,r.kt)("p",null,"Version 2.1 includes a global ",(0,r.kt)("inlineCode",{parentName:"p"},"output")," option, to allow having more control over\nhow commands output are printed to the console (see ",(0,r.kt)("a",{parentName:"p",href:"/usage/#output-syntax"},"documentation")," for\nmore info):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\noutput: prefixed\n\ntasks:\n server:\n cmds:\n - go run main.go\n prefix: server\n")),(0,r.kt)("p",null,"From this version it's also possible to ignore errors of a command or task\n(check documentation ",(0,r.kt)("a",{parentName:"p",href:"/usage/#ignore-errors"},"here"),"):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},'version: \'2\'\n\ntasks:\n example-1:\n cmds:\n - cmd: exit 1\n ignore_error: true\n - echo "This will be print"\n\n example-2:\n cmds:\n - exit 1\n - echo "This will be print"\n ignore_error: true\n')),(0,r.kt)("h2",{id:"version-22"},"Version 2.2"),(0,r.kt)("p",null,"Version 2.2 comes with a global ",(0,r.kt)("inlineCode",{parentName:"p"},"includes")," options to include other Taskfiles:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\nincludes:\n docs: ./documentation # will look for ./documentation/Taskfile.yml\n docker: ./DockerTasks.yml\n")),(0,r.kt)("h2",{id:"version-26"},"Version 2.6"),(0,r.kt)("p",null,"Version 2.6 comes with ",(0,r.kt)("inlineCode",{parentName:"p"},"preconditions")," stanza in tasks."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '2'\n\ntasks:\n upload_environment:\n preconditions:\n - test -f .env\n cmds:\n - aws s3 cp .env s3://myenvironment\n")),(0,r.kt)("p",null,"Please check the ",(0,r.kt)("a",{parentName:"p",href:"/usage/#including-other-taskfiles"},"documentation")),(0,r.kt)("h2",{id:"version-3"},"Version 3"),(0,r.kt)("p",null,"These are some major changes done on ",(0,r.kt)("inlineCode",{parentName:"p"},"v3"),":"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Task's output will now be colored"),(0,r.kt)("li",{parentName:"ul"},"Added support for ",(0,r.kt)("inlineCode",{parentName:"li"},".env")," like files"),(0,r.kt)("li",{parentName:"ul"},"Added ",(0,r.kt)("inlineCode",{parentName:"li"},"label:")," setting to task so one can override how the task name appear in\nthe logs"),(0,r.kt)("li",{parentName:"ul"},"A global ",(0,r.kt)("inlineCode",{parentName:"li"},"method:")," was added to allow setting the default method, and Task's\ndefault changed to ",(0,r.kt)("inlineCode",{parentName:"li"},"checksum")),(0,r.kt)("li",{parentName:"ul"},"Two magic variables were added when using ",(0,r.kt)("inlineCode",{parentName:"li"},"status:"),": ",(0,r.kt)("inlineCode",{parentName:"li"},"CHECKSUM")," and\n",(0,r.kt)("inlineCode",{parentName:"li"},"TIMESTAMP")," which contains, respectively, the md5 checksum and greatest\nmodification timestamp of the files listed on ",(0,r.kt)("inlineCode",{parentName:"li"},"sources:")),(0,r.kt)("li",{parentName:"ul"},"Also, the ",(0,r.kt)("inlineCode",{parentName:"li"},"TASK")," variable is always available with the current task name"),(0,r.kt)("li",{parentName:"ul"},"CLI variables are always treated as global variables"),(0,r.kt)("li",{parentName:"ul"},"Added ",(0,r.kt)("inlineCode",{parentName:"li"},"dir:")," option to ",(0,r.kt)("inlineCode",{parentName:"li"},"includes")," to allow choosing on which directory an\nincluded Taskfile will run:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"includes:\n docs:\n taskfile: ./docs\n dir: ./docs\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Implemented short task syntax. All below syntaxes are equivalent:")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print:\n cmds:\n - echo \"Hello, World!\"\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print:\n - echo \"Hello, World!\"\n")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print: echo \"Hello, World!\"\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"There was a major refactor on how variables are handled. They're now easier to\nunderstand. The ",(0,r.kt)("inlineCode",{parentName:"li"},"expansions:")," setting was removed as it became unncessary.\nThis is the order in which Task will process variables, each level can see the\nvariables set by the previous one and override those.",(0,r.kt)("ul",{parentName:"li"},(0,r.kt)("li",{parentName:"ul"},"Environment variables"),(0,r.kt)("li",{parentName:"ul"},"Global + CLI variables"),(0,r.kt)("li",{parentName:"ul"},"Call variables"),(0,r.kt)("li",{parentName:"ul"},"Task variables")))))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/0e384e19.47884a35.js b/assets/js/0e384e19.47884a35.js new file mode 100644 index 00000000..c59fca76 --- /dev/null +++ b/assets/js/0e384e19.47884a35.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[671],{3905:function(M,N,D){D.d(N,{Zo:function(){return t},kt:function(){return O}});var j=D(7294);function T(M,N,D){return N in M?Object.defineProperty(M,N,{value:D,enumerable:!0,configurable:!0,writable:!0}):M[N]=D,M}function u(M,N){var D=Object.keys(M);if(Object.getOwnPropertySymbols){var j=Object.getOwnPropertySymbols(M);N&&(j=j.filter((function(N){return Object.getOwnPropertyDescriptor(M,N).enumerable}))),D.push.apply(D,j)}return D}function I(M){for(var N=1;N=0||(T[D]=M[D]);return T}(M,N);if(Object.getOwnPropertySymbols){var u=Object.getOwnPropertySymbols(M);for(j=0;j=0||Object.prototype.propertyIsEnumerable.call(M,D)&&(T[D]=M[D])}return T}var g=j.createContext({}),e=function(M){var N=j.useContext(g),D=N;return M&&(D="function"==typeof M?M(N):I(I({},N),M)),D},t=function(M){var N=e(M.components);return j.createElement(g.Provider,{value:N},M.children)},i="mdxType",A={inlineCode:"code",wrapper:function(M){var N=M.children;return j.createElement(j.Fragment,{},N)}},y=j.forwardRef((function(M,N){var D=M.components,T=M.mdxType,u=M.originalType,g=M.parentName,t=z(M,["components","mdxType","originalType","parentName"]),i=e(D),y=T,O=i["".concat(g,".").concat(y)]||i[y]||A[y]||u;return D?j.createElement(O,I(I({ref:N},t),{},{components:D})):j.createElement(O,I({ref:N},t))}));function O(M,N){var D=arguments,T=N&&N.mdxType;if("string"==typeof M||T){var u=D.length,I=new Array(u);I[0]=y;var z={};for(var g in N)hasOwnProperty.call(N,g)&&(z[g]=N[g]);z.originalType=M,z[i]="string"==typeof M?M:T,I[1]=z;for(var e=2;e=0||(T[D]=M[D]);return T}(M,N);if(Object.getOwnPropertySymbols){var u=Object.getOwnPropertySymbols(M);for(j=0;j=0||Object.prototype.propertyIsEnumerable.call(M,D)&&(T[D]=M[D])}return T}var g=j.createContext({}),e=function(M){var N=j.useContext(g),D=N;return M&&(D="function"==typeof M?M(N):I(I({},N),M)),D},t=function(M){var N=e(M.components);return j.createElement(g.Provider,{value:N},M.children)},i="mdxType",A={inlineCode:"code",wrapper:function(M){var N=M.children;return j.createElement(j.Fragment,{},N)}},y=j.forwardRef((function(M,N){var D=M.components,T=M.mdxType,u=M.originalType,g=M.parentName,t=z(M,["components","mdxType","originalType","parentName"]),i=e(D),y=T,O=i["".concat(g,".").concat(y)]||i[y]||A[y]||u;return D?j.createElement(O,I(I({ref:N},t),{},{components:D})):j.createElement(O,I({ref:N},t))}));function O(M,N){var D=arguments,T=N&&N.mdxType;if("string"==typeof M||T){var u=D.length,I=new Array(u);I[0]=y;var z={};for(var g in N)hasOwnProperty.call(N,g)&&(z[g]=N[g]);z.originalType=M,z[i]="string"==typeof M?M:T,I[1]=z;for(var e=2;e=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},c="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=u(n),d=o,h=c["".concat(s,".").concat(d)]||c[d]||f[d]||a;return n?r.createElement(h,i(i({ref:t},p),{},{components:n})):r.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:o,i[1]=l;for(var u=2;u=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=r.createContext({}),u=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=u(e.components);return r.createElement(s.Provider,{value:t},e.children)},c="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),c=u(n),d=o,h=c["".concat(s,".").concat(d)]||c[d]||f[d]||a;return n?r.createElement(h,i(i({ref:t},p),{},{components:n})):r.createElement(h,i({ref:t},p))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=d;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:o,i[1]=l;for(var u=2;u=0||(l[a]=e[a]);return l}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(l[a]=e[a])}return l}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},u=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",k={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,l=e.mdxType,o=e.originalType,s=e.parentName,u=r(e,["components","mdxType","originalType","parentName"]),c=p(a),m=l,h=c["".concat(s,".").concat(m)]||c[m]||k[m]||o;return a?n.createElement(h,i(i({ref:t},u),{},{components:a})):n.createElement(h,i({ref:t},u))}));function h(e,t){var a=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var o=a.length,i=new Array(o);i[0]=m;var r={};for(var s in t)hasOwnProperty.call(t,s)&&(r[s]=t[s]);r.originalType=e,r[c]="string"==typeof e?e:l,i[1]=r;for(var p=2;p=0||(l[a]=e[a]);return l}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(l[a]=e[a])}return l}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},u=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},c="mdxType",k={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,l=e.mdxType,o=e.originalType,s=e.parentName,u=r(e,["components","mdxType","originalType","parentName"]),c=p(a),m=l,h=c["".concat(s,".").concat(m)]||c[m]||k[m]||o;return a?n.createElement(h,i(i({ref:t},u),{},{components:a})):n.createElement(h,i({ref:t},u))}));function h(e,t){var a=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var o=a.length,i=new Array(o);i[0]=m;var r={};for(var s in t)hasOwnProperty.call(t,s)&&(r[s]=t[s]);r.originalType=e,r[c]="string"==typeof e?e:l,i[1]=r;for(var p=2;p=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var u=a.createContext({}),l=function(e){var t=a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,h=d["".concat(u,".").concat(m)]||d[m]||p[m]||i;return n?a.createElement(h,o(o({ref:t},c),{},{components:n})):a.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var l=2;l "),"."),(0,r.kt)("h3",{id:"updating-documentation"},"Updating documentation"),(0,r.kt)("p",null,"Task uses ",(0,r.kt)("a",{parentName:"p",href:"https://docusaurus.io"},"Docusaurus")," to host a documentation server. This can be setup and run\nlocally by using ",(0,r.kt)("inlineCode",{parentName:"p"},"task docs")," (requires ",(0,r.kt)("inlineCode",{parentName:"p"},"nodejs")," & ",(0,r.kt)("inlineCode",{parentName:"p"},"yarn"),"). All content is\nwritten in Markdown and is located in the ",(0,r.kt)("inlineCode",{parentName:"p"},"docs/docs")," directory. All Markdown\ndocuments should have an 80 character line wrap limit."),(0,r.kt)("p",null,"When making a change, consider whether a change to the ",(0,r.kt)("a",{parentName:"p",href:"/usage/"},"Usage Guide"),"\nis necessary. This document contains descriptions and examples of how to use\nTask features. If you're adding a new feature, try to find an appropriate place\nto add a new section. If you're updating an existing feature, ensure that the\ndocumentation and any examples are up-to-date. Ensure that any examples follow\nthe ",(0,r.kt)("a",{parentName:"p",href:"/styleguide/"},"Taskfile Styleguide"),"."),(0,r.kt)("p",null,"If you added a new field, command or flag, ensure that you add it to the ",(0,r.kt)("a",{parentName:"p",href:"/api/"},"API\nReference"),". New fields also need to be added to the ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/blob/master/docs/static/schema.json"},"JSON\nSchema"),". The descriptions for fields in the API reference and the schema should\nmatch."),(0,r.kt)("h3",{id:"writing-tests"},"Writing tests"),(0,r.kt)("p",null,"Most of Task's test are held in the ",(0,r.kt)("inlineCode",{parentName:"p"},"task_test.go")," file in the project root and\nthis is where you'll most likely want to add new ones too. Most of these tests\nalso have a subdirectory in the ",(0,r.kt)("inlineCode",{parentName:"p"},"testdata")," directory where any Taskfiles/data\nrequired to run the tests are stored."),(0,r.kt)("p",null,"When making a changes, consider whether new tests are required. These tests\nshould ensure that the functionality you are adding will continue to work in the\nfuture. Existing tests may also need updating if you have changed Task's\nbehavior."),(0,r.kt)("h2",{id:"3-committing-your-code"},"3. Committing your code"),(0,r.kt)("p",null,"Try to write meaningful commit messages and avoid having too many commits on the\nPR. Most PRs should likely have a single commit (although for bigger PRs it may\nbe reasonable to split it in a few). Git squash and rebase is your friend!"),(0,r.kt)("h2",{id:"4-submitting-a-pr"},"4. Submitting a PR"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Describe your changes")," - Ensure that you provide a comprehensive\ndescription of your changes."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Issue/PR links")," - Link any previous work such as related issues or PRs.\nPlease describe how your changes differ to/extend this work."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Examples")," - Add any examples that you think are useful to demonstrate the\neffect of your changes."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Draft PRs")," - If your changes are incomplete, but you would like to discuss\nthem, open the PR as a draft and add a comment to start a discussion. Using\ncomments rather than the PR description allows the description to be updated\nlater while preserving any discussions.")),(0,r.kt)("h2",{id:"faq"},"FAQ"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"I want to contribute, where do I start?")),(0,r.kt)("p",null,"Take a look at the list of ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/issues"},"open issues"),". We have a ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22"},"good first issue")," label for\nsimpler issues that are ideal for first time contributions."),(0,r.kt)("p",null,"All kinds of contributions are welcome, whether its a typo fix or a shiny new\nfeature. You can also contribute by upvoting/commenting on issues, helping to\nanswer questions or contributing to other ",(0,r.kt)("a",{parentName:"p",href:"/community/"},"community projects"),"."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"I'm stuck, where can I get help?")),(0,r.kt)("p",null,"If you have questions, feel free to ask them in the ",(0,r.kt)("inlineCode",{parentName:"p"},"#help")," forum channel on our\n",(0,r.kt)("a",{parentName:"p",href:"https://discord.gg/6TY36E39UK"},"Discord server")," or open a ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/discussions"},"Discussion")," on GitHub."),(0,r.kt)("hr",null))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[80],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var u=a.createContext({}),l=function(e){var t=a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=l(e.components);return a.createElement(u.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,u=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),d=l(n),m=r,h=d["".concat(u,".").concat(m)]||d[m]||p[m]||i;return n?a.createElement(h,o(o({ref:t},c),{},{components:n})):a.createElement(h,o({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=m;var s={};for(var u in t)hasOwnProperty.call(t,u)&&(s[u]=t[u]);s.originalType=e,s[d]="string"==typeof e?e:r,o[1]=s;for(var l=2;l "),"."),(0,r.kt)("h3",{id:"updating-documentation"},"Updating documentation"),(0,r.kt)("p",null,"Task uses ",(0,r.kt)("a",{parentName:"p",href:"https://docusaurus.io"},"Docusaurus")," to host a documentation server. This can be\nsetup and run locally by using ",(0,r.kt)("inlineCode",{parentName:"p"},"task docs")," (requires ",(0,r.kt)("inlineCode",{parentName:"p"},"nodejs")," & ",(0,r.kt)("inlineCode",{parentName:"p"},"yarn"),"). All\ncontent is written in Markdown and is located in the ",(0,r.kt)("inlineCode",{parentName:"p"},"docs/docs")," directory. All\nMarkdown documents should have an 80 character line wrap limit."),(0,r.kt)("p",null,"When making a change, consider whether a change to the ",(0,r.kt)("a",{parentName:"p",href:"/usage/"},"Usage Guide"),"\nis necessary. This document contains descriptions and examples of how to use\nTask features. If you're adding a new feature, try to find an appropriate place\nto add a new section. If you're updating an existing feature, ensure that the\ndocumentation and any examples are up-to-date. Ensure that any examples follow\nthe ",(0,r.kt)("a",{parentName:"p",href:"/styleguide/"},"Taskfile Styleguide"),"."),(0,r.kt)("p",null,"If you added a new field, command or flag, ensure that you add it to the\n",(0,r.kt)("a",{parentName:"p",href:"/api/"},"API Reference"),". New fields also need to be added to the\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/blob/master/docs/static/schema.json"},"JSON Schema"),". The descriptions for fields in the API reference and\nthe schema should match."),(0,r.kt)("h3",{id:"writing-tests"},"Writing tests"),(0,r.kt)("p",null,"Most of Task's test are held in the ",(0,r.kt)("inlineCode",{parentName:"p"},"task_test.go")," file in the project root and\nthis is where you'll most likely want to add new ones too. Most of these tests\nalso have a subdirectory in the ",(0,r.kt)("inlineCode",{parentName:"p"},"testdata")," directory where any Taskfiles/data\nrequired to run the tests are stored."),(0,r.kt)("p",null,"When making a changes, consider whether new tests are required. These tests\nshould ensure that the functionality you are adding will continue to work in the\nfuture. Existing tests may also need updating if you have changed Task's\nbehavior."),(0,r.kt)("h2",{id:"3-committing-your-code"},"3. Committing your code"),(0,r.kt)("p",null,"Try to write meaningful commit messages and avoid having too many commits on the\nPR. Most PRs should likely have a single commit (although for bigger PRs it may\nbe reasonable to split it in a few). Git squash and rebase is your friend!"),(0,r.kt)("h2",{id:"4-submitting-a-pr"},"4. Submitting a PR"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Describe your changes")," - Ensure that you provide a comprehensive\ndescription of your changes."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Issue/PR links")," - Link any previous work such as related issues or PRs.\nPlease describe how your changes differ to/extend this work."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Examples")," - Add any examples that you think are useful to demonstrate the\neffect of your changes."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Draft PRs")," - If your changes are incomplete, but you would like to discuss\nthem, open the PR as a draft and add a comment to start a discussion. Using\ncomments rather than the PR description allows the description to be updated\nlater while preserving any discussions.")),(0,r.kt)("h2",{id:"faq"},"FAQ"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"I want to contribute, where do I start?")),(0,r.kt)("p",null,"Take a look at the list of ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/issues"},"open issues"),". We have a ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22"},"good first\nissue")," label for simpler issues that are ideal for first time\ncontributions."),(0,r.kt)("p",null,"All kinds of contributions are welcome, whether its a typo fix or a shiny new\nfeature. You can also contribute by upvoting/commenting on issues, helping to\nanswer questions or contributing to other ",(0,r.kt)("a",{parentName:"p",href:"/community/"},"community projects"),"."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"I'm stuck, where can I get help?")),(0,r.kt)("p",null,"If you have questions, feel free to ask them in the ",(0,r.kt)("inlineCode",{parentName:"p"},"#help")," forum channel on our\n",(0,r.kt)("a",{parentName:"p",href:"https://discord.gg/6TY36E39UK"},"Discord server")," or open a ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/discussions"},"Discussion")," on GitHub."),(0,r.kt)("hr",null))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5ef0e9d6.537bbfb9.js b/assets/js/5ef0e9d6.537bbfb9.js new file mode 100644 index 00000000..4153adba --- /dev/null +++ b/assets/js/5ef0e9d6.537bbfb9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[880],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return d}});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=p(n),m=i,d=c["".concat(l,".").concat(m)]||c[m]||h[m]||r;return n?a.createElement(d,o(o({ref:t},u),{},{components:n})):a.createElement(d,o({ref:t},u))}));function d(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:i,o[1]=s;for(var p=2;p=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),c=p(n),m=i,d=c["".concat(l,".").concat(m)]||c[m]||h[m]||r;return n?a.createElement(d,o(o({ref:t},u),{},{components:n})):a.createElement(d,o({ref:t},u))}));function d(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,o=new Array(r);o[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[c]="string"==typeof e?e:i,o[1]=s;for(var p=2;p=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var r=a.createContext({}),p=function(e){var n=a.useContext(r),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},d=function(e){var n=p(e.components);return a.createElement(r.Provider,{value:n},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},c=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,l=e.originalType,r=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),u=p(t),c=i,k=u["".concat(r,".").concat(c)]||u[c]||m[c]||l;return t?a.createElement(k,s(s({ref:n},d),{},{components:t})):a.createElement(k,s({ref:n},d))}));function k(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var l=t.length,s=new Array(l);s[0]=c;var o={};for(var r in n)hasOwnProperty.call(n,r)&&(o[r]=n[r]);o.originalType=e,o[u]="string"==typeof e?e:i,s[1]=o;for(var p=2;pdefer",id:"doing-task-cleanup-with-defer",level:2},{value:"Go's template engine",id:"gos-template-engine",level:2},{value:"Help",id:"help",level:2},{value:"Display summary of task",id:"display-summary-of-task",level:2},{value:"Task aliases",id:"task-aliases",level:2},{value:"Overriding task name",id:"overriding-task-name",level:2},{value:"Silent mode",id:"silent-mode",level:2},{value:"Dry run mode",id:"dry-run-mode",level:2},{value:"Ignore errors",id:"ignore-errors",level:2},{value:"Output syntax",id:"output-syntax",level:2},{value:"Interactive CLI application",id:"interactive-cli-application",level:2},{value:"Short task syntax",id:"short-task-syntax",level:2},{value:"set and shopt",id:"set-and-shopt",level:2},{value:"Watch tasks",id:"watch-tasks",level:2}],d={toc:p};function u(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,a.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"usage"},"Usage"),(0,i.kt)("h2",{id:"getting-started"},"Getting started"),(0,i.kt)("p",null,"Create a file called ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," in the root of your project. The ",(0,i.kt)("inlineCode",{parentName:"p"},"cmds"),"\nattribute should contain the commands of a task. The example below allows\ncompiling a Go app and uses ",(0,i.kt)("a",{parentName:"p",href:"https://esbuild.github.io/"},"esbuild")," to concat and\nminify multiple CSS files into a single one."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n cmds:\n - go build -v -i main.go\n\n assets:\n cmds:\n - esbuild --bundle --minify css/index.css > public/bundle.css\n")),(0,i.kt)("p",null,"Running the tasks is as simple as running:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"task assets build\n")),(0,i.kt)("p",null,"Task uses ",(0,i.kt)("a",{parentName:"p",href:"https://mvdan.cc/sh/"},"mvdan.cc/sh"),", a native Go sh interpreter. So\nyou can write sh/bash commands, and it will work even on Windows, where ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," or\n",(0,i.kt)("inlineCode",{parentName:"p"},"bash")," are usually not available. Just remember any executable called must be\navailable by the OS or in PATH."),(0,i.kt)("p",null,'If you omit a task name, "default" will be assumed.'),(0,i.kt)("h2",{id:"supported-file-names"},"Supported file names"),(0,i.kt)("p",null,"Task will look for the following file names, in order of priority:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Taskfile.yml"),(0,i.kt)("li",{parentName:"ul"},"Taskfile.yaml"),(0,i.kt)("li",{parentName:"ul"},"Taskfile.dist.yml"),(0,i.kt)("li",{parentName:"ul"},"Taskfile.dist.yaml")),(0,i.kt)("p",null,"The intention of having the ",(0,i.kt)("inlineCode",{parentName:"p"},".dist")," variants is to allow projects to have one\ncommitted version (",(0,i.kt)("inlineCode",{parentName:"p"},".dist"),") while still allowing individual users to override\nthe Taskfile by adding an additional ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," (which would be on\n",(0,i.kt)("inlineCode",{parentName:"p"},".gitignore"),")."),(0,i.kt)("h3",{id:"running-a-taskfile-from-a-subdirectory"},"Running a Taskfile from a subdirectory"),(0,i.kt)("p",null,"If a Taskfile cannot be found in the current working directory, it will walk up\nthe file tree until it finds one (similar to how ",(0,i.kt)("inlineCode",{parentName:"p"},"git")," works). When running Task\nfrom a subdirectory like this, it will behave as if you ran it from the\ndirectory containing the Taskfile."),(0,i.kt)("p",null,"You can use this functionality along with the special ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}"),"\nvariable to create some very useful reusable tasks. For example, if you have a\nmonorepo with directories for each microservice, you can ",(0,i.kt)("inlineCode",{parentName:"p"},"cd")," into a\nmicroservice directory and run a task command to bring it up without having to\ncreate multiple tasks or Taskfiles with identical content. For example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n up:\n dir: '{{.USER_WORKING_DIR}}'\n preconditions:\n - test -f docker-compose.yml\n cmds:\n - docker-compose up -d\n")),(0,i.kt)("p",null,"In this example, we can run ",(0,i.kt)("inlineCode",{parentName:"p"},"cd ")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"task up")," and as long as the\n",(0,i.kt)("inlineCode",{parentName:"p"},"")," directory contains a ",(0,i.kt)("inlineCode",{parentName:"p"},"docker-compose.yml"),", the Docker composition\nwill be brought up."),(0,i.kt)("h3",{id:"running-a-global-taskfile"},"Running a global Taskfile"),(0,i.kt)("p",null,"If you call Task with the ",(0,i.kt)("inlineCode",{parentName:"p"},"--global")," (alias ",(0,i.kt)("inlineCode",{parentName:"p"},"-g"),") flag, it will look for your\nhome directory instead of your working directory. In short, Task will look for a\nTaskfile on either ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yml")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yaml")," paths."),(0,i.kt)("p",null,"This is useful to have automation that you can run from anywhere in your system!"),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"When running your global Taskfile with ",(0,i.kt)("inlineCode",{parentName:"p"},"-g"),", tasks will run on ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME")," by\ndefault, and not on your working directory!"),(0,i.kt)("p",{parentName:"admonition"},"As mentioned in the previous section, the ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}")," special\nvariable can be very handy here to run stuff on the directory you're calling\n",(0,i.kt)("inlineCode",{parentName:"p"},"task -g")," from."),(0,i.kt)("pre",{parentName:"admonition"},(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n from-home:\n cmds:\n - pwd\n\n from-working-directory:\n dir: '{{.USER_WORKING_DIR}}'\n cmds:\n - pwd\n"))),(0,i.kt)("h2",{id:"environment-variables"},"Environment variables"),(0,i.kt)("h3",{id:"task"},"Task"),(0,i.kt)("p",null,"You can use ",(0,i.kt)("inlineCode",{parentName:"p"},"env")," to set custom environment variables for a specific task:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n greet:\n cmds:\n - echo $GREETING\n env:\n GREETING: Hey, there!\n")),(0,i.kt)("p",null,"Additionally, you can set global environment variables that will be available to\nall tasks:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nenv:\n GREETING: Hey, there!\n\ntasks:\n greet:\n cmds:\n - echo $GREETING\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("inlineCode",{parentName:"p"},"env")," supports expansion and retrieving output from a shell command just like\nvariables, as you can see in the ",(0,i.kt)("a",{parentName:"p",href:"#variables"},"Variables")," section.")),(0,i.kt)("h3",{id:"env-files"},".env files"),(0,i.kt)("p",null,"You can also ask Task to include ",(0,i.kt)("inlineCode",{parentName:"p"},".env")," like files by using the ",(0,i.kt)("inlineCode",{parentName:"p"},"dotenv:"),"\nsetting:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title=".env"',title:'".env"'},"KEYNAME=VALUE\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title="testing/.env"',title:'"testing/.env"'},"ENDPOINT=testing.com\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml",metastring:'title="Taskfile.yml"',title:'"Taskfile.yml"'},"version: '3'\n\nenv:\n ENV: testing\n\ndotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']\n\ntasks:\n greet:\n cmds:\n - echo \"Using $KEYNAME and endpoint $ENDPOINT\"\n")),(0,i.kt)("p",null,"Dotenv files can also be specified at the task level:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nenv:\n ENV: testing\n\ntasks:\n greet:\n dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']\n cmds:\n - echo \"Using $KEYNAME and endpoint $ENDPOINT\"\n")),(0,i.kt)("p",null,"Environment variables specified explicitly at the task-level will override\nvariables defined in dotfiles:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nenv:\n ENV: testing\n\ntasks:\n greet:\n dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']\n env:\n KEYNAME: DIFFERENT_VALUE\n cmds:\n - echo \"Using $KEYNAME and endpoint $ENDPOINT\"\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Please note that you are not currently able to use the ",(0,i.kt)("inlineCode",{parentName:"p"},"dotenv")," key inside\nincluded Taskfiles.")),(0,i.kt)("h2",{id:"including-other-taskfiles"},"Including other Taskfiles"),(0,i.kt)("p",null,"If you want to share tasks between different projects (Taskfiles), you can use\nthe importing mechanism to include other Taskfiles using the ",(0,i.kt)("inlineCode",{parentName:"p"},"includes")," keyword:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n docs: ./documentation # will look for ./documentation/Taskfile.yml\n docker: ./DockerTasks.yml\n")),(0,i.kt)("p",null,"The tasks described in the given Taskfiles will be available with the informed\nnamespace. So, you'd call ",(0,i.kt)("inlineCode",{parentName:"p"},"task docs:serve")," to run the ",(0,i.kt)("inlineCode",{parentName:"p"},"serve")," task from\n",(0,i.kt)("inlineCode",{parentName:"p"},"documentation/Taskfile.yml")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"task docker:build")," to run the ",(0,i.kt)("inlineCode",{parentName:"p"},"build")," task from\nthe ",(0,i.kt)("inlineCode",{parentName:"p"},"DockerTasks.yml")," file."),(0,i.kt)("p",null,"Relative paths are resolved relative to the directory containing the including\nTaskfile."),(0,i.kt)("h3",{id:"os-specific-taskfiles"},"OS-specific Taskfiles"),(0,i.kt)("p",null,"With ",(0,i.kt)("inlineCode",{parentName:"p"},"version: '2'"),", task automatically includes any ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_{{OS}}.yml")," if it\nexists (for example: ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_windows.yml"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_linux.yml")," or\n",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_darwin.yml"),"). Since this behavior was a bit too implicit, it was\nremoved on version 3, but you still can have a similar behavior by explicitly\nimporting these files:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n build: ./Taskfile_{{OS}}.yml\n")),(0,i.kt)("h3",{id:"directory-of-included-taskfile"},"Directory of included Taskfile"),(0,i.kt)("p",null,"By default, included Taskfile's tasks are run in the current directory, even if\nthe Taskfile is in another directory, but you can force its tasks to run in\nanother directory by using this alternative syntax:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n docs:\n taskfile: ./docs/Taskfile.yml\n dir: ./docs\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"The included Taskfiles must be using the same schema version as the main\nTaskfile uses.")),(0,i.kt)("h3",{id:"optional-includes"},"Optional includes"),(0,i.kt)("p",null,"Includes marked as optional will allow Task to continue execution as normal if\nthe included file is missing."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n tests:\n taskfile: ./tests/Taskfile.yml\n optional: true\n\ntasks:\n greet:\n cmds:\n - echo \"This command can still be successfully executed if\n ./tests/Taskfile.yml does not exist\"\n")),(0,i.kt)("h3",{id:"internal-includes"},"Internal includes"),(0,i.kt)("p",null,"Includes marked as internal will set all the tasks of the included file to be\ninternal as well (see the ",(0,i.kt)("a",{parentName:"p",href:"#internal-tasks"},"Internal tasks")," section below). This\nis useful when including utility tasks that are not intended to be used directly\nby the user."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n tests:\n taskfile: ./taskfiles/Utils.yml\n internal: true\n")),(0,i.kt)("h3",{id:"vars-of-included-taskfiles"},"Vars of included Taskfiles"),(0,i.kt)("p",null,"You can also specify variables when including a Taskfile. This may be useful for\nhaving reusable Taskfile that can be tweaked or even included more than once:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n backend:\n taskfile: ./taskfiles/Docker.yml\n vars:\n DOCKER_IMAGE: backend_image\n\n frontend:\n taskfile: ./taskfiles/Docker.yml\n vars:\n DOCKER_IMAGE: frontend_image\n")),(0,i.kt)("h3",{id:"namespace-aliases"},"Namespace aliases"),(0,i.kt)("p",null,"When including a Taskfile, you can give the namespace a list of ",(0,i.kt)("inlineCode",{parentName:"p"},"aliases"),". This\nworks in the same way as ",(0,i.kt)("a",{parentName:"p",href:"#task-aliases"},"task aliases")," and can be used together\nto create shorter and easier-to-type commands."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n generate:\n taskfile: ./taskfiles/Generate.yml\n aliases: [gen]\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Vars declared in the included Taskfile have preference over the variables in the\nincluding Taskfile! If you want a variable in an included Taskfile to be\noverridable, use the\n",(0,i.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/defaults.html"},"default function"),":\n",(0,i.kt)("inlineCode",{parentName:"p"},"MY_VAR: '{{.MY_VAR | default \"my-default-value\"}}'"),".")),(0,i.kt)("h2",{id:"internal-tasks"},"Internal tasks"),(0,i.kt)("p",null,"Internal tasks are tasks that cannot be called directly by the user. They will\nnot appear in the output when running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --list|--list-all"),". Other tasks may\ncall internal tasks in the usual way. This is useful for creating reusable,\nfunction-like tasks that have no useful purpose on the command line."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build-image-1:\n cmds:\n - task: build-image\n vars:\n DOCKER_IMAGE: image-1\n\n build-image:\n internal: true\n cmds:\n - docker build -t {{.DOCKER_IMAGE}} .\n")),(0,i.kt)("h2",{id:"task-directory"},"Task directory"),(0,i.kt)("p",null,"By default, tasks will be executed in the directory where the Taskfile is\nlocated. But you can easily make the task run in another folder, informing\n",(0,i.kt)("inlineCode",{parentName:"p"},"dir"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n serve:\n dir: public/www\n cmds:\n # run http server\n - caddy\n")),(0,i.kt)("p",null,"If the directory does not exist, ",(0,i.kt)("inlineCode",{parentName:"p"},"task")," creates it."),(0,i.kt)("h2",{id:"task-dependencies"},"Task dependencies"),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"Dependencies run in parallel, so dependencies of a task should not depend one\nanother. If you want to force tasks to run serially, take a look at the\n",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"Calling Another Task")," section below.")),(0,i.kt)("p",null,"You may have tasks that depend on others. Just pointing them on ",(0,i.kt)("inlineCode",{parentName:"p"},"deps")," will make\nthem run automatically before running the parent task:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n deps: [assets]\n cmds:\n - go build -v -i main.go\n\n assets:\n cmds:\n - esbuild --bundle --minify css/index.css > public/bundle.css\n")),(0,i.kt)("p",null,"In the above example, ",(0,i.kt)("inlineCode",{parentName:"p"},"assets")," will always run right before ",(0,i.kt)("inlineCode",{parentName:"p"},"build")," if you run\n",(0,i.kt)("inlineCode",{parentName:"p"},"task build"),"."),(0,i.kt)("p",null,"A task can have only dependencies and no commands to group tasks together:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n assets:\n deps: [js, css]\n\n js:\n cmds:\n - esbuild --bundle --minify js/index.js > public/bundle.js\n\n css:\n cmds:\n - esbuild --bundle --minify css/index.css > public/bundle.css\n")),(0,i.kt)("p",null,"If there is more than one dependency, they always run in parallel for better\nperformance."),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"You can also make the tasks given by the command line run in parallel by using\nthe ",(0,i.kt)("inlineCode",{parentName:"p"},"--parallel")," flag (alias ",(0,i.kt)("inlineCode",{parentName:"p"},"-p"),"). Example: ",(0,i.kt)("inlineCode",{parentName:"p"},"task --parallel js css"),".")),(0,i.kt)("p",null,"If you want to pass information to dependencies, you can do that the same manner\nas you would to ",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"call another task"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n deps:\n - task: echo_sth\n vars: { TEXT: 'before 1' }\n - task: echo_sth\n vars: { TEXT: 'before 2' }\n cmds:\n - echo \"after\"\n\n echo_sth:\n cmds:\n - echo {{.TEXT}}\n")),(0,i.kt)("h2",{id:"platform-specific-tasks-and-commands"},"Platform specific tasks and commands"),(0,i.kt)("p",null,"If you want to restrict the running of tasks to explicit platforms, this can be\nachieved using the ",(0,i.kt)("inlineCode",{parentName:"p"},"platforms:")," key. Tasks can be restricted to a specific OS,\narchitecture or a combination of both. On a mismatch, the task or command will\nbe skipped, and no error will be thrown."),(0,i.kt)("p",null,"The values allowed as OS or Arch are valid ",(0,i.kt)("inlineCode",{parentName:"p"},"GOOS")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"GOARCH")," values, as\ndefined by the Go language\n",(0,i.kt)("a",{parentName:"p",href:"https://github.com/golang/go/blob/master/src/go/build/syslist.go"},"here"),"."),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"build-windows")," task below will run only on Windows, and on any\narchitecture:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build-windows:\n platforms: [windows]\n cmds:\n - echo 'Running command on Windows'\n")),(0,i.kt)("p",null,"This can be restricted to a specific architecture as follows:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build-windows-amd64:\n platforms: [windows/amd64]\n cmds:\n - echo 'Running command on Windows (amd64)'\n")),(0,i.kt)("p",null,"It is also possible to restrict the task to specific architectures:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build-amd64:\n platforms: [amd64]\n cmds:\n - echo 'Running command on amd64'\n")),(0,i.kt)("p",null,"Multiple platforms can be specified as follows:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n platforms: [windows/amd64, darwin]\n cmds:\n - echo 'Running command on Windows (amd64) and macOS'\n")),(0,i.kt)("p",null,"Individual commands can also be restricted to specific platforms:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n cmds:\n - cmd: echo 'Running command on Windows (amd64) and macOS'\n platforms: [windows/amd64, darwin]\n - cmd: echo 'Running on all platforms'\n")),(0,i.kt)("h2",{id:"calling-another-task"},"Calling another task"),(0,i.kt)("p",null,"When a task has many dependencies, they are executed concurrently. This will\noften result in a faster build pipeline. However, in some situations, you may\nneed to call other tasks serially. In this case, use the following syntax:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'version: \'3\'\n\ntasks:\n main-task:\n cmds:\n - task: task-to-be-called\n - task: another-task\n - echo "Both done"\n\n task-to-be-called:\n cmds:\n - echo "Task to be called"\n\n another-task:\n cmds:\n - echo "Another task"\n')),(0,i.kt)("p",null,"Overriding variables in the called task is as simple as informing ",(0,i.kt)("inlineCode",{parentName:"p"},"vars"),"\nattribute:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n greet:\n vars:\n RECIPIENT: '{{default \"World\" .RECIPIENT}}'\n cmds:\n - echo \"Hello, {{.RECIPIENT}}!\"\n\n greet-pessimistically:\n cmds:\n - task: greet\n vars: { RECIPIENT: 'Cruel World' }\n")),(0,i.kt)("p",null,"The above syntax is also supported in ",(0,i.kt)("inlineCode",{parentName:"p"},"deps"),"."),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"NOTE: If you want to call a task declared in the root Taskfile from within an\n",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"included Taskfile"),", add a leading ",(0,i.kt)("inlineCode",{parentName:"p"},":")," like this:\n",(0,i.kt)("inlineCode",{parentName:"p"},"task: :task-name"),".")),(0,i.kt)("h2",{id:"prevent-unnecessary-work"},"Prevent unnecessary work"),(0,i.kt)("h3",{id:"by-fingerprinting-locally-generated-files-and-their-sources"},"By fingerprinting locally generated files and their sources"),(0,i.kt)("p",null,"If a task generates something, you can inform Task the source and generated\nfiles, so Task will prevent running them if not necessary."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n deps: [js, css]\n cmds:\n - go build -v -i main.go\n\n js:\n cmds:\n - esbuild --bundle --minify js/index.js > public/bundle.js\n sources:\n - src/js/**/*.js\n generates:\n - public/bundle.js\n\n css:\n cmds:\n - esbuild --bundle --minify css/index.css > public/bundle.css\n sources:\n - src/css/**/*.css\n generates:\n - public/bundle.css\n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"sources")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"generates")," can be files or file patterns. When given, Task will\ncompare the checksum of the source files to determine if it's necessary to run\nthe task. If not, it will just print a message like ",(0,i.kt)("inlineCode",{parentName:"p"},'Task "js" is up to date'),"."),(0,i.kt)("p",null,"If you prefer this check to be made by the modification timestamp of the files,\ninstead of its checksum (content), just set the ",(0,i.kt)("inlineCode",{parentName:"p"},"method")," property to\n",(0,i.kt)("inlineCode",{parentName:"p"},"timestamp"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n cmds:\n - go build .\n sources:\n - ./*.go\n generates:\n - app{{exeExt}}\n method: timestamp\n")),(0,i.kt)("p",null,"In situations where you need more flexibility the ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," keyword can be used.\nYou can even combine the two. See the documentation for\n",(0,i.kt)("a",{parentName:"p",href:"#using-programmatic-checks-to-indicate-a-task-is-up-to-date"},"status")," for an\nexample."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"By default, task stores checksums on a local ",(0,i.kt)("inlineCode",{parentName:"p"},".task")," directory in the project's\ndirectory. Most of the time, you'll want to have this directory on ",(0,i.kt)("inlineCode",{parentName:"p"},".gitignore"),"\n(or equivalent) so it isn't committed. (If you have a task for code generation\nthat is committed it may make sense to commit the checksum of that task as well,\nthough)."),(0,i.kt)("p",{parentName:"admonition"},"If you want these files to be stored in another directory, you can set a\n",(0,i.kt)("inlineCode",{parentName:"p"},"TASK_TEMP_DIR")," environment variable in your machine. It can contain a relative\npath like ",(0,i.kt)("inlineCode",{parentName:"p"},"tmp/task")," that will be interpreted as relative to the project\ndirectory, or an absolute or home path like ",(0,i.kt)("inlineCode",{parentName:"p"},"/tmp/.task")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"~/.task"),"\n(subdirectories will be created for each project)."),(0,i.kt)("pre",{parentName:"admonition"},(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"export TASK_TEMP_DIR='~/.task'\n"))),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Each task has only one checksum stored for its ",(0,i.kt)("inlineCode",{parentName:"p"},"sources"),". If you want to\ndistinguish a task by any of its input variables, you can add those variables as\npart of the task's label, and it will be considered a different task."),(0,i.kt)("p",{parentName:"admonition"},"This is useful if you want to run a task once for each distinct set of inputs\nuntil the sources actually change. For example, if the sources depend on the\nvalue of a variable, or you if you want the task to rerun if some arguments\nchange even if the source has not.")),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"The method ",(0,i.kt)("inlineCode",{parentName:"p"},"none")," skips any validation and always run the task.")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"For the ",(0,i.kt)("inlineCode",{parentName:"p"},"checksum")," (default) or ",(0,i.kt)("inlineCode",{parentName:"p"},"timestamp")," method to work, it is only necessary\nto inform the source files. When the ",(0,i.kt)("inlineCode",{parentName:"p"},"timestamp")," method is used, the last time\nof the running the task is considered as a generate.")),(0,i.kt)("h3",{id:"using-programmatic-checks-to-indicate-a-task-is-up-to-date"},"Using programmatic checks to indicate a task is up to date"),(0,i.kt)("p",null,"Alternatively, you can inform a sequence of tests as ",(0,i.kt)("inlineCode",{parentName:"p"},"status"),". If no error is\nreturned (exit status 0), the task is considered up-to-date:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n generate-files:\n cmds:\n - mkdir directory\n - touch directory/file1.txt\n - touch directory/file2.txt\n # test existence of files\n status:\n - test -d directory\n - test -f directory/file1.txt\n - test -f directory/file2.txt\n")),(0,i.kt)("p",null,"Normally, you would use ",(0,i.kt)("inlineCode",{parentName:"p"},"sources")," in combination with ",(0,i.kt)("inlineCode",{parentName:"p"},"generates")," - but for\ntasks that generate remote artifacts (Docker images, deploys, CD releases) the\nchecksum source and timestamps require either access to the artifact or for an\nout-of-band refresh of the ",(0,i.kt)("inlineCode",{parentName:"p"},".checksum")," fingerprint file."),(0,i.kt)("p",null,"Two special variables ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.CHECKSUM}}")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.TIMESTAMP}}")," are available for\ninterpolation within ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," commands, depending on the method assigned to\nfingerprint the sources. Only ",(0,i.kt)("inlineCode",{parentName:"p"},"source")," globs are fingerprinted."),(0,i.kt)("p",null,"Note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.TIMESTAMP}}"),' variable is a "live" Go ',(0,i.kt)("inlineCode",{parentName:"p"},"time.Time")," struct, and\ncan be formatted using any of the methods that ",(0,i.kt)("inlineCode",{parentName:"p"},"time.Time")," responds to."),(0,i.kt)("p",null,"See ",(0,i.kt)("a",{parentName:"p",href:"https://golang.org/pkg/time/"},"the Go Time documentation")," for more\ninformation."),(0,i.kt)("p",null,"You can use ",(0,i.kt)("inlineCode",{parentName:"p"},"--force")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"-f")," if you want to force a task to run even when\nup-to-date."),(0,i.kt)("p",null,"Also, ",(0,i.kt)("inlineCode",{parentName:"p"},"task --status [tasks]...")," will exit with a non-zero exit code if any of\nthe tasks are not up-to-date."),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"status")," can be combined with the\n",(0,i.kt)("a",{parentName:"p",href:"#by-fingerprinting-locally-generated-files-and-their-sources"},"fingerprinting"),"\nto have a task run if either the the source/generated artifacts changes, or the\nprogrammatic check fails:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:prod:\n desc: Build for production usage.\n cmds:\n - composer install\n # Run this task if source files changes.\n sources:\n - composer.json\n - composer.lock\n generates:\n - ./vendor/composer/installed.json\n - ./vendor/autoload.php\n # But also run the task if the last build was not a production build.\n status:\n - grep -q '\"dev\": false' ./vendor/composer/installed.json\n")),(0,i.kt)("h3",{id:"using-programmatic-checks-to-cancel-the-execution-of-a-task-and-its-dependencies"},"Using programmatic checks to cancel the execution of a task and its dependencies"),(0,i.kt)("p",null,"In addition to ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," checks, ",(0,i.kt)("inlineCode",{parentName:"p"},"preconditions")," checks are the logical inverse\nof ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," checks. That is, if you need a certain set of conditions to be\n",(0,i.kt)("em",{parentName:"p"},"true")," you can use the ",(0,i.kt)("inlineCode",{parentName:"p"},"preconditions")," stanza. ",(0,i.kt)("inlineCode",{parentName:"p"},"preconditions")," are similar to\n",(0,i.kt)("inlineCode",{parentName:"p"},"status")," lines, except they support ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," expansion, and they SHOULD all\nreturn 0."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n generate-files:\n cmds:\n - mkdir directory\n - touch directory/file1.txt\n - touch directory/file2.txt\n # test existence of files\n preconditions:\n - test -f .env\n - sh: '[ 1 = 0 ]'\n msg: \"One doesn't equal Zero, Halting\"\n")),(0,i.kt)("p",null,"Preconditions can set specific failure messages that can tell a user what steps\nto take using the ",(0,i.kt)("inlineCode",{parentName:"p"},"msg")," field."),(0,i.kt)("p",null,"If a task has a dependency on a sub-task with a precondition, and that\nprecondition is not met - the calling task will fail. Note that a task executed\nwith a failing precondition will not run unless ",(0,i.kt)("inlineCode",{parentName:"p"},"--force")," is given."),(0,i.kt)("p",null,"Unlike ",(0,i.kt)("inlineCode",{parentName:"p"},"status"),", which will skip a task if it is up to date and continue\nexecuting tasks that depend on it, a ",(0,i.kt)("inlineCode",{parentName:"p"},"precondition")," will fail a task, along with\nany other tasks that depend on it."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n task-will-fail:\n preconditions:\n - sh: 'exit 1'\n\n task-will-also-fail:\n deps:\n - task-will-fail\n\n task-will-still-fail:\n cmds:\n - task: task-will-fail\n - echo \"I will not run\"\n")),(0,i.kt)("h3",{id:"limiting-when-tasks-run"},"Limiting when tasks run"),(0,i.kt)("p",null,"If a task executed by multiple ",(0,i.kt)("inlineCode",{parentName:"p"},"cmds")," or multiple ",(0,i.kt)("inlineCode",{parentName:"p"},"deps")," you can control when it\nis executed using ",(0,i.kt)("inlineCode",{parentName:"p"},"run"),". ",(0,i.kt)("inlineCode",{parentName:"p"},"run")," can also be set at the root of the Taskfile to\nchange the behavior of all the tasks unless explicitly overridden."),(0,i.kt)("p",null,"Supported values for ",(0,i.kt)("inlineCode",{parentName:"p"},"run"),":"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"always")," (default) always attempt to invoke the task regardless of the number\nof previous executions"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"once")," only invoke this task once regardless of the number of references"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"when_changed")," only invokes the task once for each unique set of variables\npassed into the task")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n cmds:\n - task: generate-file\n vars: { CONTENT: '1' }\n - task: generate-file\n vars: { CONTENT: '2' }\n - task: generate-file\n vars: { CONTENT: '2' }\n\n generate-file:\n run: when_changed\n deps:\n - install-deps\n cmds:\n - echo {{.CONTENT}}\n\n install-deps:\n run: once\n cmds:\n - sleep 5 # long operation like installing packages\n")),(0,i.kt)("h2",{id:"variables"},"Variables"),(0,i.kt)("p",null,"When doing interpolation of variables, Task will look for the below. They are\nlisted below in order of importance (i.e. most important first):"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Variables declared in the task definition"),(0,i.kt)("li",{parentName:"ul"},"Variables given while calling a task from another (See\n",(0,i.kt)("a",{parentName:"li",href:"#calling-another-task"},"Calling another task")," above)"),(0,i.kt)("li",{parentName:"ul"},"Variables of the ",(0,i.kt)("a",{parentName:"li",href:"#including-other-taskfiles"},"included Taskfile")," (when the\ntask is included)"),(0,i.kt)("li",{parentName:"ul"},"Variables of the ",(0,i.kt)("a",{parentName:"li",href:"#vars-of-included-taskfiles"},"inclusion of the Taskfile"),"\n(when the task is included)"),(0,i.kt)("li",{parentName:"ul"},"Global variables (those declared in the ",(0,i.kt)("inlineCode",{parentName:"li"},"vars:")," option in the Taskfile)"),(0,i.kt)("li",{parentName:"ul"},"Environment variables")),(0,i.kt)("p",null,"Example of sending parameters with environment variables:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ TASK_VARIABLE=a-value task do-something\n")),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"A special variable ",(0,i.kt)("inlineCode",{parentName:"p"},".TASK")," is always available containing the task name.")),(0,i.kt)("p",null,"Since some shells do not support the above syntax to set environment variables\n(Windows) tasks also accept a similar style when not at the beginning of the\ncommand."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'$ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!"\n')),(0,i.kt)("p",null,"Example of locally declared vars:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print-var:\n cmds:\n - echo \"{{.VAR}}\"\n vars:\n VAR: Hello!\n")),(0,i.kt)("p",null,"Example of global vars in a ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nvars:\n GREETING: Hello from Taskfile!\n\ntasks:\n greet:\n cmds:\n - echo \"{{.GREETING}}\"\n")),(0,i.kt)("h3",{id:"dynamic-variables"},"Dynamic variables"),(0,i.kt)("p",null,"The below syntax (",(0,i.kt)("inlineCode",{parentName:"p"},"sh:")," prop in a variable) is considered a dynamic variable.\nThe value will be treated as a command and the output assigned. If there are one\nor more trailing newlines, the last newline will be trimmed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n cmds:\n - go build -ldflags=\"-X main.Version={{.GIT_COMMIT}}\" main.go\n vars:\n GIT_COMMIT:\n sh: git log -n 1 --format=%h\n")),(0,i.kt)("p",null,"This works for all types of variables."),(0,i.kt)("h2",{id:"forwarding-cli-arguments-to-commands"},"Forwarding CLI arguments to commands"),(0,i.kt)("p",null,"If ",(0,i.kt)("inlineCode",{parentName:"p"},"--")," is given in the CLI, all following parameters are added to a special\n",(0,i.kt)("inlineCode",{parentName:"p"},".CLI_ARGS")," variable. This is useful to forward arguments to another command."),(0,i.kt)("p",null,"The below example will run ",(0,i.kt)("inlineCode",{parentName:"p"},"yarn install"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ task yarn -- install\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n yarn:\n cmds:\n - yarn {{.CLI_ARGS}}\n")),(0,i.kt)("h2",{id:"doing-task-cleanup-with-defer"},"Doing task cleanup with ",(0,i.kt)("inlineCode",{parentName:"h2"},"defer")),(0,i.kt)("p",null,"With the ",(0,i.kt)("inlineCode",{parentName:"p"},"defer")," keyword, it's possible to schedule cleanup to be run once the\ntask finishes. The difference with just putting it as the last command is that\nthis command will run even when the task fails."),(0,i.kt)("p",null,"In the example below, ",(0,i.kt)("inlineCode",{parentName:"p"},"rm -rf tmpdir/")," will run even if the third command fails:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n cmds:\n - mkdir -p tmpdir/\n - defer: rm -rf tmpdir/\n - echo 'Do work on tmpdir/'\n")),(0,i.kt)("p",null,"If you want to move the cleanup command into another task, that is possible as\nwell:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n cmds:\n - mkdir -p tmpdir/\n - defer: { task: cleanup }\n - echo 'Do work on tmpdir/'\n\n cleanup: rm -rf tmpdir/\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Due to the nature of how the\n",(0,i.kt)("a",{parentName:"p",href:"https://go.dev/tour/flowcontrol/13"},"Go's own ",(0,i.kt)("inlineCode",{parentName:"a"},"defer")," work"),", the deferred\ncommands are executed in the reverse order if you schedule multiple of them.")),(0,i.kt)("h2",{id:"gos-template-engine"},"Go's template engine"),(0,i.kt)("p",null,"Task parse commands as ",(0,i.kt)("a",{parentName:"p",href:"https://golang.org/pkg/text/template/"},"Go's template engine")," before executing them.\nVariables are accessible through dot syntax (",(0,i.kt)("inlineCode",{parentName:"p"},".VARNAME"),")."),(0,i.kt)("p",null,"All functions by the Go's\n",(0,i.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/"},"slim-sprig lib")," are available. The\nfollowing example gets the current date in a given format:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print-date:\n cmds:\n - echo {{now | date \"2006-01-02\"}}\n")),(0,i.kt)("p",null,"Task also adds the following functions:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"OS"),': Returns the operating system. Possible values are "windows", "linux",\n"darwin" (macOS) and "freebsd".'),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"ARCH"),': return the architecture Task was compiled to: "386", "amd64", "arm" or\n"s390x".'),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"splitLines"),": Splits Unix (\\n) and Windows (\\r\\n) styled newlines."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"catLines"),": Replaces Unix (\\n) and Windows (\\r\\n) styled newlines with a\nspace."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"toSlash"),": Does nothing on Unix, but on Windows converts a string from ",(0,i.kt)("inlineCode",{parentName:"li"},"\\"),"\npath format to ",(0,i.kt)("inlineCode",{parentName:"li"},"/"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"fromSlash"),": Opposite of ",(0,i.kt)("inlineCode",{parentName:"li"},"toSlash"),". Does nothing on Unix, but on Windows\nconverts a string from ",(0,i.kt)("inlineCode",{parentName:"li"},"/")," path format to ",(0,i.kt)("inlineCode",{parentName:"li"},"\\"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"exeExt"),": Returns the right executable extension for the current OS (",(0,i.kt)("inlineCode",{parentName:"li"},'".exe"'),"\nfor Windows, ",(0,i.kt)("inlineCode",{parentName:"li"},'""')," for others)."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"shellQuote"),": Quotes a string to make it safe for use in shell scripts. Task\nuses ",(0,i.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote"},"this Go function"),"\nfor this. The Bash dialect is assumed."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"splitArgs"),": Splits a string as if it were a command's arguments. Task uses\n",(0,i.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/shell#Fields"},"this Go function"))),(0,i.kt)("p",null,"Example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print-os:\n cmds:\n - echo '{{OS}} {{ARCH}}'\n - echo '{{if eq OS \"windows\"}}windows-command{{else}}unix-command{{end}}'\n # This will be path/to/file on Unix but path\\to\\file on Windows\n - echo '{{fromSlash \"path/to/file\"}}'\n enumerated-file:\n vars:\n CONTENT: |\n foo\n bar\n cmds:\n - |\n cat << EOF > output.txt\n {{range $i, $line := .CONTENT | splitLines -}}\n {{printf \"%3d\" $i}}: {{$line}}\n {{end}}EOF\n")),(0,i.kt)("h2",{id:"help"},"Help"),(0,i.kt)("p",null,"Running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --list")," (or ",(0,i.kt)("inlineCode",{parentName:"p"},"task -l"),") lists all tasks with a description. The\nfollowing Taskfile:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n desc: Build the go binary.\n cmds:\n - go build -v -i main.go\n\n test:\n desc: Run all the go tests.\n cmds:\n - go test -race ./...\n\n js:\n cmds:\n - esbuild --bundle --minify js/index.js > public/bundle.js\n\n css:\n cmds:\n - esbuild --bundle --minify css/index.css > public/bundle.css\n")),(0,i.kt)("p",null,"would print the following output:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"* build: Build the go binary.\n* test: Run all the go tests.\n")),(0,i.kt)("p",null,"If you want to see all tasks, there's a ",(0,i.kt)("inlineCode",{parentName:"p"},"--list-all")," (alias ",(0,i.kt)("inlineCode",{parentName:"p"},"-a"),") flag as well."),(0,i.kt)("h2",{id:"display-summary-of-task"},"Display summary of task"),(0,i.kt)("p",null,"Running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --summary task-name")," will show a summary of a task. The following\nTaskfile:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n release:\n deps: [build]\n summary: |\n Release your project to github\n\n It will build your project before starting the release.\n Please make sure that you have set GITHUB_TOKEN before starting.\n cmds:\n - your-release-tool\n\n build:\n cmds:\n - your-build-tool\n")),(0,i.kt)("p",null,"with running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --summary release")," would print the following output:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"task: release\n\nRelease your project to github\n\nIt will build your project before starting the release.\nPlease make sure that you have set GITHUB_TOKEN before starting.\n\ndependencies:\n - build\n\ncommands:\n - your-release-tool\n")),(0,i.kt)("p",null,"If a summary is missing, the description will be printed. If the task does not\nhave a summary or a description, a warning is printed."),(0,i.kt)("p",null,"Please note: ",(0,i.kt)("em",{parentName:"p"},"showing the summary will not execute the command"),"."),(0,i.kt)("h2",{id:"task-aliases"},"Task aliases"),(0,i.kt)("p",null,"Aliases are alternative names for tasks. They can be used to make it easier and\nquicker to run tasks with long or hard-to-type names. You can use them on the\ncommand line, when ",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"calling sub-tasks")," in your Taskfile\nand when ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"including tasks")," with aliases from another\nTaskfile. They can also be used together with\n",(0,i.kt)("a",{parentName:"p",href:"#namespace-aliases"},"namespace aliases"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n generate:\n aliases: [gen]\n cmds:\n - task: gen-mocks\n\n generate-mocks:\n aliases: [gen-mocks]\n cmds:\n - echo \"generating...\"\n")),(0,i.kt)("h2",{id:"overriding-task-name"},"Overriding task name"),(0,i.kt)("p",null,"Sometimes you may want to override the task name printed on the summary,\nup-to-date messages to STDOUT, etc. In this case, you can just set ",(0,i.kt)("inlineCode",{parentName:"p"},"label:"),",\nwhich can also be interpolated with variables:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n - task: print\n vars:\n MESSAGE: hello\n - task: print\n vars:\n MESSAGE: world\n\n print:\n label: 'print-{{.MESSAGE}}'\n cmds:\n - echo \"{{.MESSAGE}}\"\n")),(0,i.kt)("h2",{id:"silent-mode"},"Silent mode"),(0,i.kt)("p",null,"Silent mode disables the echoing of commands before Task runs it. For the\nfollowing Taskfile:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n")),(0,i.kt)("p",null,"Normally this will be printed:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},'echo "Print something"\nPrint something\n')),(0,i.kt)("p",null,"With silent mode on, the below will be printed instead:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"Print something\n")),(0,i.kt)("p",null,"There are four ways to enable silent mode:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"At command level:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - cmd: echo \"Print something\"\n silent: true\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"At task level:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n silent: true\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Globally at Taskfile level:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nsilent: true\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Or globally with ",(0,i.kt)("inlineCode",{parentName:"li"},"--silent")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"-s")," flag")),(0,i.kt)("p",null,"If you want to suppress STDOUT instead, just redirect a command to ",(0,i.kt)("inlineCode",{parentName:"p"},"/dev/null"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - echo \"This will print nothing\" > /dev/null\n")),(0,i.kt)("h2",{id:"dry-run-mode"},"Dry run mode"),(0,i.kt)("p",null,"Dry run mode (",(0,i.kt)("inlineCode",{parentName:"p"},"--dry"),") compiles and steps through each task, printing the\ncommands that would be run without executing them. This is useful for debugging\nyour Taskfiles."),(0,i.kt)("h2",{id:"ignore-errors"},"Ignore errors"),(0,i.kt)("p",null,"You have the option to ignore errors during command execution. Given the\nfollowing Taskfile:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - exit 1\n - echo \"Hello World\"\n")),(0,i.kt)("p",null,"Task will abort the execution after running ",(0,i.kt)("inlineCode",{parentName:"p"},"exit 1")," because the status code ",(0,i.kt)("inlineCode",{parentName:"p"},"1"),"\nstands for ",(0,i.kt)("inlineCode",{parentName:"p"},"EXIT_FAILURE"),". However, it is possible to continue with execution\nusing ",(0,i.kt)("inlineCode",{parentName:"p"},"ignore_error"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - cmd: exit 1\n ignore_error: true\n - echo \"Hello World\"\n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"ignore_error")," can also be set for a task, which means errors will be suppressed\nfor all commands. Nevertheless, keep in mind that this option will not propagate\nto other tasks called either by ",(0,i.kt)("inlineCode",{parentName:"p"},"deps")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"cmds"),"!"),(0,i.kt)("h2",{id:"output-syntax"},"Output syntax"),(0,i.kt)("p",null,"By default, Task just redirects the STDOUT and STDERR of the running commands to\nthe shell in real-time. This is good for having live feedback for logging\nprinted by commands, but the output can become messy if you have multiple\ncommands running simultaneously and printing lots of stuff."),(0,i.kt)("p",null,"To make this more customizable, there are currently three different output\noptions you can choose:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"interleaved")," (default)"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"group")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"prefixed"))),(0,i.kt)("p",null,"To choose another one, just set it to root in the Taskfile:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\noutput: 'group'\n\ntasks:\n # ...\n")),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"group")," output will print the entire output of a command once after it\nfinishes, so you will not have live feedback for commands that take a long time\nto run."),(0,i.kt)("p",null,"When using the ",(0,i.kt)("inlineCode",{parentName:"p"},"group")," output, you can optionally provide a templated message to\nprint at the start and end of the group. This can be useful for instructing CI\nsystems to group all of the output for a given task, such as with\n",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#grouping-log-lines"},"GitHub Actions' ",(0,i.kt)("inlineCode",{parentName:"a"},"::group::")," command"),"\nor\n",(0,i.kt)("a",{parentName:"p",href:"https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?expand=1&view=azure-devops&tabs=bash#formatting-commands"},"Azure Pipelines"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\noutput:\n group:\n begin: '::group::{{.TASK}}'\n end: '::endgroup::'\n\ntasks:\n default:\n cmds:\n - echo 'Hello, World!'\n silent: true\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ task default\n::group::default\nHello, World!\n::endgroup::\n")),(0,i.kt)("p",null,"When using the ",(0,i.kt)("inlineCode",{parentName:"p"},"group")," output, you may swallow the output of the executed\ncommand on standard output and standard error if it does not fail (zero exit\ncode)."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nsilent: true\n\noutput:\n group:\n error_only: true\n\ntasks:\n passes: echo 'output-of-passes'\n errors: echo 'output-of-errors' && exit 1\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'$ task passes\n$ task errors\noutput-of-errors\ntask: Failed to run task "errors": exit status 1\n')),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"prefix")," output will prefix every line printed by a command with\n",(0,i.kt)("inlineCode",{parentName:"p"},"[task-name] ")," as the prefix, but you can customize the prefix for a command\nwith the ",(0,i.kt)("inlineCode",{parentName:"p"},"prefix:")," attribute:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\noutput: prefixed\n\ntasks:\n default:\n deps:\n - task: print\n vars: { TEXT: foo }\n - task: print\n vars: { TEXT: bar }\n - task: print\n vars: { TEXT: baz }\n\n print:\n cmds:\n - echo \"{{.TEXT}}\"\n prefix: 'print-{{.TEXT}}'\n silent: true\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ task default\n[print-foo] foo\n[print-bar] bar\n[print-baz] baz\n")),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"The ",(0,i.kt)("inlineCode",{parentName:"p"},"output")," option can also be specified by the ",(0,i.kt)("inlineCode",{parentName:"p"},"--output")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"-o")," flags.")),(0,i.kt)("h2",{id:"interactive-cli-application"},"Interactive CLI application"),(0,i.kt)("p",null,"When running interactive CLI applications inside Task they can sometimes behave\nweirdly, especially when the ",(0,i.kt)("a",{parentName:"p",href:"#output-syntax"},"output mode")," is set to something\nother than ",(0,i.kt)("inlineCode",{parentName:"p"},"interleaved")," (the default), or when interactive apps are run in\nparallel with other tasks."),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"interactive: true")," tells Task this is an interactive application and Task\nwill try to optimize for it:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n cmds:\n - vim my-file.txt\n interactive: true\n")),(0,i.kt)("p",null,"If you still have problems running an interactive app through Task, please open\nan issue about it."),(0,i.kt)("h2",{id:"short-task-syntax"},"Short task syntax"),(0,i.kt)("p",null,"Starting on Task v3, you can now write tasks with a shorter syntax if they have\nthe default settings (e.g. no custom ",(0,i.kt)("inlineCode",{parentName:"p"},"env:"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"vars:"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"desc:"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"silent:")," , etc):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build: go build -v -o ./app{{exeExt}} .\n\n run:\n - task: build\n - ./app{{exeExt}} -h localhost -p 8080\n")),(0,i.kt)("h2",{id:"set-and-shopt"},(0,i.kt)("inlineCode",{parentName:"h2"},"set")," and ",(0,i.kt)("inlineCode",{parentName:"h2"},"shopt")),(0,i.kt)("p",null,"It's possible to specify options to the\n",(0,i.kt)("a",{parentName:"p",href:"https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html"},(0,i.kt)("inlineCode",{parentName:"a"},"set")),"\nand\n",(0,i.kt)("a",{parentName:"p",href:"https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html"},(0,i.kt)("inlineCode",{parentName:"a"},"shopt")),"\nbuiltins. This can be added at global, task or command level."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nset: [pipefail]\nshopt: [globstar]\n\ntasks:\n # `globstar` required for double star globs to work\n default: echo **/*.go\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Keep in mind that not all options are available in the\n",(0,i.kt)("a",{parentName:"p",href:"https://github.com/mvdan/sh"},"shell interpreter library")," that Task uses.")),(0,i.kt)("h2",{id:"watch-tasks"},"Watch tasks"),(0,i.kt)("p",null,"With the flags ",(0,i.kt)("inlineCode",{parentName:"p"},"--watch")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"-w")," task will watch for file changes and run the\ntask again. This requires the ",(0,i.kt)("inlineCode",{parentName:"p"},"sources")," attribute to be given, so task knows\nwhich files to watch."),(0,i.kt)("p",null,"The default watch interval is 5 seconds, but it's possible to change it by\neither setting ",(0,i.kt)("inlineCode",{parentName:"p"},"interval: '500ms'")," in the root of the Taskfile passing it as an\nargument like ",(0,i.kt)("inlineCode",{parentName:"p"},"--interval=500ms"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6476eba6.f5165ba7.js b/assets/js/6476eba6.f5165ba7.js deleted file mode 100644 index 5b067093..00000000 --- a/assets/js/6476eba6.f5165ba7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[827],{3905:function(e,n,t){t.d(n,{Zo:function(){return d},kt:function(){return k}});var a=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function l(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function s(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var r=a.createContext({}),p=function(e){var n=a.useContext(r),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},d=function(e){var n=p(e.components);return a.createElement(r.Provider,{value:n},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},c=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,l=e.originalType,r=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),u=p(t),c=i,k=u["".concat(r,".").concat(c)]||u[c]||m[c]||l;return t?a.createElement(k,s(s({ref:n},d),{},{components:t})):a.createElement(k,s({ref:n},d))}));function k(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var l=t.length,s=new Array(l);s[0]=c;var o={};for(var r in n)hasOwnProperty.call(n,r)&&(o[r]=n[r]);o.originalType=e,o[u]="string"==typeof e?e:i,s[1]=o;for(var p=2;pdefer",id:"doing-task-cleanup-with-defer",level:2},{value:"Go's template engine",id:"gos-template-engine",level:2},{value:"Help",id:"help",level:2},{value:"Display summary of task",id:"display-summary-of-task",level:2},{value:"Task aliases",id:"task-aliases",level:2},{value:"Overriding task name",id:"overriding-task-name",level:2},{value:"Silent mode",id:"silent-mode",level:2},{value:"Dry run mode",id:"dry-run-mode",level:2},{value:"Ignore errors",id:"ignore-errors",level:2},{value:"Output syntax",id:"output-syntax",level:2},{value:"Interactive CLI application",id:"interactive-cli-application",level:2},{value:"Short task syntax",id:"short-task-syntax",level:2},{value:"set and shopt",id:"set-and-shopt",level:2},{value:"Watch tasks",id:"watch-tasks",level:2}],d={toc:p};function u(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,a.Z)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"usage"},"Usage"),(0,i.kt)("h2",{id:"getting-started"},"Getting started"),(0,i.kt)("p",null,"Create a file called ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," in the root of your project.\nThe ",(0,i.kt)("inlineCode",{parentName:"p"},"cmds")," attribute should contain the commands of a task.\nThe example below allows compiling a Go app and uses ",(0,i.kt)("a",{parentName:"p",href:"https://esbuild.github.io/"},"esbuild")," to concat\nand minify multiple CSS files into a single one."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n cmds:\n - go build -v -i main.go\n\n assets:\n cmds:\n - esbuild --bundle --minify css/index.css > public/bundle.css\n")),(0,i.kt)("p",null,"Running the tasks is as simple as running:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"task assets build\n")),(0,i.kt)("p",null,"Task uses ",(0,i.kt)("a",{parentName:"p",href:"https://mvdan.cc/sh/"},"mvdan.cc/sh"),", a native Go sh\ninterpreter. So you can write sh/bash commands, and it will work even on\nWindows, where ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"bash")," are usually not available. Just remember any\nexecutable called must be available by the OS or in PATH."),(0,i.kt)("p",null,'If you omit a task name, "default" will be assumed.'),(0,i.kt)("h2",{id:"supported-file-names"},"Supported file names"),(0,i.kt)("p",null,"Task will look for the following file names, in order of priority:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Taskfile.yml"),(0,i.kt)("li",{parentName:"ul"},"Taskfile.yaml"),(0,i.kt)("li",{parentName:"ul"},"Taskfile.dist.yml"),(0,i.kt)("li",{parentName:"ul"},"Taskfile.dist.yaml")),(0,i.kt)("p",null,"The intention of having the ",(0,i.kt)("inlineCode",{parentName:"p"},".dist")," variants is to allow projects to have one\ncommitted version (",(0,i.kt)("inlineCode",{parentName:"p"},".dist"),") while still allowing individual users to override\nthe Taskfile by adding an additional ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," (which would be on\n",(0,i.kt)("inlineCode",{parentName:"p"},".gitignore"),")."),(0,i.kt)("h3",{id:"running-a-taskfile-from-a-subdirectory"},"Running a Taskfile from a subdirectory"),(0,i.kt)("p",null,"If a Taskfile cannot be found in the current working directory, it will walk up\nthe file tree until it finds one (similar to how ",(0,i.kt)("inlineCode",{parentName:"p"},"git")," works). When running Task\nfrom a subdirectory like this, it will behave as if you ran it from the\ndirectory containing the Taskfile."),(0,i.kt)("p",null,"You can use this functionality along with the special ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}"),"\nvariable to create some very useful reusable tasks. For example, if you have a\nmonorepo with directories for each microservice, you can ",(0,i.kt)("inlineCode",{parentName:"p"},"cd")," into a\nmicroservice directory and run a task command to bring it up without having to\ncreate multiple tasks or Taskfiles with identical content. For example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n up:\n dir: '{{.USER_WORKING_DIR}}'\n preconditions:\n - test -f docker-compose.yml\n cmds:\n - docker-compose up -d\n")),(0,i.kt)("p",null,"In this example, we can run ",(0,i.kt)("inlineCode",{parentName:"p"},"cd ")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"task up")," and as long as the\n",(0,i.kt)("inlineCode",{parentName:"p"},"")," directory contains a ",(0,i.kt)("inlineCode",{parentName:"p"},"docker-compose.yml"),", the Docker composition will be\nbrought up."),(0,i.kt)("h3",{id:"running-a-global-taskfile"},"Running a global Taskfile"),(0,i.kt)("p",null,"If you call Task with the ",(0,i.kt)("inlineCode",{parentName:"p"},"--global")," (alias ",(0,i.kt)("inlineCode",{parentName:"p"},"-g"),") flag, it will look for your\nhome directory instead of your working directory. In short, Task will look for\na Taskfile on either ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yml")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yaml")," paths."),(0,i.kt)("p",null,"This is useful to have automation that you can run from anywhere in your\nsystem!"),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"When running your global Taskfile with ",(0,i.kt)("inlineCode",{parentName:"p"},"-g"),", tasks will run on ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME")," by\ndefault, and not on your working directory!"),(0,i.kt)("p",{parentName:"admonition"},"As mentioned in the previous section, the ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}")," special\nvariable can be very handy here to run stuff on the directory you're calling\n",(0,i.kt)("inlineCode",{parentName:"p"},"task -g")," from."),(0,i.kt)("pre",{parentName:"admonition"},(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n from-home:\n cmds:\n - pwd\n\n from-working-directory:\n dir: '{{.USER_WORKING_DIR}}'\n cmds:\n - pwd\n"))),(0,i.kt)("h2",{id:"environment-variables"},"Environment variables"),(0,i.kt)("h3",{id:"task"},"Task"),(0,i.kt)("p",null,"You can use ",(0,i.kt)("inlineCode",{parentName:"p"},"env")," to set custom environment variables for a specific task:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n greet:\n cmds:\n - echo $GREETING\n env:\n GREETING: Hey, there!\n")),(0,i.kt)("p",null,"Additionally, you can set global environment variables that will be available\nto all tasks:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nenv:\n GREETING: Hey, there!\n\ntasks:\n greet:\n cmds:\n - echo $GREETING\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},(0,i.kt)("inlineCode",{parentName:"p"},"env")," supports expansion and retrieving output from a shell command\njust like variables, as you can see in the ",(0,i.kt)("a",{parentName:"p",href:"#variables"},"Variables")," section.")),(0,i.kt)("h3",{id:"env-files"},".env files"),(0,i.kt)("p",null,"You can also ask Task to include ",(0,i.kt)("inlineCode",{parentName:"p"},".env")," like files by using the ",(0,i.kt)("inlineCode",{parentName:"p"},"dotenv:"),"\nsetting:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title=".env"',title:'".env"'},"KEYNAME=VALUE\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title="testing/.env"',title:'"testing/.env"'},"ENDPOINT=testing.com\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml",metastring:'title="Taskfile.yml"',title:'"Taskfile.yml"'},"version: '3'\n\nenv:\n ENV: testing\n\ndotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']\n\ntasks:\n greet:\n cmds:\n - echo \"Using $KEYNAME and endpoint $ENDPOINT\"\n")),(0,i.kt)("p",null,"Dotenv files can also be specified at the task level:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nenv:\n ENV: testing\n\ntasks:\n greet:\n dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']\n cmds:\n - echo \"Using $KEYNAME and endpoint $ENDPOINT\"\n")),(0,i.kt)("p",null,"Environment variables specified explicitly at the task-level will override\nvariables defined in dotfiles:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nenv:\n ENV: testing\n\ntasks:\n greet:\n dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']\n env:\n KEYNAME: DIFFERENT_VALUE\n cmds:\n - echo \"Using $KEYNAME and endpoint $ENDPOINT\"\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Please note that you are not currently able to use the ",(0,i.kt)("inlineCode",{parentName:"p"},"dotenv")," key inside included Taskfiles.")),(0,i.kt)("h2",{id:"including-other-taskfiles"},"Including other Taskfiles"),(0,i.kt)("p",null,"If you want to share tasks between different projects (Taskfiles), you can use\nthe importing mechanism to include other Taskfiles using the ",(0,i.kt)("inlineCode",{parentName:"p"},"includes")," keyword:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n docs: ./documentation # will look for ./documentation/Taskfile.yml\n docker: ./DockerTasks.yml\n")),(0,i.kt)("p",null,"The tasks described in the given Taskfiles will be available with the informed\nnamespace. So, you'd call ",(0,i.kt)("inlineCode",{parentName:"p"},"task docs:serve")," to run the ",(0,i.kt)("inlineCode",{parentName:"p"},"serve")," task from\n",(0,i.kt)("inlineCode",{parentName:"p"},"documentation/Taskfile.yml")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"task docker:build")," to run the ",(0,i.kt)("inlineCode",{parentName:"p"},"build")," task\nfrom the ",(0,i.kt)("inlineCode",{parentName:"p"},"DockerTasks.yml")," file."),(0,i.kt)("p",null,"Relative paths are resolved relative to the directory containing the including Taskfile."),(0,i.kt)("h3",{id:"os-specific-taskfiles"},"OS-specific Taskfiles"),(0,i.kt)("p",null,"With ",(0,i.kt)("inlineCode",{parentName:"p"},"version: '2'"),", task automatically includes any ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_{{OS}}.yml"),"\nif it exists (for example: ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_windows.yml"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_linux.yml")," or\n",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_darwin.yml"),"). Since this behavior was a bit too implicit, it\nwas removed on version 3, but you still can have a similar behavior by\nexplicitly importing these files:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n build: ./Taskfile_{{OS}}.yml\n")),(0,i.kt)("h3",{id:"directory-of-included-taskfile"},"Directory of included Taskfile"),(0,i.kt)("p",null,"By default, included Taskfile's tasks are run in the current directory, even\nif the Taskfile is in another directory, but you can force its tasks to run\nin another directory by using this alternative syntax:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n docs:\n taskfile: ./docs/Taskfile.yml\n dir: ./docs\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"The included Taskfiles must be using the same schema version as the main\nTaskfile uses.")),(0,i.kt)("h3",{id:"optional-includes"},"Optional includes"),(0,i.kt)("p",null,"Includes marked as optional will allow Task to continue execution as normal if\nthe included file is missing."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n tests:\n taskfile: ./tests/Taskfile.yml\n optional: true\n\ntasks:\n greet:\n cmds:\n - echo \"This command can still be successfully executed if ./tests/Taskfile.yml does not exist\"\n")),(0,i.kt)("h3",{id:"internal-includes"},"Internal includes"),(0,i.kt)("p",null,"Includes marked as internal will set all the tasks of the included file to be\ninternal as well (see the ",(0,i.kt)("a",{parentName:"p",href:"#internal-tasks"},"Internal tasks")," section below).\nThis is useful when including utility tasks that are not intended to be used\ndirectly by the user."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n tests:\n taskfile: ./taskfiles/Utils.yml\n internal: true\n")),(0,i.kt)("h3",{id:"vars-of-included-taskfiles"},"Vars of included Taskfiles"),(0,i.kt)("p",null,"You can also specify variables when including a Taskfile. This may be useful\nfor having reusable Taskfile that can be tweaked or even included more than once:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n backend:\n taskfile: ./taskfiles/Docker.yml\n vars:\n DOCKER_IMAGE: backend_image\n\n frontend:\n taskfile: ./taskfiles/Docker.yml\n vars:\n DOCKER_IMAGE: frontend_image\n")),(0,i.kt)("h3",{id:"namespace-aliases"},"Namespace aliases"),(0,i.kt)("p",null,"When including a Taskfile, you can give the namespace a list of ",(0,i.kt)("inlineCode",{parentName:"p"},"aliases"),".\nThis works in the same way as ",(0,i.kt)("a",{parentName:"p",href:"#task-aliases"},"task aliases")," and can be used\ntogether to create shorter and easier-to-type commands."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n generate:\n taskfile: ./taskfiles/Generate.yml\n aliases: [gen]\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Vars declared in the included Taskfile have preference over the\nvariables in the including Taskfile! If you want a variable in an included Taskfile to be overridable,\nuse the ",(0,i.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/defaults.html"},"default function"),":\n",(0,i.kt)("inlineCode",{parentName:"p"},"MY_VAR: '{{.MY_VAR | default \"my-default-value\"}}'"),".")),(0,i.kt)("h2",{id:"internal-tasks"},"Internal tasks"),(0,i.kt)("p",null,"Internal tasks are tasks that cannot be called directly by the user. They will\nnot appear in the output when running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --list|--list-all"),". Other tasks may\ncall internal tasks in the usual way. This is useful for creating reusable,\nfunction-like tasks that have no useful purpose on the command line."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build-image-1:\n cmds:\n - task: build-image\n vars:\n DOCKER_IMAGE: image-1\n\n build-image:\n internal: true\n cmds:\n - docker build -t {{.DOCKER_IMAGE}} .\n")),(0,i.kt)("h2",{id:"task-directory"},"Task directory"),(0,i.kt)("p",null,"By default, tasks will be executed in the directory where the Taskfile is\nlocated. But you can easily make the task run in another folder, informing\n",(0,i.kt)("inlineCode",{parentName:"p"},"dir"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n serve:\n dir: public/www\n cmds:\n # run http server\n - caddy\n")),(0,i.kt)("p",null,"If the directory does not exist, ",(0,i.kt)("inlineCode",{parentName:"p"},"task")," creates it."),(0,i.kt)("h2",{id:"task-dependencies"},"Task dependencies"),(0,i.kt)("blockquote",null,(0,i.kt)("p",{parentName:"blockquote"},"Dependencies run in parallel, so dependencies of a task should not depend one\nanother. If you want to force tasks to run serially, take a look at the\n",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"Calling Another Task")," section below.")),(0,i.kt)("p",null,"You may have tasks that depend on others. Just pointing them on ",(0,i.kt)("inlineCode",{parentName:"p"},"deps")," will\nmake them run automatically before running the parent task:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n deps: [assets]\n cmds:\n - go build -v -i main.go\n\n assets:\n cmds:\n - esbuild --bundle --minify css/index.css > public/bundle.css\n")),(0,i.kt)("p",null,"In the above example, ",(0,i.kt)("inlineCode",{parentName:"p"},"assets")," will always run right before ",(0,i.kt)("inlineCode",{parentName:"p"},"build")," if you run\n",(0,i.kt)("inlineCode",{parentName:"p"},"task build"),"."),(0,i.kt)("p",null,"A task can have only dependencies and no commands to group tasks together:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n assets:\n deps: [js, css]\n\n js:\n cmds:\n - esbuild --bundle --minify js/index.js > public/bundle.js\n\n css:\n cmds:\n - esbuild --bundle --minify css/index.css > public/bundle.css\n")),(0,i.kt)("p",null,"If there is more than one dependency, they always run in parallel for better\nperformance."),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"You can also make the tasks given by the command line run in parallel by\nusing the ",(0,i.kt)("inlineCode",{parentName:"p"},"--parallel")," flag (alias ",(0,i.kt)("inlineCode",{parentName:"p"},"-p"),"). Example: ",(0,i.kt)("inlineCode",{parentName:"p"},"task --parallel js css"),".")),(0,i.kt)("p",null,"If you want to pass information to dependencies, you can do that the same\nmanner as you would to ",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"call another task"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'version: \'3\'\n\ntasks:\n default:\n deps:\n - task: echo_sth\n vars: {TEXT: "before 1"}\n - task: echo_sth\n vars: {TEXT: "before 2"}\n cmds:\n - echo "after"\n\n echo_sth:\n cmds:\n - echo {{.TEXT}}\n')),(0,i.kt)("h2",{id:"platform-specific-tasks-and-commands"},"Platform specific tasks and commands"),(0,i.kt)("p",null,"If you want to restrict the running of tasks to explicit platforms, this can be achieved\nusing the ",(0,i.kt)("inlineCode",{parentName:"p"},"platforms:")," key. Tasks can be restricted to a specific OS, architecture or a\ncombination of both.\nOn a mismatch, the task or command will be skipped, and no error will be thrown."),(0,i.kt)("p",null,"The values allowed as OS or Arch are valid ",(0,i.kt)("inlineCode",{parentName:"p"},"GOOS")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"GOARCH")," values, as\ndefined by the Go language\n",(0,i.kt)("a",{parentName:"p",href:"https://github.com/golang/go/blob/master/src/go/build/syslist.go"},"here"),"."),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"build-windows")," task below will run only on Windows, and on any architecture:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build-windows:\n platforms: [windows]\n cmds:\n - echo 'Running command on Windows'\n")),(0,i.kt)("p",null,"This can be restricted to a specific architecture as follows:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build-windows-amd64:\n platforms: [windows/amd64]\n cmds:\n - echo 'Running command on Windows (amd64)'\n")),(0,i.kt)("p",null,"It is also possible to restrict the task to specific architectures:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build-amd64:\n platforms: [amd64]\n cmds:\n - echo 'Running command on amd64'\n")),(0,i.kt)("p",null,"Multiple platforms can be specified as follows:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n platforms: [windows/amd64, darwin]\n cmds:\n - echo 'Running command on Windows (amd64) and macOS'\n")),(0,i.kt)("p",null,"Individual commands can also be restricted to specific platforms:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n cmds:\n - cmd: echo 'Running command on Windows (amd64) and macOS'\n platforms: [windows/amd64, darwin]\n - cmd: echo 'Running on all platforms'\n")),(0,i.kt)("h2",{id:"calling-another-task"},"Calling another task"),(0,i.kt)("p",null,"When a task has many dependencies, they are executed concurrently. This will\noften result in a faster build pipeline. However, in some situations, you may need\nto call other tasks serially. In this case, use the following syntax:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'version: \'3\'\n\ntasks:\n main-task:\n cmds:\n - task: task-to-be-called\n - task: another-task\n - echo "Both done"\n\n task-to-be-called:\n cmds:\n - echo "Task to be called"\n\n another-task:\n cmds:\n - echo "Another task"\n')),(0,i.kt)("p",null,"Overriding variables in the called task is as simple as informing ",(0,i.kt)("inlineCode",{parentName:"p"},"vars"),"\nattribute:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'version: \'3\'\n\ntasks:\n greet:\n vars:\n RECIPIENT: \'{{default "World" .RECIPIENT}}\'\n cmds:\n - echo "Hello, {{.RECIPIENT}}!"\n\n greet-pessimistically:\n cmds:\n - task: greet\n vars: {RECIPIENT: "Cruel World"}\n')),(0,i.kt)("p",null,"The above syntax is also supported in ",(0,i.kt)("inlineCode",{parentName:"p"},"deps"),"."),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"NOTE: If you want to call a task declared in the root Taskfile from within an\n",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"included Taskfile"),", add a leading ",(0,i.kt)("inlineCode",{parentName:"p"},":")," like this:\n",(0,i.kt)("inlineCode",{parentName:"p"},"task: :task-name"),".")),(0,i.kt)("h2",{id:"prevent-unnecessary-work"},"Prevent unnecessary work"),(0,i.kt)("h3",{id:"by-fingerprinting-locally-generated-files-and-their-sources"},"By fingerprinting locally generated files and their sources"),(0,i.kt)("p",null,"If a task generates something, you can inform Task the source and generated\nfiles, so Task will prevent running them if not necessary."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n deps: [js, css]\n cmds:\n - go build -v -i main.go\n\n js:\n cmds:\n - esbuild --bundle --minify js/index.js > public/bundle.js\n sources:\n - src/js/**/*.js\n generates:\n - public/bundle.js\n\n css:\n cmds:\n - esbuild --bundle --minify css/index.css > public/bundle.css\n sources:\n - src/css/**/*.css\n generates:\n - public/bundle.css\n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"sources")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"generates")," can be files or file patterns. When given,\nTask will compare the checksum of the source files to determine if it's\nnecessary to run the task. If not, it will just print a message like\n",(0,i.kt)("inlineCode",{parentName:"p"},'Task "js" is up to date'),"."),(0,i.kt)("p",null,"If you prefer this check to be made by the modification timestamp of the files,\ninstead of its checksum (content), just set the ",(0,i.kt)("inlineCode",{parentName:"p"},"method")," property to ",(0,i.kt)("inlineCode",{parentName:"p"},"timestamp"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n cmds:\n - go build .\n sources:\n - ./*.go\n generates:\n - app{{exeExt}}\n method: timestamp\n")),(0,i.kt)("p",null,"In situations where you need more flexibility the ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," keyword can be used.\nYou can even combine the two. See the documentation for\n",(0,i.kt)("a",{parentName:"p",href:"#using-programmatic-checks-to-indicate-a-task-is-up-to-date"},"status")," for an\nexample."),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"By default, task stores checksums on a local ",(0,i.kt)("inlineCode",{parentName:"p"},".task")," directory in the project's\ndirectory. Most of the time, you'll want to have this directory on ",(0,i.kt)("inlineCode",{parentName:"p"},".gitignore"),"\n(or equivalent) so it isn't committed. (If you have a task for code generation\nthat is committed it may make sense to commit the checksum of that task as\nwell, though)."),(0,i.kt)("p",{parentName:"admonition"},"If you want these files to be stored in another directory, you can set a\n",(0,i.kt)("inlineCode",{parentName:"p"},"TASK_TEMP_DIR")," environment variable in your machine. It can contain a relative\npath like ",(0,i.kt)("inlineCode",{parentName:"p"},"tmp/task")," that will be interpreted as relative to the project\ndirectory, or an absolute or home path like ",(0,i.kt)("inlineCode",{parentName:"p"},"/tmp/.task")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"~/.task"),"\n(subdirectories will be created for each project)."),(0,i.kt)("pre",{parentName:"admonition"},(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"export TASK_TEMP_DIR='~/.task'\n"))),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Each task has only one checksum stored for its ",(0,i.kt)("inlineCode",{parentName:"p"},"sources"),". If you want\nto distinguish a task by any of its input variables, you can add those\nvariables as part of the task's label, and it will be considered a different\ntask."),(0,i.kt)("p",{parentName:"admonition"},"This is useful if you want to run a task once for each distinct set of\ninputs until the sources actually change. For example, if the sources depend\non the value of a variable, or you if you want the task to rerun if some arguments\nchange even if the source has not.")),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"The method ",(0,i.kt)("inlineCode",{parentName:"p"},"none")," skips any validation and always run the task.")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"For the ",(0,i.kt)("inlineCode",{parentName:"p"},"checksum")," (default) or ",(0,i.kt)("inlineCode",{parentName:"p"},"timestamp")," method to work, it is only necessary to\ninform the source files.\nWhen the ",(0,i.kt)("inlineCode",{parentName:"p"},"timestamp")," method is used, the last time of the running the task is considered as a generate.")),(0,i.kt)("h3",{id:"using-programmatic-checks-to-indicate-a-task-is-up-to-date"},"Using programmatic checks to indicate a task is up to date"),(0,i.kt)("p",null,"Alternatively, you can inform a sequence of tests as ",(0,i.kt)("inlineCode",{parentName:"p"},"status"),". If no error\nis returned (exit status 0), the task is considered up-to-date:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n generate-files:\n cmds:\n - mkdir directory\n - touch directory/file1.txt\n - touch directory/file2.txt\n # test existence of files\n status:\n - test -d directory\n - test -f directory/file1.txt\n - test -f directory/file2.txt\n")),(0,i.kt)("p",null,"Normally, you would use ",(0,i.kt)("inlineCode",{parentName:"p"},"sources")," in combination with\n",(0,i.kt)("inlineCode",{parentName:"p"},"generates")," - but for tasks that generate remote artifacts (Docker images,\ndeploys, CD releases) the checksum source and timestamps require either\naccess to the artifact or for an out-of-band refresh of the ",(0,i.kt)("inlineCode",{parentName:"p"},".checksum"),"\nfingerprint file."),(0,i.kt)("p",null,"Two special variables ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.CHECKSUM}}")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.TIMESTAMP}}")," are available\nfor interpolation within ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," commands, depending on the method assigned\nto fingerprint the sources. Only ",(0,i.kt)("inlineCode",{parentName:"p"},"source")," globs are fingerprinted."),(0,i.kt)("p",null,"Note that the ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.TIMESTAMP}}"),' variable is a "live" Go ',(0,i.kt)("inlineCode",{parentName:"p"},"time.Time")," struct, and\ncan be formatted using any of the methods that ",(0,i.kt)("inlineCode",{parentName:"p"},"time.Time")," responds to."),(0,i.kt)("p",null,"See ",(0,i.kt)("a",{parentName:"p",href:"https://golang.org/pkg/time/"},"the Go Time documentation")," for more information."),(0,i.kt)("p",null,"You can use ",(0,i.kt)("inlineCode",{parentName:"p"},"--force")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"-f")," if you want to force a task to run even when\nup-to-date."),(0,i.kt)("p",null,"Also, ",(0,i.kt)("inlineCode",{parentName:"p"},"task --status [tasks]...")," will exit with a non-zero exit code if any of\nthe tasks are not up-to-date."),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"status")," can be combined with the ",(0,i.kt)("a",{parentName:"p",href:"#by-fingerprinting-locally-generated-files-and-their-sources"},"fingerprinting"),"\nto have a task run if either the the source/generated artifacts changes, or the\nprogrammatic check fails:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:prod:\n desc: Build for production usage.\n cmds:\n - composer install\n # Run this task if source files changes.\n sources:\n - composer.json\n - composer.lock\n generates:\n - ./vendor/composer/installed.json\n - ./vendor/autoload.php\n # But also run the task if the last build was not a production build.\n status:\n - grep -q '\"dev\": false' ./vendor/composer/installed.json\n")),(0,i.kt)("h3",{id:"using-programmatic-checks-to-cancel-the-execution-of-a-task-and-its-dependencies"},"Using programmatic checks to cancel the execution of a task and its dependencies"),(0,i.kt)("p",null,"In addition to ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," checks, ",(0,i.kt)("inlineCode",{parentName:"p"},"preconditions")," checks are\nthe logical inverse of ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," checks. That is, if you need a certain set of\nconditions to be ",(0,i.kt)("em",{parentName:"p"},"true")," you can use the ",(0,i.kt)("inlineCode",{parentName:"p"},"preconditions")," stanza.\n",(0,i.kt)("inlineCode",{parentName:"p"},"preconditions")," are similar to ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," lines, except they support ",(0,i.kt)("inlineCode",{parentName:"p"},"sh"),"\nexpansion, and they SHOULD all return 0."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'version: \'3\'\n\ntasks:\n generate-files:\n cmds:\n - mkdir directory\n - touch directory/file1.txt\n - touch directory/file2.txt\n # test existence of files\n preconditions:\n - test -f .env\n - sh: "[ 1 = 0 ]"\n msg: "One doesn\'t equal Zero, Halting"\n')),(0,i.kt)("p",null,"Preconditions can set specific failure messages that can tell\na user what steps to take using the ",(0,i.kt)("inlineCode",{parentName:"p"},"msg")," field."),(0,i.kt)("p",null,"If a task has a dependency on a sub-task with a precondition, and that\nprecondition is not met - the calling task will fail. Note that a task\nexecuted with a failing precondition will not run unless ",(0,i.kt)("inlineCode",{parentName:"p"},"--force")," is\ngiven."),(0,i.kt)("p",null,"Unlike ",(0,i.kt)("inlineCode",{parentName:"p"},"status"),", which will skip a task if it is up to date and continue\nexecuting tasks that depend on it, a ",(0,i.kt)("inlineCode",{parentName:"p"},"precondition")," will fail a task, along\nwith any other tasks that depend on it."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'version: \'3\'\n\ntasks:\n task-will-fail:\n preconditions:\n - sh: "exit 1"\n\n task-will-also-fail:\n deps:\n - task-will-fail\n\n task-will-still-fail:\n cmds:\n - task: task-will-fail\n - echo "I will not run"\n')),(0,i.kt)("h3",{id:"limiting-when-tasks-run"},"Limiting when tasks run"),(0,i.kt)("p",null,"If a task executed by multiple ",(0,i.kt)("inlineCode",{parentName:"p"},"cmds")," or multiple ",(0,i.kt)("inlineCode",{parentName:"p"},"deps")," you can control\nwhen it is executed using ",(0,i.kt)("inlineCode",{parentName:"p"},"run"),". ",(0,i.kt)("inlineCode",{parentName:"p"},"run")," can also be set at the root\nof the Taskfile to change the behavior of all the tasks unless explicitly\noverridden."),(0,i.kt)("p",null,"Supported values for ",(0,i.kt)("inlineCode",{parentName:"p"},"run"),":"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"always")," (default) always attempt to invoke the task regardless of the\nnumber of previous executions"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"once")," only invoke this task once regardless of the number of references"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"when_changed")," only invokes the task once for each unique set of variables\npassed into the task")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n cmds:\n - task: generate-file\n vars: { CONTENT: '1' }\n - task: generate-file\n vars: { CONTENT: '2' }\n - task: generate-file\n vars: { CONTENT: '2' }\n\n generate-file:\n run: when_changed\n deps:\n - install-deps\n cmds:\n - echo {{.CONTENT}}\n\n install-deps:\n run: once\n cmds:\n - sleep 5 # long operation like installing packages\n")),(0,i.kt)("h2",{id:"variables"},"Variables"),(0,i.kt)("p",null,"When doing interpolation of variables, Task will look for the below.\nThey are listed below in order of importance (i.e. most important first):"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Variables declared in the task definition"),(0,i.kt)("li",{parentName:"ul"},"Variables given while calling a task from another\n(See ",(0,i.kt)("a",{parentName:"li",href:"#calling-another-task"},"Calling another task")," above)"),(0,i.kt)("li",{parentName:"ul"},"Variables of the ",(0,i.kt)("a",{parentName:"li",href:"#including-other-taskfiles"},"included Taskfile")," (when the task is included)"),(0,i.kt)("li",{parentName:"ul"},"Variables of the ",(0,i.kt)("a",{parentName:"li",href:"#vars-of-included-taskfiles"},"inclusion of the Taskfile")," (when the task is included)"),(0,i.kt)("li",{parentName:"ul"},"Global variables (those declared in the ",(0,i.kt)("inlineCode",{parentName:"li"},"vars:")," option in the Taskfile)"),(0,i.kt)("li",{parentName:"ul"},"Environment variables")),(0,i.kt)("p",null,"Example of sending parameters with environment variables:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ TASK_VARIABLE=a-value task do-something\n")),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"A special variable ",(0,i.kt)("inlineCode",{parentName:"p"},".TASK")," is always available containing the task name.")),(0,i.kt)("p",null,"Since some shells do not support the above syntax to set environment variables\n(Windows) tasks also accept a similar style when not at the beginning of\nthe command."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'$ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!"\n')),(0,i.kt)("p",null,"Example of locally declared vars:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print-var:\n cmds:\n - echo \"{{.VAR}}\"\n vars:\n VAR: Hello!\n")),(0,i.kt)("p",null,"Example of global vars in a ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nvars:\n GREETING: Hello from Taskfile!\n\ntasks:\n greet:\n cmds:\n - echo \"{{.GREETING}}\"\n")),(0,i.kt)("h3",{id:"dynamic-variables"},"Dynamic variables"),(0,i.kt)("p",null,"The below syntax (",(0,i.kt)("inlineCode",{parentName:"p"},"sh:")," prop in a variable) is considered a dynamic variable.\nThe value will be treated as a command and the output assigned. If there are one\nor more trailing newlines, the last newline will be trimmed."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n cmds:\n - go build -ldflags=\"-X main.Version={{.GIT_COMMIT}}\" main.go\n vars:\n GIT_COMMIT:\n sh: git log -n 1 --format=%h\n")),(0,i.kt)("p",null,"This works for all types of variables."),(0,i.kt)("h2",{id:"forwarding-cli-arguments-to-commands"},"Forwarding CLI arguments to commands"),(0,i.kt)("p",null,"If ",(0,i.kt)("inlineCode",{parentName:"p"},"--")," is given in the CLI, all following parameters are added to a\nspecial ",(0,i.kt)("inlineCode",{parentName:"p"},".CLI_ARGS")," variable. This is useful to forward arguments to another\ncommand."),(0,i.kt)("p",null,"The below example will run ",(0,i.kt)("inlineCode",{parentName:"p"},"yarn install"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ task yarn -- install\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n yarn:\n cmds:\n - yarn {{.CLI_ARGS}}\n")),(0,i.kt)("h2",{id:"doing-task-cleanup-with-defer"},"Doing task cleanup with ",(0,i.kt)("inlineCode",{parentName:"h2"},"defer")),(0,i.kt)("p",null,"With the ",(0,i.kt)("inlineCode",{parentName:"p"},"defer")," keyword, it's possible to schedule cleanup to be run once\nthe task finishes. The difference with just putting it as the last command is\nthat this command will run even when the task fails."),(0,i.kt)("p",null,"In the example below, ",(0,i.kt)("inlineCode",{parentName:"p"},"rm -rf tmpdir/")," will run even if the third command fails:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n cmds:\n - mkdir -p tmpdir/\n - defer: rm -rf tmpdir/\n - echo 'Do work on tmpdir/'\n")),(0,i.kt)("p",null,"If you want to move the cleanup command into another task, that is possible as\nwell:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n cmds:\n - mkdir -p tmpdir/\n - defer: { task: cleanup }\n - echo 'Do work on tmpdir/'\n\n cleanup: rm -rf tmpdir/\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Due to the nature of how the\n",(0,i.kt)("a",{parentName:"p",href:"https://go.dev/tour/flowcontrol/13"},"Go's own ",(0,i.kt)("inlineCode",{parentName:"a"},"defer")," work"),", the deferred\ncommands are executed in the reverse order if you schedule multiple of them.")),(0,i.kt)("h2",{id:"gos-template-engine"},"Go's template engine"),(0,i.kt)("p",null,"Task parse commands as ",(0,i.kt)("a",{parentName:"p",href:"https://golang.org/pkg/text/template/"},"Go's template engine")," before executing\nthem. Variables are accessible through dot syntax (",(0,i.kt)("inlineCode",{parentName:"p"},".VARNAME"),")."),(0,i.kt)("p",null,"All functions by the Go's ",(0,i.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/"},"slim-sprig lib"),"\nare available. The following example gets the current date in a given format:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print-date:\n cmds:\n - echo {{now | date \"2006-01-02\"}}\n")),(0,i.kt)("p",null,"Task also adds the following functions:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"OS"),': Returns the operating system. Possible values are "windows", "linux",\n"darwin" (macOS) and "freebsd".'),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"ARCH"),': return the architecture Task was compiled to: "386", "amd64", "arm"\nor "s390x".'),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"splitLines"),": Splits Unix (\\n) and Windows (\\r\\n) styled newlines."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"catLines"),": Replaces Unix (\\n) and Windows (\\r\\n) styled newlines with a space."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"toSlash"),": Does nothing on Unix, but on Windows converts a string from ",(0,i.kt)("inlineCode",{parentName:"li"},"\\"),"\npath format to ",(0,i.kt)("inlineCode",{parentName:"li"},"/"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"fromSlash"),": Opposite of ",(0,i.kt)("inlineCode",{parentName:"li"},"toSlash"),". Does nothing on Unix, but on Windows\nconverts a string from ",(0,i.kt)("inlineCode",{parentName:"li"},"/")," path format to ",(0,i.kt)("inlineCode",{parentName:"li"},"\\"),"."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"exeExt"),": Returns the right executable extension for the current OS\n(",(0,i.kt)("inlineCode",{parentName:"li"},'".exe"')," for Windows, ",(0,i.kt)("inlineCode",{parentName:"li"},'""')," for others)."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"shellQuote"),": Quotes a string to make it safe for use in shell scripts.\nTask uses ",(0,i.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote"},"this Go function"),"\nfor this. The Bash dialect is assumed."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"splitArgs"),": Splits a string as if it were a command's arguments.\nTask uses ",(0,i.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/shell#Fields"},"this Go function"))),(0,i.kt)("p",null,"Example:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n print-os:\n cmds:\n - echo '{{OS}} {{ARCH}}'\n - echo '{{if eq OS \"windows\"}}windows-command{{else}}unix-command{{end}}'\n # This will be path/to/file on Unix but path\\to\\file on Windows\n - echo '{{fromSlash \"path/to/file\"}}'\n enumerated-file:\n vars:\n CONTENT: |\n foo\n bar\n cmds:\n - |\n cat << EOF > output.txt\n {{range $i, $line := .CONTENT | splitLines -}}\n {{printf \"%3d\" $i}}: {{$line}}\n {{end}}EOF\n")),(0,i.kt)("h2",{id:"help"},"Help"),(0,i.kt)("p",null,"Running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --list")," (or ",(0,i.kt)("inlineCode",{parentName:"p"},"task -l"),") lists all tasks with a description.\nThe following Taskfile:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build:\n desc: Build the go binary.\n cmds:\n - go build -v -i main.go\n\n test:\n desc: Run all the go tests.\n cmds:\n - go test -race ./...\n\n js:\n cmds:\n - esbuild --bundle --minify js/index.js > public/bundle.js\n\n css:\n cmds:\n - esbuild --bundle --minify css/index.css > public/bundle.css\n")),(0,i.kt)("p",null,"would print the following output:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"* build: Build the go binary.\n* test: Run all the go tests.\n")),(0,i.kt)("p",null,"If you want to see all tasks, there's a ",(0,i.kt)("inlineCode",{parentName:"p"},"--list-all")," (alias ",(0,i.kt)("inlineCode",{parentName:"p"},"-a"),") flag as well."),(0,i.kt)("h2",{id:"display-summary-of-task"},"Display summary of task"),(0,i.kt)("p",null,"Running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --summary task-name")," will show a summary of a task.\nThe following Taskfile:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n release:\n deps: [build]\n summary: |\n Release your project to github\n\n It will build your project before starting the release.\n Please make sure that you have set GITHUB_TOKEN before starting.\n cmds:\n - your-release-tool\n\n build:\n cmds:\n - your-build-tool\n")),(0,i.kt)("p",null,"with running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --summary release")," would print the following output:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre"},"task: release\n\nRelease your project to github\n\nIt will build your project before starting the release.\nPlease make sure that you have set GITHUB_TOKEN before starting.\n\ndependencies:\n - build\n\ncommands:\n - your-release-tool\n")),(0,i.kt)("p",null,"If a summary is missing, the description will be printed.\nIf the task does not have a summary or a description, a warning is printed."),(0,i.kt)("p",null,"Please note: ",(0,i.kt)("em",{parentName:"p"},"showing the summary will not execute the command"),"."),(0,i.kt)("h2",{id:"task-aliases"},"Task aliases"),(0,i.kt)("p",null,"Aliases are alternative names for tasks. They can be used to make it easier and\nquicker to run tasks with long or hard-to-type names. You can use them on the\ncommand line, when ",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"calling sub-tasks")," in your Taskfile\nand when ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"including tasks")," with aliases from another\nTaskfile. They can also be used together with ",(0,i.kt)("a",{parentName:"p",href:"#namespace-aliases"},"namespace\naliases"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n generate:\n aliases: [gen]\n cmds:\n - task: gen-mocks\n\n generate-mocks:\n aliases: [gen-mocks]\n cmds:\n - echo \"generating...\"\n")),(0,i.kt)("h2",{id:"overriding-task-name"},"Overriding task name"),(0,i.kt)("p",null,"Sometimes you may want to override the task name printed on the summary, up-to-date\nmessages to STDOUT, etc. In this case, you can just set ",(0,i.kt)("inlineCode",{parentName:"p"},"label:"),", which can also\nbe interpolated with variables:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n - task: print\n vars:\n MESSAGE: hello\n - task: print\n vars:\n MESSAGE: world\n\n print:\n label: 'print-{{.MESSAGE}}'\n cmds:\n - echo \"{{.MESSAGE}}\"\n")),(0,i.kt)("h2",{id:"silent-mode"},"Silent mode"),(0,i.kt)("p",null,"Silent mode disables the echoing of commands before Task runs it.\nFor the following Taskfile:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n")),(0,i.kt)("p",null,"Normally this will be printed:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},'echo "Print something"\nPrint something\n')),(0,i.kt)("p",null,"With silent mode on, the below will be printed instead:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"Print something\n")),(0,i.kt)("p",null,"There are four ways to enable silent mode:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"At command level:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - cmd: echo \"Print something\"\n silent: true\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"At task level:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n silent: true\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Globally at Taskfile level:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nsilent: true\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n")),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"Or globally with ",(0,i.kt)("inlineCode",{parentName:"li"},"--silent")," or ",(0,i.kt)("inlineCode",{parentName:"li"},"-s")," flag")),(0,i.kt)("p",null,"If you want to suppress STDOUT instead, just redirect a command to ",(0,i.kt)("inlineCode",{parentName:"p"},"/dev/null"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - echo \"This will print nothing\" > /dev/null\n")),(0,i.kt)("h2",{id:"dry-run-mode"},"Dry run mode"),(0,i.kt)("p",null,"Dry run mode (",(0,i.kt)("inlineCode",{parentName:"p"},"--dry"),") compiles and steps through each task, printing the commands\nthat would be run without executing them. This is useful for debugging your Taskfiles."),(0,i.kt)("h2",{id:"ignore-errors"},"Ignore errors"),(0,i.kt)("p",null,"You have the option to ignore errors during command execution.\nGiven the following Taskfile:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - exit 1\n - echo \"Hello World\"\n")),(0,i.kt)("p",null,"Task will abort the execution after running ",(0,i.kt)("inlineCode",{parentName:"p"},"exit 1")," because the status code ",(0,i.kt)("inlineCode",{parentName:"p"},"1")," stands for ",(0,i.kt)("inlineCode",{parentName:"p"},"EXIT_FAILURE"),".\nHowever, it is possible to continue with execution using ",(0,i.kt)("inlineCode",{parentName:"p"},"ignore_error"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - cmd: exit 1\n ignore_error: true\n - echo \"Hello World\"\n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"ignore_error")," can also be set for a task, which means errors will be suppressed\nfor all commands. Nevertheless, keep in mind that this option will not propagate to other tasks\ncalled either by ",(0,i.kt)("inlineCode",{parentName:"p"},"deps")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"cmds"),"!"),(0,i.kt)("h2",{id:"output-syntax"},"Output syntax"),(0,i.kt)("p",null,"By default, Task just redirects the STDOUT and STDERR of the running commands\nto the shell in real-time. This is good for having live feedback for logging\nprinted by commands, but the output can become messy if you have multiple\ncommands running simultaneously and printing lots of stuff."),(0,i.kt)("p",null,"To make this more customizable, there are currently three different output\noptions you can choose:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"interleaved")," (default)"),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"group")),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"prefixed"))),(0,i.kt)("p",null,"To choose another one, just set it to root in the Taskfile:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\noutput: 'group'\n\ntasks:\n # ...\n")),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"group")," output will print the entire output of a command once after it\nfinishes, so you will not have live feedback for commands that take a long time\nto run."),(0,i.kt)("p",null,"When using the ",(0,i.kt)("inlineCode",{parentName:"p"},"group")," output, you can optionally provide a templated message\nto print at the start and end of the group. This can be useful for instructing\nCI systems to group all of the output for a given task, such as with\n",(0,i.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#grouping-log-lines"},"GitHub Actions' ",(0,i.kt)("inlineCode",{parentName:"a"},"::group::")," command"),"\nor ",(0,i.kt)("a",{parentName:"p",href:"https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?expand=1&view=azure-devops&tabs=bash#formatting-commands"},"Azure Pipelines"),"."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\noutput:\n group:\n begin: '::group::{{.TASK}}'\n end: '::endgroup::'\n\ntasks:\n default:\n cmds:\n - echo 'Hello, World!'\n silent: true\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ task default\n::group::default\nHello, World!\n::endgroup::\n")),(0,i.kt)("p",null,"When using the ",(0,i.kt)("inlineCode",{parentName:"p"},"group")," output, you may swallow the output of the executed command\non standard output and standard error if it does not fail (zero exit code)."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nsilent: true\n\noutput:\n group:\n error_only: true\n\ntasks:\n passes: echo 'output-of-passes'\n errors: echo 'output-of-errors' && exit 1\n")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'$ task passes\n$ task errors\noutput-of-errors\ntask: Failed to run task "errors": exit status 1\n')),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"prefix")," output will prefix every line printed by a command with\n",(0,i.kt)("inlineCode",{parentName:"p"},"[task-name] ")," as the prefix, but you can customize the prefix for a command\nwith the ",(0,i.kt)("inlineCode",{parentName:"p"},"prefix:")," attribute:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},'version: \'3\'\n\noutput: prefixed\n\ntasks:\n default:\n deps:\n - task: print\n vars: {TEXT: foo}\n - task: print\n vars: {TEXT: bar}\n - task: print\n vars: {TEXT: baz}\n\n print:\n cmds:\n - echo "{{.TEXT}}"\n prefix: "print-{{.TEXT}}"\n silent: true\n')),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"$ task default\n[print-foo] foo\n[print-bar] bar\n[print-baz] baz\n")),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"The ",(0,i.kt)("inlineCode",{parentName:"p"},"output")," option can also be specified by the ",(0,i.kt)("inlineCode",{parentName:"p"},"--output")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"-o")," flags.")),(0,i.kt)("h2",{id:"interactive-cli-application"},"Interactive CLI application"),(0,i.kt)("p",null,"When running interactive CLI applications inside Task they can sometimes behave\nweirdly, especially when the ",(0,i.kt)("a",{parentName:"p",href:"#output-syntax"},"output mode")," is set to something\nother than ",(0,i.kt)("inlineCode",{parentName:"p"},"interleaved")," (the default), or when interactive apps are run in\nparallel with other tasks."),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"interactive: true")," tells Task this is an interactive application and Task\nwill try to optimize for it:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n default:\n cmds:\n - vim my-file.txt\n interactive: true\n")),(0,i.kt)("p",null,"If you still have problems running an interactive app through Task, please open\nan issue about it."),(0,i.kt)("h2",{id:"short-task-syntax"},"Short task syntax"),(0,i.kt)("p",null,"Starting on Task v3, you can now write tasks with a shorter syntax if they\nhave the default settings (e.g. no custom ",(0,i.kt)("inlineCode",{parentName:"p"},"env:"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"vars:"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"desc:"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"silent:")," , etc):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n build: go build -v -o ./app{{exeExt}} .\n\n run:\n - task: build\n - ./app{{exeExt}} -h localhost -p 8080\n")),(0,i.kt)("h2",{id:"set-and-shopt"},(0,i.kt)("inlineCode",{parentName:"h2"},"set")," and ",(0,i.kt)("inlineCode",{parentName:"h2"},"shopt")),(0,i.kt)("p",null,"It's possible to specify options to the\n",(0,i.kt)("a",{parentName:"p",href:"https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html"},(0,i.kt)("inlineCode",{parentName:"a"},"set")),"\nand ",(0,i.kt)("a",{parentName:"p",href:"https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html"},(0,i.kt)("inlineCode",{parentName:"a"},"shopt")),"\nbuiltins. This can be added at global, task or command level."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nset: [pipefail]\nshopt: [globstar]\n\ntasks:\n # `globstar` required for double star globs to work\n default: echo **/*.go\n")),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"Keep in mind that not all options are available in the\n",(0,i.kt)("a",{parentName:"p",href:"https://github.com/mvdan/sh"},"shell interpreter library")," that Task uses.")),(0,i.kt)("h2",{id:"watch-tasks"},"Watch tasks"),(0,i.kt)("p",null,"With the flags ",(0,i.kt)("inlineCode",{parentName:"p"},"--watch")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"-w")," task will watch for file changes\nand run the task again. This requires the ",(0,i.kt)("inlineCode",{parentName:"p"},"sources")," attribute to be given,\nso task knows which files to watch."),(0,i.kt)("p",null,"The default watch interval is 5 seconds, but it's possible to change it by\neither setting ",(0,i.kt)("inlineCode",{parentName:"p"},"interval: '500ms'")," in the root of the Taskfile passing it\nas an argument like ",(0,i.kt)("inlineCode",{parentName:"p"},"--interval=500ms"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/7d415946.6bf3701e.js b/assets/js/7d415946.6bf3701e.js deleted file mode 100644 index 6a947e68..00000000 --- a/assets/js/7d415946.6bf3701e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[705],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return h}});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),f=r,h=u["".concat(l,".").concat(f)]||u[f]||m[f]||o;return n?a.createElement(h,i(i({ref:t},c),{},{components:n})):a.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var p=2;p=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),p=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(l.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},f=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=p(n),f=r,h=u["".concat(l,".").concat(f)]||u[f]||m[f]||o;return n?a.createElement(h,i(i({ref:t},c),{},{components:n})):a.createElement(h,i({ref:t},c))}));function h(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=f;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var p=2;p=0||(l[n]=t[n]);return l}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(l[n]=t[n])}return l}var p=a.createContext({}),o=function(t){var e=a.useContext(p),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},m=function(t){var e=o(t.components);return a.createElement(p.Provider,{value:e},t.children)},k="mdxType",N={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,l=t.mdxType,r=t.originalType,p=t.parentName,m=d(t,["components","mdxType","originalType","parentName"]),k=o(n),u=l,s=k["".concat(p,".").concat(u)]||k[u]||N[u]||r;return n?a.createElement(s,i(i({ref:e},m),{},{components:n})):a.createElement(s,i({ref:e},m))}));function s(t,e){var n=arguments,l=e&&e.mdxType;if("string"==typeof t||l){var r=n.length,i=new Array(r);i[0]=u;var d={};for(var p in e)hasOwnProperty.call(e,p)&&(d[p]=e[p]);d.originalType=t,d[k]="string"==typeof t?t:l,i[1]=d;for(var o=2;o=0||(l[n]=t[n]);return l}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(l[n]=t[n])}return l}var p=a.createContext({}),o=function(t){var e=a.useContext(p),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},m=function(t){var e=o(t.components);return a.createElement(p.Provider,{value:e},t.children)},k="mdxType",N={inlineCode:"code",wrapper:function(t){var e=t.children;return a.createElement(a.Fragment,{},e)}},u=a.forwardRef((function(t,e){var n=t.components,l=t.mdxType,r=t.originalType,p=t.parentName,m=d(t,["components","mdxType","originalType","parentName"]),k=o(n),u=l,s=k["".concat(p,".").concat(u)]||k[u]||N[u]||r;return n?a.createElement(s,i(i({ref:e},m),{},{components:n})):a.createElement(s,i({ref:e},m))}));function s(t,e){var n=arguments,l=e&&e.mdxType;if("string"==typeof t||l){var r=n.length,i=new Array(r);i[0]=u;var d={};for(var p in e)hasOwnProperty.call(e,p)&&(d[p]=e[p]);d.originalType=t,d[k]="string"==typeof t?t:l,i[1]=d;for(var o=2;o=o)&&Object.keys(u.O).every((function(e){return u.O[e](n[i])}))?n.splice(i--,1):(a=!1,o0&&e[d-1][2]>o;d--)e[d]=e[d-1];e[d]=[n,r,o]},u.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return u.d(t,{a:t}),t},n=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},u.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var o=Object.create(null);u.r(o);var f={};t=t||[null,n({}),n([]),n(n)];for(var a=2&r&&e;"object"==typeof a&&!~t.indexOf(a);a=n(a))Object.getOwnPropertyNames(a).forEach((function(t){f[t]=function(){return e[t]}}));return f.default=function(){return e},u.d(o,f),o},u.d=function(e,t){for(var n in t)u.o(t,n)&&!u.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},u.f={},u.e=function(e){return Promise.all(Object.keys(u.f).reduce((function(t,n){return u.f[n](e,t),t}),[]))},u.u=function(e){return"assets/js/"+({34:"9beb87c2",53:"935f2afb",80:"4d54d076",133:"f1d66b0d",217:"3b8c55ea",252:"02371786",514:"1be78505",552:"0afd354a",582:"f7fd502c",595:"d0766b26",648:"3c140c84",671:"0e384e19",705:"7d415946",713:"1c56b476",827:"6476eba6",836:"0480b142",880:"5ef0e9d6",918:"17896441",920:"1a4e3797"}[e]||e)+"."+{34:"ae7d3c47",53:"9bf38336",80:"a2286968",133:"6862b446",217:"151fc55e",252:"9481901e",514:"9062895a",552:"fb40b428",582:"3c1fe589",595:"c5627647",648:"b629b889",671:"47884a35",705:"d2c60d0c",713:"7edac691",780:"b979b06f",827:"e90c30d8",836:"098568bb",880:"537bbfb9",894:"4bf7d380",918:"e75765f6",920:"a9132d06",945:"3694633c",972:"01a5a892"}[e]+".js"},u.miniCssF=function(e){},u.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),u.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r={},o="taskfile-dev:",u.l=function(e,t,n,f){if(r[e])r[e].push(t);else{var a,i;if(void 0!==n)for(var c=document.getElementsByTagName("script"),d=0;d=o)&&Object.keys(i.O).every((function(e){return i.O[e](n[a])}))?n.splice(a--,1):(u=!1,o0&&e[d-1][2]>o;d--)e[d]=e[d-1];e[d]=[n,r,o]},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,{a:t}),t},n=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},i.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var o=Object.create(null);i.r(o);var f={};t=t||[null,n({}),n([]),n(n)];for(var u=2&r&&e;"object"==typeof u&&!~t.indexOf(u);u=n(u))Object.getOwnPropertyNames(u).forEach((function(t){f[t]=function(){return e[t]}}));return f.default=function(){return e},i.d(o,f),o},i.d=function(e,t){for(var n in t)i.o(t,n)&&!i.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},i.f={},i.e=function(e){return Promise.all(Object.keys(i.f).reduce((function(t,n){return i.f[n](e,t),t}),[]))},i.u=function(e){return"assets/js/"+({34:"9beb87c2",53:"935f2afb",80:"4d54d076",133:"f1d66b0d",217:"3b8c55ea",252:"02371786",514:"1be78505",552:"0afd354a",582:"f7fd502c",595:"d0766b26",648:"3c140c84",671:"0e384e19",705:"7d415946",713:"1c56b476",827:"6476eba6",836:"0480b142",880:"5ef0e9d6",918:"17896441",920:"1a4e3797"}[e]||e)+"."+{34:"ae7d3c47",53:"8872dd05",80:"63a4de28",133:"6862b446",217:"6a334942",252:"2e4dab92",514:"9062895a",552:"e8bad103",582:"4177ef6b",595:"c5627647",648:"b629b889",671:"649e4736",705:"6bf3701e",713:"63036b78",780:"b979b06f",827:"f5165ba7",836:"098568bb",880:"9579102c",894:"4bf7d380",918:"e75765f6",920:"a9132d06",945:"3694633c",972:"01a5a892"}[e]+".js"},i.miniCssF=function(e){},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r={},o="taskfile-dev:",i.l=function(e,t,n,f){if(r[e])r[e].push(t);else{var u,a;if(void 0!==n)for(var c=document.getElementsByTagName("script"),d=0;d
- + \ No newline at end of file diff --git a/community/index.html b/community/index.html index a1ea857c..8a1b4abb 100644 --- a/community/index.html +++ b/community/index.html @@ -3,43 +3,48 @@ -Community | Task +Community | Task - +
-
Skip to main content

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.

Translations

@DeronW maintains the +

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.

Translations

@DeronW maintains the Chinese translation of the -website on this repository.

Editor Integrations

JSON Schema

Initial work on the schema was made by @KROSF -on this Gist. -The schema is currently available at -https://taskfile.dev/schema.json and linked at https://json.schemastore.org/taskfile.json -so it is be used automatically many code editors, like VSCode. -Contributions can be done by editing this file.

Visual Studio Code extension

Additionally, there's also some work done by +website on this repository.

Editor Integrations

JSON Schema

Initial work on the schema was made by @KROSF on +this Gist. The +schema is currently available at https://taskfile.dev/schema.json and linked at +https://json.schemastore.org/taskfile.json so it is be used automatically many +code editors, like VSCode. Contributions can be done by editing +this file.

Visual Studio Code extension

Additionally, there's also some work done by @paulvarache in making an Visual Studio Code -extension, which has its code here -and is published here.

Sublime Text 4 package

There is a convenience wrapper for initializing and running tasks from Sublime Text's command palette. The package is -developed by @biozz, the source code is available here -and it is published on Package Control here.

IntelliJ plugin

There's a JetBrains IntelliJ plugin done by -@lechuckroh, which has its code here -and is published here.

Other Integrations

  • mk command line tool recognizes Taskfiles -natively.

Installation methods

Some installation methods are maintained by third party:

More

Also, thanks for all the code contributors, +extension, which has its code +here and is published +here.

Sublime Text 4 package

There is a convenience wrapper for initializing and running tasks from Sublime +Text's command palette. The package is developed by +@biozz, the source code is available +here and it is published on Package +Control here.

IntelliJ plugin

There's a JetBrains IntelliJ plugin done by +@lechuckroh, which has its code +here and is published +here.

Other Integrations

  • mk command line tool recognizes Taskfiles +natively.

Installation methods

Some installation methods are maintained by third party:

More

Also, thanks for all the +code contributors, financial contributors, all those who reported bugs and -answered questions.

If you know something that is missing in this document, please submit a -pull request.

- +answered questions.

If you know something that is missing in this document, please submit a pull +request.

+ \ No newline at end of file diff --git a/contributing/index.html b/contributing/index.html index f3f09cc6..aff108a9 100644 --- a/contributing/index.html +++ b/contributing/index.html @@ -10,21 +10,21 @@ - +
Skip to main content

Contributing

Contributions to Task are very welcome, but we ask that you read this document before submitting a PR.

Before you start

  • Check existing work - Is there an existing PR? Are there issues discussing -the feature/change you want to make? Please make sure you consider/address these -discussions in your work.
  • Backwards compatibility - Will your change break existing Taskfiles? It is +the feature/change you want to make? Please make sure you consider/address +these discussions in your work.
  • Backwards compatibility - Will your change break existing Taskfiles? It is much more likely that your change will merged if it backwards compatible. Is there an approach you can take that maintains this compatibility? If not, -consider opening an issue first so that API changes can be discussed before you -invest your time into a PR.

1. Setup

  • Go - Task is written in Go. We always support the latest two major Go -versions, so make sure your version is recent enough.
  • Node.js - Node.js is used to host Task's documentation server and is -required if you want to run this server locally.
  • Yarn - Yarn is the Node.js package manager used by Task.

2. Making changes

  • Code style - Try to maintain the existing code style where possible and +consider opening an issue first so that API changes can be discussed before +you invest your time into a PR.

1. Setup

  • Go - Task is written in Go. We always support the latest two major +Go versions, so make sure your version is recent enough.
  • Node.js - Node.js is used to host Task's documentation server +and is required if you want to run this server locally.
  • Yarn - Yarn is the Node.js package manager used by Task.

2. Making changes

  • Code style - Try to maintain the existing code style where possible and ensure that code is formatted by gofumpt. We use golangci-lint in our CI to enforce a @@ -34,19 +34,19 @@ that are found.
  • Documentation - Ensure that you add/upd the updating documentation section below.
  • Tests - Ensure that you add/update any relevant tests and that all tests are passing before submitting the PR. See the writing tests section below.

Running your changes

To run Task with working changes, you can use go run ./cmd/task. To run a -development build of task against a test Taskfile in testdata, you can use go -run ./cmd/task --dir ./testdata/<my_test_dir> <task_name>.

Updating documentation

Task uses Docusaurus to host a documentation server. This can be setup and run -locally by using task docs (requires nodejs & yarn). All content is -written in Markdown and is located in the docs/docs directory. All Markdown -documents should have an 80 character line wrap limit.

When making a change, consider whether a change to the Usage Guide +development build of task against a test Taskfile in testdata, you can use +go run ./cmd/task --dir ./testdata/<my_test_dir> <task_name>.

Updating documentation

Task uses Docusaurus to host a documentation server. This can be +setup and run locally by using task docs (requires nodejs & yarn). All +content is written in Markdown and is located in the docs/docs directory. All +Markdown documents should have an 80 character line wrap limit.

When making a change, consider whether a change to the Usage Guide is necessary. This document contains descriptions and examples of how to use Task features. If you're adding a new feature, try to find an appropriate place to add a new section. If you're updating an existing feature, ensure that the documentation and any examples are up-to-date. Ensure that any examples follow -the Taskfile Styleguide.

If you added a new field, command or flag, ensure that you add it to the API -Reference. New fields also need to be added to the JSON -Schema. The descriptions for fields in the API reference and the schema should -match.

Writing tests

Most of Task's test are held in the task_test.go file in the project root and +the Taskfile Styleguide.

If you added a new field, command or flag, ensure that you add it to the +API Reference. New fields also need to be added to the +JSON Schema. The descriptions for fields in the API reference and +the schema should match.

Writing tests

Most of Task's test are held in the task_test.go file in the project root and this is where you'll most likely want to add new ones too. Most of these tests also have a subdirectory in the testdata directory where any Taskfiles/data required to run the tests are stored.

When making a changes, consider whether new tests are required. These tests @@ -60,12 +60,13 @@ Please describe how your changes differ to/extend this work.

  • Exa effect of your changes.
  • Draft PRs - If your changes are incomplete, but you would like to discuss them, open the PR as a draft and add a comment to start a discussion. Using comments rather than the PR description allows the description to be updated -later while preserving any discussions.
  • FAQ

    I want to contribute, where do I start?

    Take a look at the list of open issues. We have a good first issue label for -simpler issues that are ideal for first time contributions.

    All kinds of contributions are welcome, whether its a typo fix or a shiny new +later while preserving any discussions.

    FAQ

    I want to contribute, where do I start?

    Take a look at the list of open issues. We have a good first +issue label for simpler issues that are ideal for first time +contributions.

    All kinds of contributions are welcome, whether its a typo fix or a shiny new feature. You can also contribute by upvoting/commenting on issues, helping to answer questions or contributing to other community projects.

    I'm stuck, where can I get help?

    If you have questions, feel free to ask them in the #help forum channel on our Discord server or open a Discussion on GitHub.


    - + \ No newline at end of file diff --git a/donate/index.html b/donate/index.html index 60de045d..ccbb00aa 100644 --- a/donate/index.html +++ b/donate/index.html @@ -10,21 +10,21 @@ - +
    Skip to main content

    Donate

    If you find this project useful, you can consider donating by using one of the channels listed below.

    This is just a way of saying "thank you", it won't give you any benefits like -higher priority on issues or something similar.

    Companies who donate at least $50/month will be featured as a "Gold Sponsor" -in the website homepage and on the GitHub repository README. Make contact with -@andreynering with the logo you want to be shown. -Suspect businesses (gambling, casinos, etc) won't be allowed, though.

    GitHub Sponsors

    The preferred way to donate to the maintainers is via GitHub Sponsors. -Just use the following links to do your donation:

    Open Collective

    If you prefer Open Collective you can donate +higher priority on issues or something similar.

    Companies who donate at least $50/month will be featured as a "Gold Sponsor" in +the website homepage and on the GitHub repository README. Make contact with +@andreynering with the logo you want to be shown. Suspect businesses +(gambling, casinos, etc) won't be allowed, though.

    GitHub Sponsors

    The preferred way to donate to the maintainers is via GitHub Sponsors. Just use +the following links to do your donation:

    Open Collective

    If you prefer Open Collective you can donate by using these links:

    PayPal

    You can donate to @andreynering via PayPal as well:

    PIX (Brazil only)

    And if you're Brazilian, you can also donate to @andreynering via PIX by using this QR Code.

    - + \ No newline at end of file diff --git a/faq/index.html b/faq/index.html index 2f0a79e8..d406efef 100644 --- a/faq/index.html +++ b/faq/index.html @@ -10,7 +10,7 @@ - + @@ -27,7 +27,7 @@ around this limitation using one of the following methods:

    We want to make improvements to this part of Task and the issues below track this work. Constructive comments and contributions are very welcome!

    - + \ No newline at end of file diff --git a/index.html b/index.html index 1d663a79..d3d58ba1 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@ - + @@ -22,12 +22,14 @@ setups just to use a build tool.

    Once installedYAML schema in a file called Taskfile.yml:

    Taskfile.yml
    version: '3'

    tasks:
    hello:
    cmds:
    - echo 'Hello World from Task!'
    silent: true

    And call it by running task hello from your terminal.

    The above example is just the start, you can take a look at the usage guide to check the full schema documentation and Task features.

    Features

    Gold Sponsors

    Appwrite
    Appwrite
    - +Snapcraft, or Scoop if you want.
  • Available on CIs: by adding +this simple command to install on your CI +script and you're ready to use Task as part of your CI pipeline;
  • Truly cross-platform: while most build tools only work well on Linux or macOS, +Task also supports Windows thanks to this shell interpreter for Go.
  • Great for code generation: you can easily +prevent a task from running if a given set +of files haven't changed since last run (based either on its timestamp or +content).
  • Gold Sponsors

    Appwrite
    Appwrite
    + \ No newline at end of file diff --git a/installation/index.html b/installation/index.html index 95e54827..ca3f31ce 100644 --- a/installation/index.html +++ b/installation/index.html @@ -10,45 +10,48 @@ - +
    Skip to main content

    Installation

    Task offers many installation methods. Check out the available methods below.

    Package Managers

    Homebrew

    If you're on macOS or Linux and have Homebrew installed, getting -Task is as simple as running:

    brew install go-task/tap/go-task

    The above Formula is maintained by ourselves.

    Recently, Task was also made available on the official Homebrew repository, -so you also have that option if you prefer:

    brew install go-task

    Snap

    Task is available in Snapcraft, but keep in mind that your -Linux distribution should allow classic confinement for Snaps to Task work -right:

    sudo snap install task --classic

    Chocolatey

    If you're on Windows and have Chocolatey installed, getting -Task is as simple as running:

    choco install go-task

    This installation method is community owned.

    Scoop

    If you're on Windows and have Scoop installed, getting -Task is as simple as running:

    scoop install task

    This installation method is community owned. After a new release of Task, it -may take some time until it's available on Scoop.

    AUR

    If you're on Arch Linux you can install Task from +Task is as simple as running:

    brew install go-task/tap/go-task

    The above Formula is +maintained by ourselves.

    Recently, Task was also made available +on the official Homebrew repository, +so you also have that option if you prefer:

    brew install go-task

    Snap

    Task is available in Snapcraft, but keep in mind that your Linux +distribution should allow classic confinement for Snaps to Task work right:

    sudo snap install task --classic

    Chocolatey

    If you're on Windows and have Chocolatey installed, getting Task is as +simple as running:

    choco install go-task

    This installation method is community owned.

    Scoop

    If you're on Windows and have Scoop installed, getting Task is as +simple as running:

    scoop install task

    This installation method is community owned. After a new release of Task, it may +take some time until it's available on Scoop.

    AUR

    If you're on Arch Linux you can install Task from AUR using your favorite package manager such as yay, pacaur or yaourt:

    yay -S go-task-bin

    Alternatively, there's this package which installs from the source code instead of downloading the binary from the releases page:

    yay -S go-task

    This installation method is community owned.

    Fedora

    If you're on Fedora Linux you can install Task from the official -Fedora repository using dnf:

    sudo dnf install go-task

    This installation method is community owned. After a new release of Task, it -may take some time until it's available in Fedora.

    Nix

    If you're on NixOS or have Nix installed -you can install Task from nixpkgs:

    nix-env -iA nixpkgs.go-task

    This installation method is community owned. After a new release of Task, it -may take some time until it's available in nixpkgs.

    npm

    You can also use Node and npm to install Task by installing +Fedora +repository using dnf:

    sudo dnf install go-task

    This installation method is community owned. After a new release of Task, it may +take some time until it's available in +Fedora.

    Nix

    If you're on NixOS or have Nix installed you can install Task from +nixpkgs:

    nix-env -iA nixpkgs.go-task

    This installation method is community owned. After a new release of Task, it may +take some time until it's available in +nixpkgs.

    npm

    You can also use Node and npm to install Task by installing this package.

    npm install -g @go-task/cli

    Winget

    If you are using Windows and installed the -winget package management tool, -you can install Task from -winget-pkgs.

    winget install Task.Task

    Get The Binary

    Binary

    You can download the binary from the releases page on GitHub and -add to your $PATH.

    DEB and RPM packages are also available.

    The task_checksums.txt file contains the SHA-256 checksum for each file.

    Install Script

    We also have an install script which is very useful in +winget package management tool, you +can install Task from winget-pkgs.

    winget install Task.Task

    Get The Binary

    Binary

    You can download the binary from the releases page on GitHub and add +to your $PATH.

    DEB and RPM packages are also available.

    The task_checksums.txt file contains the SHA-256 checksum for each file.

    Install Script

    We also have an install script which is very useful in scenarios like CI. Many thanks to GoDownloader for enabling the easy generation of this script.

    By default, it installs on the ./bin directory relative to the working directory:

    sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d

    It is possible to override the installation directory with the -b parameter. On Linux, common choices are ~/.local/bin and ~/bin to install for the current user or /usr/local/bin to install for all users:

    sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin
    caution

    On macOS and Windows, ~/.local/bin and ~/bin are not added to $PATH by default.

    GitHub Actions

    If you want to install Task in GitHub Actions you can try using -this action -by the Arduino team:

    - name: Install Task
    uses: arduino/setup-task@v1
    with:
    version: 3.x
    repo-token: ${{ secrets.GITHUB_TOKEN }}

    This installation method is community owned.

    Build From Source

    Go Modules

    Ensure that you have a supported version of Go properly installed and setup. You can find -the minimum required version of Go in the go.mod file.

    You can then install the latest release globally by running:

    go install github.com/go-task/task/v3/cmd/task@latest

    Or you can install into another directory:

    env GOBIN=/bin go install github.com/go-task/task/v3/cmd/task@latest
    tip

    For CI environments we recommend using the install script +this action by the Arduino team:

    - name: Install Task
    uses: arduino/setup-task@v1
    with:
    version: 3.x
    repo-token: ${{ secrets.GITHUB_TOKEN }}

    This installation method is community owned.

    Build From Source

    Go Modules

    Ensure that you have a supported version of Go properly installed and +setup. You can find the minimum required version of Go in the +go.mod file.

    You can then install the latest release globally by running:

    go install github.com/go-task/task/v3/cmd/task@latest

    Or you can install into another directory:

    env GOBIN=/bin go install github.com/go-task/task/v3/cmd/task@latest
    tip

    For CI environments we recommend using the install script instead, which is faster and more stable, since it'll just download the latest released binary.

    Setup completions

    Download the autocompletion file corresponding to your shell.

    All completions are available on the Task repository.

    Bash

    First, ensure that you installed bash-completion using your package manager.

    Make the completion file executable:

    chmod +x path/to/task.bash

    After, add this to your ~/.bash_profile:

    source path/to/task.bash

    ZSH

    Put the _task file somewhere in your $FPATH:

    mv path/to/_task /usr/local/share/zsh/site-functions/_task

    Ensure that the following is present in your ~/.zshrc:

    autoload -U compinit
    compinit -i

    ZSH version 5.7 or later is recommended.

    Fish

    Move the task.fish completion script:

    mv path/to/task.fish ~/.config/fish/completions/task.fish

    PowerShell

    Open your profile script with:

    mkdir -Path (Split-Path -Parent $profile) -ErrorAction SilentlyContinue
    notepad $profile

    Add the line and save the file:

    Invoke-Expression -Command path/to/task.ps1
    - + \ No newline at end of file diff --git a/releasing/index.html b/releasing/index.html index 7682a948..22556827 100644 --- a/releasing/index.html +++ b/releasing/index.html @@ -3,37 +3,38 @@ -Releasing | Task +Releasing | Task - +
    -
    Skip to main content

    Releasing

    The release process of Task is done with the help of -GoReleaser. You can test the release process locally by calling -the test-release task of the Taskfile.

    GitHub Actions should release -artifacts automatically when a new Git tag is pushed to master -(raw executables and DEB and RPM packages).

    Since v3.15.0, raw executables can also be reproduced and verified locally by +

    Releasing

    The release process of Task is done with the help of GoReleaser. +You can test the release process locally by calling the test-release task of +the Taskfile.

    GitHub Actions should release +artifacts automatically when a new Git tag is pushed to master (raw executables +and DEB and RPM packages).

    Since v3.15.0, raw executables can also be reproduced and verified locally by checking out a specific tag and calling goreleaser build, using the Go version defined in the above GitHub Actions.

    Homebrew

    Goreleaser will automatically push a new commit to the Formula/go-task.rb file in the Homebrew tap repository to release the new version.

    npm

    To release to npm update the version in the package.json file and then run task npm:publish to push it.

    Snapcraft

    The snap package requires to manual steps to release a new -version:

    Scoop

    Scoop is a command-line package manager for the Windows operating system. -Scoop package manifests are maintained by the community. -Scoop owners usually take care of updating versions there by editing this file. -If you think its Task version is outdated, open an issue to let us know.

    Nix

    Nix is a community owned installation method. Nix package maintainers usually take care -of updating versions there by editing +version:

    Scoop

    Scoop is a command-line package manager for the Windows operating system. Scoop +package manifests are maintained by the community. Scoop owners usually take +care of updating versions there by editing +this file. +If you think its Task version is outdated, open an issue to let us know.

    Nix

    Nix is a community owned installation method. Nix package maintainers usually +take care of updating versions there by editing this file. If you think its Task version is outdated, open an issue to let us know.

    - + \ No newline at end of file diff --git a/search/index.html b/search/index.html index 29465b3f..b51f9db6 100644 --- a/search/index.html +++ b/search/index.html @@ -10,13 +10,13 @@ - + - + \ No newline at end of file diff --git a/styleguide/index.html b/styleguide/index.html index ccf6add7..fa664adf 100644 --- a/styleguide/index.html +++ b/styleguide/index.html @@ -10,7 +10,7 @@ - + @@ -23,7 +23,7 @@ need or want to. Also, feel free to open issues or pull requests with improvements to this guide.

    Use Taskfile.yml and not taskfile.yml

    # bad
    taskfile.yml


    # good
    Taskfile.yml

    This is important especially for Linux users. Windows and macOS have case insensitive filesystems, so taskfile.yml will end up working, even that not officially supported. On Linux, only Taskfile.yml will work, though.

    Use the correct order of keywords

    • version:
    • includes:
    • Configuration ones, like output:, silent:, method: and run:
    • vars:
    • env:, dotenv:
    • tasks:

    Use 2 spaces for indentation

    This is the most common convention for YAML files, and Task follows it.

    # bad
    tasks:
    foo:
    cmds:
    - echo 'foo'


    # good
    tasks:
    foo:
    cmds:
    - echo 'foo'

    Separate with spaces the mains sections

    # bad
    version: '3'
    includes:
    docker: ./docker/Taskfile.yml
    output: prefixed
    vars:
    FOO: bar
    env:
    BAR: baz
    tasks:
    # ...


    # good
    version: '3'

    includes:
    docker: ./docker/Taskfile.yml

    output: prefixed

    vars:
    FOO: bar

    env:
    BAR: baz

    tasks:
    # ...

    Add spaces between tasks

    # bad
    version: '3'

    tasks:
    foo:
    cmds:
    - echo 'foo'
    bar:
    cmds:
    - echo 'bar'
    baz:
    cmds:
    - echo 'baz'


    # good
    version: '3'

    tasks:
    foo:
    cmds:
    - echo 'foo'

    bar:
    cmds:
    - echo 'bar'

    baz:
    cmds:
    - echo 'baz'

    Use upper-case variable names

    # bad
    version: '3'

    vars:
    binary_name: myapp

    tasks:
    build:
    cmds:
    - go build -o {{.binary_name}} .


    # good
    version: '3'

    vars:
    BINARY_NAME: myapp

    tasks:
    build:
    cmds:
    - go build -o {{.BINARY_NAME}} .

    Don't wrap vars in spaces when templating

    # bad
    version: '3'

    tasks:
    greet:
    cmds:
    - echo '{{ .MESSAGE }}'


    # good
    version: '3'

    tasks:
    greet:
    cmds:
    - echo '{{.MESSAGE}}'

    This convention is also used by most people for any Go templating.

    Separate task name words with a dash

    # bad
    version: '3'

    tasks:
    do_something_fancy:
    cmds:
    - echo 'Do something'


    # good
    version: '3'

    tasks:
    do-something-fancy:
    cmds:
    - echo 'Do something'

    Use colon for task namespacing

    # good
    version: '3'

    tasks:
    docker:build:
    cmds:
    - docker ...

    docker:run:
    cmds:
    - docker-compose ...

    This is also done automatically when using included Taskfiles.

    - + \ No newline at end of file diff --git a/taskfile-versions/index.html b/taskfile-versions/index.html index c3cf9c0b..d3f8997b 100644 --- a/taskfile-versions/index.html +++ b/taskfile-versions/index.html @@ -10,7 +10,7 @@ - + @@ -21,24 +21,22 @@ version 2 means that Task v2.0.0 should be release to 2.0.0 is accepted. If you choose to use 2.0 Task will not enable future 2.1 features, but if you choose to use 2, then any 2.x.x features will be available, but not 3.0.0+.

    Version 1

    NOTE: Taskfiles in version 1 are not supported on Task >= v3.0.0 anymore.

    In the first version of the Taskfile, the version: key was not available, -because the tasks was in the root of the YAML document. Like this:

    echo:
    cmds:
    - echo "Hello, World!"

    The variable priority order was also different:

    1. Call variables
    2. Environment
    3. Task variables
    4. Taskvars.yml variables

    Version 2.0

    At version 2, we introduced the version: key, to allow us to evolve Task -with new features without breaking existing Taskfiles. The new syntax is as -follows:

    version: '2'

    tasks:
    echo:
    cmds:
    - echo "Hello, World!"

    Version 2 allows you to write global variables directly in the Taskfile, -if you don't want to create a Taskvars.yml:

    version: '2'

    vars:
    GREETING: Hello, World!

    tasks:
    greet:
    cmds:
    - echo "{{.GREETING}}"

    The variable priority order changed to the following:

    1. Task variables
    2. Call variables
    3. Taskfile variables
    4. Taskvars file variables
    5. Environment variables

    A new global option was added to configure the number of variables expansions -(which default to 2):

    version: '2'

    expansions: 3

    vars:
    FOO: foo
    BAR: bar
    BAZ: baz
    FOOBAR: "{{.FOO}}{{.BAR}}"
    FOOBARBAZ: "{{.FOOBAR}}{{.BAZ}}"

    tasks:
    default:
    cmds:
    - echo "{{.FOOBARBAZ}}"

    Version 2.1

    Version 2.1 includes a global output option, to allow having more control -over how commands output are printed to the console -(see documentation for more info):

    version: '2'

    output: prefixed

    tasks:
    server:
    cmds:
    - go run main.go
    prefix: server

    From this version it's also possible to ignore errors of a command or task -(check documentation here):

    version: '2'

    tasks:
    example-1:
    cmds:
    - cmd: exit 1
    ignore_error: true
    - echo "This will be print"

    example-2:
    cmds:
    - exit 1
    - echo "This will be print"
    ignore_error: true

    Version 2.2

    Version 2.2 comes with a global includes options to include other -Taskfiles:

    version: '2'

    includes:
    docs: ./documentation # will look for ./documentation/Taskfile.yml
    docker: ./DockerTasks.yml

    Version 2.6

    Version 2.6 comes with preconditions stanza in tasks.

    version: '2'

    tasks:
    upload_environment:
    preconditions:
    - test -f .env
    cmds:
    - aws s3 cp .env s3://myenvironment

    Please check the documentation

    Version 3

    These are some major changes done on v3:

    includes:
    docs:
    taskfile: ./docs
    dir: ./docs
    version: '3'

    tasks:
    print:
    cmds:
    - echo "Hello, World!"
    version: '3'

    tasks:
    print:
    - echo "Hello, World!"
    version: '3'

    tasks:
    print: echo "Hello, World!"
    + \ No newline at end of file diff --git a/translate/index.html b/translate/index.html index d1f898a4..3c870f9e 100644 --- a/translate/index.html +++ b/translate/index.html @@ -10,19 +10,18 @@ - +
    -
    Skip to main content

    Translate

    Want to help us translate this documentation? In this document we explain how.

    Do NOT edit translated markdown files directly on the GitHub repository! -We use Crowdin to allow contributors on work on translations. -The repository is periodically updated with progress from Crowdin.

    If you want to have access to the Crowdin project to be able to suggest -translations, please ask for access on the -#translations channel on our Discord server. -If a given language is not being shown to Crowdin yet, just ask and we can -configure it.

    - +
    Skip to main content

    Translate

    Want to help us translate this documentation? In this document we explain how.

    Do NOT edit translated markdown files directly on the GitHub repository! We use +Crowdin to allow contributors on work on translations. The repository +is periodically updated with progress from Crowdin.

    If you want to have access to the Crowdin project to be able to suggest +translations, please ask for access on the #translations channel on our Discord +server. If a given language is not being shown to Crowdin yet, just +ask and we can configure it.

    + \ No newline at end of file diff --git a/usage/index.html b/usage/index.html index a3d79ea0..b37091a5 100644 --- a/usage/index.html +++ b/usage/index.html @@ -10,18 +10,18 @@ - +
    -
    Skip to main content

    Usage

    Getting started

    Create a file called Taskfile.yml in the root of your project. -The cmds attribute should contain the commands of a task. -The example below allows compiling a Go app and uses esbuild to concat -and minify multiple CSS files into a single one.

    version: '3'

    tasks:
    build:
    cmds:
    - go build -v -i main.go

    assets:
    cmds:
    - esbuild --bundle --minify css/index.css > public/bundle.css

    Running the tasks is as simple as running:

    task assets build

    Task uses mvdan.cc/sh, a native Go sh -interpreter. So you can write sh/bash commands, and it will work even on -Windows, where sh or bash are usually not available. Just remember any -executable called must be available by the OS or in PATH.

    If you omit a task name, "default" will be assumed.

    Supported file names

    Task will look for the following file names, in order of priority:

    • Taskfile.yml
    • Taskfile.yaml
    • Taskfile.dist.yml
    • Taskfile.dist.yaml

    The intention of having the .dist variants is to allow projects to have one +

    Usage

    Getting started

    Create a file called Taskfile.yml in the root of your project. The cmds +attribute should contain the commands of a task. The example below allows +compiling a Go app and uses esbuild to concat and +minify multiple CSS files into a single one.

    version: '3'

    tasks:
    build:
    cmds:
    - go build -v -i main.go

    assets:
    cmds:
    - esbuild --bundle --minify css/index.css > public/bundle.css

    Running the tasks is as simple as running:

    task assets build

    Task uses mvdan.cc/sh, a native Go sh interpreter. So +you can write sh/bash commands, and it will work even on Windows, where sh or +bash are usually not available. Just remember any executable called must be +available by the OS or in PATH.

    If you omit a task name, "default" will be assumed.

    Supported file names

    Task will look for the following file names, in order of priority:

    • Taskfile.yml
    • Taskfile.yaml
    • Taskfile.dist.yml
    • Taskfile.dist.yaml

    The intention of having the .dist variants is to allow projects to have one committed version (.dist) while still allowing individual users to override the Taskfile by adding an additional Taskfile.yml (which would be on .gitignore).

    Running a Taskfile from a subdirectory

    If a Taskfile cannot be found in the current working directory, it will walk up @@ -32,38 +32,40 @@ variable to create some very useful reusable tasks. For example, if you have a monorepo with directories for each microservice, you can cd into a microservice directory and run a task command to bring it up without having to create multiple tasks or Taskfiles with identical content. For example:

    version: '3'

    tasks:
    up:
    dir: '{{.USER_WORKING_DIR}}'
    preconditions:
    - test -f docker-compose.yml
    cmds:
    - docker-compose up -d

    In this example, we can run cd <service> and task up and as long as the -<service> directory contains a docker-compose.yml, the Docker composition will be -brought up.

    Running a global Taskfile

    If you call Task with the --global (alias -g) flag, it will look for your -home directory instead of your working directory. In short, Task will look for -a Taskfile on either $HOME/Taskfile.yml or $HOME/Taskfile.yaml paths.

    This is useful to have automation that you can run from anywhere in your -system!

    info

    When running your global Taskfile with -g, tasks will run on $HOME by +<service> directory contains a docker-compose.yml, the Docker composition +will be brought up.

    Running a global Taskfile

    If you call Task with the --global (alias -g) flag, it will look for your +home directory instead of your working directory. In short, Task will look for a +Taskfile on either $HOME/Taskfile.yml or $HOME/Taskfile.yaml paths.

    This is useful to have automation that you can run from anywhere in your system!

    info

    When running your global Taskfile with -g, tasks will run on $HOME by default, and not on your working directory!

    As mentioned in the previous section, the {{.USER_WORKING_DIR}} special variable can be very handy here to run stuff on the directory you're calling -task -g from.

    version: '3'

    tasks:
    from-home:
    cmds:
    - pwd

    from-working-directory:
    dir: '{{.USER_WORKING_DIR}}'
    cmds:
    - pwd

    Environment variables

    Task

    You can use env to set custom environment variables for a specific task:

    version: '3'

    tasks:
    greet:
    cmds:
    - echo $GREETING
    env:
    GREETING: Hey, there!

    Additionally, you can set global environment variables that will be available -to all tasks:

    version: '3'

    env:
    GREETING: Hey, there!

    tasks:
    greet:
    cmds:
    - echo $GREETING
    info

    env supports expansion and retrieving output from a shell command -just like variables, as you can see in the Variables section.

    .env files

    You can also ask Task to include .env like files by using the dotenv: +task -g from.

    version: '3'

    tasks:
    from-home:
    cmds:
    - pwd

    from-working-directory:
    dir: '{{.USER_WORKING_DIR}}'
    cmds:
    - pwd

    Environment variables

    Task

    You can use env to set custom environment variables for a specific task:

    version: '3'

    tasks:
    greet:
    cmds:
    - echo $GREETING
    env:
    GREETING: Hey, there!

    Additionally, you can set global environment variables that will be available to +all tasks:

    version: '3'

    env:
    GREETING: Hey, there!

    tasks:
    greet:
    cmds:
    - echo $GREETING
    info

    env supports expansion and retrieving output from a shell command just like +variables, as you can see in the Variables section.

    .env files

    You can also ask Task to include .env like files by using the dotenv: setting:

    .env
    KEYNAME=VALUE
    testing/.env
    ENDPOINT=testing.com
    Taskfile.yml
    version: '3'

    env:
    ENV: testing

    dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']

    tasks:
    greet:
    cmds:
    - echo "Using $KEYNAME and endpoint $ENDPOINT"

    Dotenv files can also be specified at the task level:

    version: '3'

    env:
    ENV: testing

    tasks:
    greet:
    dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']
    cmds:
    - echo "Using $KEYNAME and endpoint $ENDPOINT"

    Environment variables specified explicitly at the task-level will override -variables defined in dotfiles:

    version: '3'

    env:
    ENV: testing

    tasks:
    greet:
    dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']
    env:
    KEYNAME: DIFFERENT_VALUE
    cmds:
    - echo "Using $KEYNAME and endpoint $ENDPOINT"
    info

    Please note that you are not currently able to use the dotenv key inside included Taskfiles.

    Including other Taskfiles

    If you want to share tasks between different projects (Taskfiles), you can use +variables defined in dotfiles:

    version: '3'

    env:
    ENV: testing

    tasks:
    greet:
    dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']
    env:
    KEYNAME: DIFFERENT_VALUE
    cmds:
    - echo "Using $KEYNAME and endpoint $ENDPOINT"
    info

    Please note that you are not currently able to use the dotenv key inside +included Taskfiles.

    Including other Taskfiles

    If you want to share tasks between different projects (Taskfiles), you can use the importing mechanism to include other Taskfiles using the includes keyword:

    version: '3'

    includes:
    docs: ./documentation # will look for ./documentation/Taskfile.yml
    docker: ./DockerTasks.yml

    The tasks described in the given Taskfiles will be available with the informed namespace. So, you'd call task docs:serve to run the serve task from -documentation/Taskfile.yml or task docker:build to run the build task -from the DockerTasks.yml file.

    Relative paths are resolved relative to the directory containing the including Taskfile.

    OS-specific Taskfiles

    With version: '2', task automatically includes any Taskfile_{{OS}}.yml -if it exists (for example: Taskfile_windows.yml, Taskfile_linux.yml or -Taskfile_darwin.yml). Since this behavior was a bit too implicit, it -was removed on version 3, but you still can have a similar behavior by -explicitly importing these files:

    version: '3'

    includes:
    build: ./Taskfile_{{OS}}.yml

    Directory of included Taskfile

    By default, included Taskfile's tasks are run in the current directory, even -if the Taskfile is in another directory, but you can force its tasks to run -in another directory by using this alternative syntax:

    version: '3'

    includes:
    docs:
    taskfile: ./docs/Taskfile.yml
    dir: ./docs
    info

    The included Taskfiles must be using the same schema version as the main +documentation/Taskfile.yml or task docker:build to run the build task from +the DockerTasks.yml file.

    Relative paths are resolved relative to the directory containing the including +Taskfile.

    OS-specific Taskfiles

    With version: '2', task automatically includes any Taskfile_{{OS}}.yml if it +exists (for example: Taskfile_windows.yml, Taskfile_linux.yml or +Taskfile_darwin.yml). Since this behavior was a bit too implicit, it was +removed on version 3, but you still can have a similar behavior by explicitly +importing these files:

    version: '3'

    includes:
    build: ./Taskfile_{{OS}}.yml

    Directory of included Taskfile

    By default, included Taskfile's tasks are run in the current directory, even if +the Taskfile is in another directory, but you can force its tasks to run in +another directory by using this alternative syntax:

    version: '3'

    includes:
    docs:
    taskfile: ./docs/Taskfile.yml
    dir: ./docs
    info

    The included Taskfiles must be using the same schema version as the main Taskfile uses.

    Optional includes

    Includes marked as optional will allow Task to continue execution as normal if -the included file is missing.

    version: '3'

    includes:
    tests:
    taskfile: ./tests/Taskfile.yml
    optional: true

    tasks:
    greet:
    cmds:
    - echo "This command can still be successfully executed if ./tests/Taskfile.yml does not exist"

    Internal includes

    Includes marked as internal will set all the tasks of the included file to be -internal as well (see the Internal tasks section below). -This is useful when including utility tasks that are not intended to be used -directly by the user.

    version: '3'

    includes:
    tests:
    taskfile: ./taskfiles/Utils.yml
    internal: true

    Vars of included Taskfiles

    You can also specify variables when including a Taskfile. This may be useful -for having reusable Taskfile that can be tweaked or even included more than once:

    version: '3'

    includes:
    backend:
    taskfile: ./taskfiles/Docker.yml
    vars:
    DOCKER_IMAGE: backend_image

    frontend:
    taskfile: ./taskfiles/Docker.yml
    vars:
    DOCKER_IMAGE: frontend_image

    Namespace aliases

    When including a Taskfile, you can give the namespace a list of aliases. -This works in the same way as task aliases and can be used -together to create shorter and easier-to-type commands.

    version: '3'

    includes:
    generate:
    taskfile: ./taskfiles/Generate.yml
    aliases: [gen]
    info

    Vars declared in the included Taskfile have preference over the -variables in the including Taskfile! If you want a variable in an included Taskfile to be overridable, -use the default function: +the included file is missing.

    version: '3'

    includes:
    tests:
    taskfile: ./tests/Taskfile.yml
    optional: true

    tasks:
    greet:
    cmds:
    - echo "This command can still be successfully executed if
    ./tests/Taskfile.yml does not exist"

    Internal includes

    Includes marked as internal will set all the tasks of the included file to be +internal as well (see the Internal tasks section below). This +is useful when including utility tasks that are not intended to be used directly +by the user.

    version: '3'

    includes:
    tests:
    taskfile: ./taskfiles/Utils.yml
    internal: true

    Vars of included Taskfiles

    You can also specify variables when including a Taskfile. This may be useful for +having reusable Taskfile that can be tweaked or even included more than once:

    version: '3'

    includes:
    backend:
    taskfile: ./taskfiles/Docker.yml
    vars:
    DOCKER_IMAGE: backend_image

    frontend:
    taskfile: ./taskfiles/Docker.yml
    vars:
    DOCKER_IMAGE: frontend_image

    Namespace aliases

    When including a Taskfile, you can give the namespace a list of aliases. This +works in the same way as task aliases and can be used together +to create shorter and easier-to-type commands.

    version: '3'

    includes:
    generate:
    taskfile: ./taskfiles/Generate.yml
    aliases: [gen]
    info

    Vars declared in the included Taskfile have preference over the variables in the +including Taskfile! If you want a variable in an included Taskfile to be +overridable, use the +default function: MY_VAR: '{{.MY_VAR | default "my-default-value"}}'.

    Internal tasks

    Internal tasks are tasks that cannot be called directly by the user. They will not appear in the output when running task --list|--list-all. Other tasks may call internal tasks in the usual way. This is useful for creating reusable, @@ -71,140 +73,147 @@ function-like tasks that have no useful purpose on the command line.

    dir:

    version: '3'

    tasks:
    serve:
    dir: public/www
    cmds:
    # run http server
    - caddy

    If the directory does not exist, task creates it.

    Task dependencies

    Dependencies run in parallel, so dependencies of a task should not depend one another. If you want to force tasks to run serially, take a look at the -Calling Another Task section below.

    You may have tasks that depend on others. Just pointing them on deps will -make them run automatically before running the parent task:

    version: '3'

    tasks:
    build:
    deps: [assets]
    cmds:
    - go build -v -i main.go

    assets:
    cmds:
    - esbuild --bundle --minify css/index.css > public/bundle.css

    In the above example, assets will always run right before build if you run +Calling Another Task section below.

    You may have tasks that depend on others. Just pointing them on deps will make +them run automatically before running the parent task:

    version: '3'

    tasks:
    build:
    deps: [assets]
    cmds:
    - go build -v -i main.go

    assets:
    cmds:
    - esbuild --bundle --minify css/index.css > public/bundle.css

    In the above example, assets will always run right before build if you run task build.

    A task can have only dependencies and no commands to group tasks together:

    version: '3'

    tasks:
    assets:
    deps: [js, css]

    js:
    cmds:
    - esbuild --bundle --minify js/index.js > public/bundle.js

    css:
    cmds:
    - esbuild --bundle --minify css/index.css > public/bundle.css

    If there is more than one dependency, they always run in parallel for better -performance.

    tip

    You can also make the tasks given by the command line run in parallel by -using the --parallel flag (alias -p). Example: task --parallel js css.

    If you want to pass information to dependencies, you can do that the same -manner as you would to call another task:

    version: '3'

    tasks:
    default:
    deps:
    - task: echo_sth
    vars: {TEXT: "before 1"}
    - task: echo_sth
    vars: {TEXT: "before 2"}
    cmds:
    - echo "after"

    echo_sth:
    cmds:
    - echo {{.TEXT}}

    Platform specific tasks and commands

    If you want to restrict the running of tasks to explicit platforms, this can be achieved -using the platforms: key. Tasks can be restricted to a specific OS, architecture or a -combination of both. -On a mismatch, the task or command will be skipped, and no error will be thrown.

    The values allowed as OS or Arch are valid GOOS and GOARCH values, as +performance.

    tip

    You can also make the tasks given by the command line run in parallel by using +the --parallel flag (alias -p). Example: task --parallel js css.

    If you want to pass information to dependencies, you can do that the same manner +as you would to call another task:

    version: '3'

    tasks:
    default:
    deps:
    - task: echo_sth
    vars: { TEXT: 'before 1' }
    - task: echo_sth
    vars: { TEXT: 'before 2' }
    cmds:
    - echo "after"

    echo_sth:
    cmds:
    - echo {{.TEXT}}

    Platform specific tasks and commands

    If you want to restrict the running of tasks to explicit platforms, this can be +achieved using the platforms: key. Tasks can be restricted to a specific OS, +architecture or a combination of both. On a mismatch, the task or command will +be skipped, and no error will be thrown.

    The values allowed as OS or Arch are valid GOOS and GOARCH values, as defined by the Go language -here.

    The build-windows task below will run only on Windows, and on any architecture:

    version: '3'

    tasks:
    build-windows:
    platforms: [windows]
    cmds:
    - echo 'Running command on Windows'

    This can be restricted to a specific architecture as follows:

    version: '3'

    tasks:
    build-windows-amd64:
    platforms: [windows/amd64]
    cmds:
    - echo 'Running command on Windows (amd64)'

    It is also possible to restrict the task to specific architectures:

    version: '3'

    tasks:
    build-amd64:
    platforms: [amd64]
    cmds:
    - echo 'Running command on amd64'

    Multiple platforms can be specified as follows:

    version: '3'

    tasks:
    build:
    platforms: [windows/amd64, darwin]
    cmds:
    - echo 'Running command on Windows (amd64) and macOS'

    Individual commands can also be restricted to specific platforms:

    version: '3'

    tasks:
    build:
    cmds:
    - cmd: echo 'Running command on Windows (amd64) and macOS'
    platforms: [windows/amd64, darwin]
    - cmd: echo 'Running on all platforms'

    Calling another task

    When a task has many dependencies, they are executed concurrently. This will -often result in a faster build pipeline. However, in some situations, you may need -to call other tasks serially. In this case, use the following syntax:

    version: '3'

    tasks:
    main-task:
    cmds:
    - task: task-to-be-called
    - task: another-task
    - echo "Both done"

    task-to-be-called:
    cmds:
    - echo "Task to be called"

    another-task:
    cmds:
    - echo "Another task"

    Overriding variables in the called task is as simple as informing vars -attribute:

    version: '3'

    tasks:
    greet:
    vars:
    RECIPIENT: '{{default "World" .RECIPIENT}}'
    cmds:
    - echo "Hello, {{.RECIPIENT}}!"

    greet-pessimistically:
    cmds:
    - task: greet
    vars: {RECIPIENT: "Cruel World"}

    The above syntax is also supported in deps.

    tip

    NOTE: If you want to call a task declared in the root Taskfile from within an +here.

    The build-windows task below will run only on Windows, and on any +architecture:

    version: '3'

    tasks:
    build-windows:
    platforms: [windows]
    cmds:
    - echo 'Running command on Windows'

    This can be restricted to a specific architecture as follows:

    version: '3'

    tasks:
    build-windows-amd64:
    platforms: [windows/amd64]
    cmds:
    - echo 'Running command on Windows (amd64)'

    It is also possible to restrict the task to specific architectures:

    version: '3'

    tasks:
    build-amd64:
    platforms: [amd64]
    cmds:
    - echo 'Running command on amd64'

    Multiple platforms can be specified as follows:

    version: '3'

    tasks:
    build:
    platforms: [windows/amd64, darwin]
    cmds:
    - echo 'Running command on Windows (amd64) and macOS'

    Individual commands can also be restricted to specific platforms:

    version: '3'

    tasks:
    build:
    cmds:
    - cmd: echo 'Running command on Windows (amd64) and macOS'
    platforms: [windows/amd64, darwin]
    - cmd: echo 'Running on all platforms'

    Calling another task

    When a task has many dependencies, they are executed concurrently. This will +often result in a faster build pipeline. However, in some situations, you may +need to call other tasks serially. In this case, use the following syntax:

    version: '3'

    tasks:
    main-task:
    cmds:
    - task: task-to-be-called
    - task: another-task
    - echo "Both done"

    task-to-be-called:
    cmds:
    - echo "Task to be called"

    another-task:
    cmds:
    - echo "Another task"

    Overriding variables in the called task is as simple as informing vars +attribute:

    version: '3'

    tasks:
    greet:
    vars:
    RECIPIENT: '{{default "World" .RECIPIENT}}'
    cmds:
    - echo "Hello, {{.RECIPIENT}}!"

    greet-pessimistically:
    cmds:
    - task: greet
    vars: { RECIPIENT: 'Cruel World' }

    The above syntax is also supported in deps.

    tip

    NOTE: If you want to call a task declared in the root Taskfile from within an included Taskfile, add a leading : like this: task: :task-name.

    Prevent unnecessary work

    By fingerprinting locally generated files and their sources

    If a task generates something, you can inform Task the source and generated -files, so Task will prevent running them if not necessary.

    version: '3'

    tasks:
    build:
    deps: [js, css]
    cmds:
    - go build -v -i main.go

    js:
    cmds:
    - esbuild --bundle --minify js/index.js > public/bundle.js
    sources:
    - src/js/**/*.js
    generates:
    - public/bundle.js

    css:
    cmds:
    - esbuild --bundle --minify css/index.css > public/bundle.css
    sources:
    - src/css/**/*.css
    generates:
    - public/bundle.css

    sources and generates can be files or file patterns. When given, -Task will compare the checksum of the source files to determine if it's -necessary to run the task. If not, it will just print a message like -Task "js" is up to date.

    If you prefer this check to be made by the modification timestamp of the files, -instead of its checksum (content), just set the method property to timestamp.

    version: '3'

    tasks:
    build:
    cmds:
    - go build .
    sources:
    - ./*.go
    generates:
    - app{{exeExt}}
    method: timestamp

    In situations where you need more flexibility the status keyword can be used. +files, so Task will prevent running them if not necessary.

    version: '3'

    tasks:
    build:
    deps: [js, css]
    cmds:
    - go build -v -i main.go

    js:
    cmds:
    - esbuild --bundle --minify js/index.js > public/bundle.js
    sources:
    - src/js/**/*.js
    generates:
    - public/bundle.js

    css:
    cmds:
    - esbuild --bundle --minify css/index.css > public/bundle.css
    sources:
    - src/css/**/*.css
    generates:
    - public/bundle.css

    sources and generates can be files or file patterns. When given, Task will +compare the checksum of the source files to determine if it's necessary to run +the task. If not, it will just print a message like Task "js" is up to date.

    If you prefer this check to be made by the modification timestamp of the files, +instead of its checksum (content), just set the method property to +timestamp.

    version: '3'

    tasks:
    build:
    cmds:
    - go build .
    sources:
    - ./*.go
    generates:
    - app{{exeExt}}
    method: timestamp

    In situations where you need more flexibility the status keyword can be used. You can even combine the two. See the documentation for status for an example.

    info

    By default, task stores checksums on a local .task directory in the project's directory. Most of the time, you'll want to have this directory on .gitignore (or equivalent) so it isn't committed. (If you have a task for code generation -that is committed it may make sense to commit the checksum of that task as -well, though).

    If you want these files to be stored in another directory, you can set a +that is committed it may make sense to commit the checksum of that task as well, +though).

    If you want these files to be stored in another directory, you can set a TASK_TEMP_DIR environment variable in your machine. It can contain a relative path like tmp/task that will be interpreted as relative to the project directory, or an absolute or home path like /tmp/.task or ~/.task -(subdirectories will be created for each project).

    export TASK_TEMP_DIR='~/.task'
    info

    Each task has only one checksum stored for its sources. If you want -to distinguish a task by any of its input variables, you can add those -variables as part of the task's label, and it will be considered a different -task.

    This is useful if you want to run a task once for each distinct set of -inputs until the sources actually change. For example, if the sources depend -on the value of a variable, or you if you want the task to rerun if some arguments -change even if the source has not.

    tip

    The method none skips any validation and always run the task.

    info

    For the checksum (default) or timestamp method to work, it is only necessary to -inform the source files. -When the timestamp method is used, the last time of the running the task is considered as a generate.

    Using programmatic checks to indicate a task is up to date

    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:

    version: '3'

    tasks:
    generate-files:
    cmds:
    - mkdir directory
    - touch directory/file1.txt
    - touch directory/file2.txt
    # test existence of files
    status:
    - test -d directory
    - test -f directory/file1.txt
    - test -f directory/file2.txt

    Normally, you would use sources in combination with -generates - but for tasks that generate remote artifacts (Docker images, -deploys, CD releases) the checksum source and timestamps require either -access to the artifact or for an out-of-band refresh of the .checksum -fingerprint file.

    Two special variables {{.CHECKSUM}} and {{.TIMESTAMP}} are available -for interpolation within status commands, depending on the method assigned -to fingerprint the sources. Only source globs are fingerprinted.

    Note that the {{.TIMESTAMP}} variable is a "live" Go time.Time struct, and -can be formatted using any of the methods that time.Time responds to.

    See the Go Time documentation for more information.

    You can use --force or -f if you want to force a task to run even when +(subdirectories will be created for each project).

    export TASK_TEMP_DIR='~/.task'
    info

    Each task has only one checksum stored for its sources. If you want to +distinguish a task by any of its input variables, you can add those variables as +part of the task's label, and it will be considered a different task.

    This is useful if you want to run a task once for each distinct set of inputs +until the sources actually change. For example, if the sources depend on the +value of a variable, or you if you want the task to rerun if some arguments +change even if the source has not.

    tip

    The method none skips any validation and always run the task.

    info

    For the checksum (default) or timestamp method to work, it is only necessary +to inform the source files. When the timestamp method is used, the last time +of the running the task is considered as a generate.

    Using programmatic checks to indicate a task is up to date

    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:

    version: '3'

    tasks:
    generate-files:
    cmds:
    - mkdir directory
    - touch directory/file1.txt
    - touch directory/file2.txt
    # test existence of files
    status:
    - test -d directory
    - test -f directory/file1.txt
    - test -f directory/file2.txt

    Normally, you would use sources in combination with generates - but for +tasks that generate remote artifacts (Docker images, deploys, CD releases) the +checksum source and timestamps require either access to the artifact or for an +out-of-band refresh of the .checksum fingerprint file.

    Two special variables {{.CHECKSUM}} and {{.TIMESTAMP}} are available for +interpolation within status commands, depending on the method assigned to +fingerprint the sources. Only source globs are fingerprinted.

    Note that the {{.TIMESTAMP}} variable is a "live" Go time.Time struct, and +can be formatted using any of the methods that time.Time responds to.

    See the Go Time documentation for more +information.

    You can use --force or -f if you want to force a task to run even when up-to-date.

    Also, task --status [tasks]... will exit with a non-zero exit code if any of -the tasks are not up-to-date.

    status can be combined with the fingerprinting +the tasks are not up-to-date.

    status can be combined with the +fingerprinting to have a task run if either the the source/generated artifacts changes, or the -programmatic check fails:

    version: '3'

    tasks:
    build:prod:
    desc: Build for production usage.
    cmds:
    - composer install
    # Run this task if source files changes.
    sources:
    - composer.json
    - composer.lock
    generates:
    - ./vendor/composer/installed.json
    - ./vendor/autoload.php
    # But also run the task if the last build was not a production build.
    status:
    - grep -q '"dev": false' ./vendor/composer/installed.json

    Using programmatic checks to cancel the execution of a task and its dependencies

    In addition to status checks, preconditions checks 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.

    version: '3'

    tasks:
    generate-files:
    cmds:
    - mkdir directory
    - touch directory/file1.txt
    - touch directory/file2.txt
    # test existence of files
    preconditions:
    - test -f .env
    - sh: "[ 1 = 0 ]"
    msg: "One doesn't equal Zero, Halting"

    Preconditions can set specific failure messages that can tell -a user what steps to take using the msg field.

    If a task has a dependency on a sub-task with a precondition, and that -precondition is not met - the calling task will fail. Note that a task -executed with a failing precondition will not run unless --force is -given.

    Unlike status, which will skip a task if it is up to date and continue -executing tasks that depend on it, a precondition will fail a task, along -with any other tasks that depend on it.

    version: '3'

    tasks:
    task-will-fail:
    preconditions:
    - sh: "exit 1"

    task-will-also-fail:
    deps:
    - task-will-fail

    task-will-still-fail:
    cmds:
    - task: task-will-fail
    - echo "I will not run"

    Limiting when tasks run

    If a task executed by multiple cmds or multiple deps you can control -when it is executed using run. run can also be set at the root -of the Taskfile to change the behavior of all the tasks unless explicitly -overridden.

    Supported values for run:

    • always (default) always attempt to invoke the task regardless of the -number of previous executions
    • once only invoke this task once regardless of the number of references
    • when_changed only invokes the task once for each unique set of variables -passed into the task
    version: '3'

    tasks:
    default:
    cmds:
    - task: generate-file
    vars: { CONTENT: '1' }
    - task: generate-file
    vars: { CONTENT: '2' }
    - task: generate-file
    vars: { CONTENT: '2' }

    generate-file:
    run: when_changed
    deps:
    - install-deps
    cmds:
    - echo {{.CONTENT}}

    install-deps:
    run: once
    cmds:
    - sleep 5 # long operation like installing packages

    Variables

    When doing interpolation of variables, Task will look for the below. -They are listed below in order of importance (i.e. most important first):

    • Variables declared in the task definition
    • Variables given while calling a task from another -(See Calling another task above)
    • Variables of the included Taskfile (when the task is included)
    • Variables of the inclusion of the Taskfile (when the task is included)
    • Global variables (those declared in the vars: option in the Taskfile)
    • Environment variables

    Example of sending parameters with environment variables:

    $ TASK_VARIABLE=a-value task do-something
    tip

    A special variable .TASK is always available containing the task name.

    Since some shells do not support the above syntax to set environment variables -(Windows) tasks also accept a similar style when not at the beginning of -the command.

    $ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!"

    Example of locally declared vars:

    version: '3'

    tasks:
    print-var:
    cmds:
    - echo "{{.VAR}}"
    vars:
    VAR: Hello!

    Example of global vars in a Taskfile.yml:

    version: '3'

    vars:
    GREETING: Hello from Taskfile!

    tasks:
    greet:
    cmds:
    - echo "{{.GREETING}}"

    Dynamic variables

    The below syntax (sh: prop in a variable) is considered a dynamic variable. +programmatic check fails:

    version: '3'

    tasks:
    build:prod:
    desc: Build for production usage.
    cmds:
    - composer install
    # Run this task if source files changes.
    sources:
    - composer.json
    - composer.lock
    generates:
    - ./vendor/composer/installed.json
    - ./vendor/autoload.php
    # But also run the task if the last build was not a production build.
    status:
    - grep -q '"dev": false' ./vendor/composer/installed.json

    Using programmatic checks to cancel the execution of a task and its dependencies

    In addition to status checks, preconditions checks 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.

    version: '3'

    tasks:
    generate-files:
    cmds:
    - mkdir directory
    - touch directory/file1.txt
    - touch directory/file2.txt
    # test existence of files
    preconditions:
    - test -f .env
    - sh: '[ 1 = 0 ]'
    msg: "One doesn't equal Zero, Halting"

    Preconditions can set specific failure messages that can tell a user what steps +to take using the msg field.

    If a task has a dependency on a sub-task with a precondition, and that +precondition is not met - the calling task will fail. Note that a task executed +with a failing precondition will not run unless --force is given.

    Unlike status, which will skip a task if it is up to date and continue +executing tasks that depend on it, a precondition will fail a task, along with +any other tasks that depend on it.

    version: '3'

    tasks:
    task-will-fail:
    preconditions:
    - sh: 'exit 1'

    task-will-also-fail:
    deps:
    - task-will-fail

    task-will-still-fail:
    cmds:
    - task: task-will-fail
    - echo "I will not run"

    Limiting when tasks run

    If a task executed by multiple cmds or multiple deps you can control when it +is executed using run. run can also be set at the root of the Taskfile to +change the behavior of all the tasks unless explicitly overridden.

    Supported values for run:

    • always (default) always attempt to invoke the task regardless of the number +of previous executions
    • once only invoke this task once regardless of the number of references
    • when_changed only invokes the task once for each unique set of variables +passed into the task
    version: '3'

    tasks:
    default:
    cmds:
    - task: generate-file
    vars: { CONTENT: '1' }
    - task: generate-file
    vars: { CONTENT: '2' }
    - task: generate-file
    vars: { CONTENT: '2' }

    generate-file:
    run: when_changed
    deps:
    - install-deps
    cmds:
    - echo {{.CONTENT}}

    install-deps:
    run: once
    cmds:
    - sleep 5 # long operation like installing packages

    Variables

    When doing interpolation of variables, Task will look for the below. They are +listed below in order of importance (i.e. most important first):

    • Variables declared in the task definition
    • Variables given while calling a task from another (See +Calling another task above)
    • Variables of the included Taskfile (when the +task is included)
    • Variables of the inclusion of the Taskfile +(when the task is included)
    • Global variables (those declared in the vars: option in the Taskfile)
    • Environment variables

    Example of sending parameters with environment variables:

    $ TASK_VARIABLE=a-value task do-something
    tip

    A special variable .TASK is always available containing the task name.

    Since some shells do not support the above syntax to set environment variables +(Windows) tasks also accept a similar style when not at the beginning of the +command.

    $ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!"

    Example of locally declared vars:

    version: '3'

    tasks:
    print-var:
    cmds:
    - echo "{{.VAR}}"
    vars:
    VAR: Hello!

    Example of global vars in a Taskfile.yml:

    version: '3'

    vars:
    GREETING: Hello from Taskfile!

    tasks:
    greet:
    cmds:
    - echo "{{.GREETING}}"

    Dynamic variables

    The below syntax (sh: prop in a variable) is considered a dynamic variable. The value will be treated as a command and the output assigned. If there are one -or more trailing newlines, the last newline will be trimmed.

    version: '3'

    tasks:
    build:
    cmds:
    - go build -ldflags="-X main.Version={{.GIT_COMMIT}}" main.go
    vars:
    GIT_COMMIT:
    sh: git log -n 1 --format=%h

    This works for all types of variables.

    Forwarding CLI arguments to commands

    If -- is given in the CLI, all following parameters are added to a -special .CLI_ARGS variable. This is useful to forward arguments to another -command.

    The below example will run yarn install.

    $ task yarn -- install
    version: '3'

    tasks:
    yarn:
    cmds:
    - yarn {{.CLI_ARGS}}

    Doing task cleanup with defer

    With the defer keyword, it's possible to schedule cleanup to be run once -the task finishes. The difference with just putting it as the last command is -that this command will run even when the task fails.

    In the example below, rm -rf tmpdir/ will run even if the third command fails:

    version: '3'

    tasks:
    default:
    cmds:
    - mkdir -p tmpdir/
    - defer: rm -rf tmpdir/
    - echo 'Do work on tmpdir/'

    If you want to move the cleanup command into another task, that is possible as +or more trailing newlines, the last newline will be trimmed.

    version: '3'

    tasks:
    build:
    cmds:
    - go build -ldflags="-X main.Version={{.GIT_COMMIT}}" main.go
    vars:
    GIT_COMMIT:
    sh: git log -n 1 --format=%h

    This works for all types of variables.

    Forwarding CLI arguments to commands

    If -- is given in the CLI, all following parameters are added to a special +.CLI_ARGS variable. This is useful to forward arguments to another command.

    The below example will run yarn install.

    $ task yarn -- install
    version: '3'

    tasks:
    yarn:
    cmds:
    - yarn {{.CLI_ARGS}}

    Doing task cleanup with defer

    With the defer keyword, it's possible to schedule cleanup to be run once the +task finishes. The difference with just putting it as the last command is that +this command will run even when the task fails.

    In the example below, rm -rf tmpdir/ will run even if the third command fails:

    version: '3'

    tasks:
    default:
    cmds:
    - mkdir -p tmpdir/
    - defer: rm -rf tmpdir/
    - echo 'Do work on tmpdir/'

    If you want to move the cleanup command into another task, that is possible as well:

    version: '3'

    tasks:
    default:
    cmds:
    - mkdir -p tmpdir/
    - defer: { task: cleanup }
    - echo 'Do work on tmpdir/'

    cleanup: rm -rf tmpdir/
    info

    Due to the nature of how the Go's own defer work, the deferred -commands are executed in the reverse order if you schedule multiple of them.

    Go's template engine

    Task parse commands as Go's template engine before executing -them. Variables are accessible through dot syntax (.VARNAME).

    All functions by the Go's slim-sprig lib -are available. The following example gets the current date in a given format:

    version: '3'

    tasks:
    print-date:
    cmds:
    - echo {{now | date "2006-01-02"}}

    Task also adds the following functions:

    • OS: Returns the operating system. Possible values are "windows", "linux", -"darwin" (macOS) and "freebsd".
    • ARCH: return the architecture Task was compiled to: "386", "amd64", "arm" -or "s390x".
    • splitLines: Splits Unix (\n) and Windows (\r\n) styled newlines.
    • catLines: Replaces Unix (\n) and Windows (\r\n) styled newlines with a space.
    • toSlash: Does nothing on Unix, but on Windows converts a string from \ +commands are executed in the reverse order if you schedule multiple of them.

    Go's template engine

    Task parse commands as Go's template engine before executing them. +Variables are accessible through dot syntax (.VARNAME).

    All functions by the Go's +slim-sprig lib are available. The +following example gets the current date in a given format:

    version: '3'

    tasks:
    print-date:
    cmds:
    - echo {{now | date "2006-01-02"}}

    Task also adds the following functions:

    • OS: Returns the operating system. Possible values are "windows", "linux", +"darwin" (macOS) and "freebsd".
    • ARCH: return the architecture Task was compiled to: "386", "amd64", "arm" or +"s390x".
    • splitLines: Splits Unix (\n) and Windows (\r\n) styled newlines.
    • catLines: Replaces Unix (\n) and Windows (\r\n) styled newlines with a +space.
    • toSlash: Does nothing on Unix, but on Windows converts a string from \ path format to /.
    • fromSlash: Opposite of toSlash. Does nothing on Unix, but on Windows -converts a string from / path format to \.
    • exeExt: Returns the right executable extension for the current OS -(".exe" for Windows, "" for others).
    • shellQuote: Quotes a string to make it safe for use in shell scripts. -Task uses this Go function -for this. The Bash dialect is assumed.
    • splitArgs: Splits a string as if it were a command's arguments. -Task uses this Go function

    Example:

    version: '3'

    tasks:
    print-os:
    cmds:
    - echo '{{OS}} {{ARCH}}'
    - echo '{{if eq OS "windows"}}windows-command{{else}}unix-command{{end}}'
    # This will be path/to/file on Unix but path\to\file on Windows
    - echo '{{fromSlash "path/to/file"}}'
    enumerated-file:
    vars:
    CONTENT: |
    foo
    bar
    cmds:
    - |
    cat << EOF > output.txt
    {{range $i, $line := .CONTENT | splitLines -}}
    {{printf "%3d" $i}}: {{$line}}
    {{end}}EOF

    Help

    Running task --list (or task -l) lists all tasks with a description. -The following Taskfile:

    version: '3'

    tasks:
    build:
    desc: Build the go binary.
    cmds:
    - go build -v -i main.go

    test:
    desc: Run all the go tests.
    cmds:
    - go test -race ./...

    js:
    cmds:
    - esbuild --bundle --minify js/index.js > public/bundle.js

    css:
    cmds:
    - esbuild --bundle --minify css/index.css > public/bundle.css

    would print the following output:

    * build:   Build the go binary.
    * test: Run all the go tests.

    If you want to see all tasks, there's a --list-all (alias -a) flag as well.

    Display summary of task

    Running task --summary task-name will show a summary of a task. -The following Taskfile:

    version: '3'

    tasks:
    release:
    deps: [build]
    summary: |
    Release your project to github

    It will build your project before starting the release.
    Please make sure that you have set GITHUB_TOKEN before starting.
    cmds:
    - your-release-tool

    build:
    cmds:
    - your-build-tool

    with running task --summary release would print the following output:

    task: release

    Release your project to github

    It will build your project before starting the release.
    Please make sure that you have set GITHUB_TOKEN before starting.

    dependencies:
    - build

    commands:
    - your-release-tool

    If a summary is missing, the description will be printed. -If the task does not have a summary or a description, a warning is printed.

    Please note: showing the summary will not execute the command.

    Task aliases

    Aliases are alternative names for tasks. They can be used to make it easier and +converts a string from / path format to \.

  • exeExt: Returns the right executable extension for the current OS (".exe" +for Windows, "" for others).
  • shellQuote: Quotes a string to make it safe for use in shell scripts. Task +uses this Go function +for this. The Bash dialect is assumed.
  • splitArgs: Splits a string as if it were a command's arguments. Task uses +this Go function
  • Example:

    version: '3'

    tasks:
    print-os:
    cmds:
    - echo '{{OS}} {{ARCH}}'
    - echo '{{if eq OS "windows"}}windows-command{{else}}unix-command{{end}}'
    # This will be path/to/file on Unix but path\to\file on Windows
    - echo '{{fromSlash "path/to/file"}}'
    enumerated-file:
    vars:
    CONTENT: |
    foo
    bar
    cmds:
    - |
    cat << EOF > output.txt
    {{range $i, $line := .CONTENT | splitLines -}}
    {{printf "%3d" $i}}: {{$line}}
    {{end}}EOF

    Help

    Running task --list (or task -l) lists all tasks with a description. The +following Taskfile:

    version: '3'

    tasks:
    build:
    desc: Build the go binary.
    cmds:
    - go build -v -i main.go

    test:
    desc: Run all the go tests.
    cmds:
    - go test -race ./...

    js:
    cmds:
    - esbuild --bundle --minify js/index.js > public/bundle.js

    css:
    cmds:
    - esbuild --bundle --minify css/index.css > public/bundle.css

    would print the following output:

    * build:   Build the go binary.
    * test: Run all the go tests.

    If you want to see all tasks, there's a --list-all (alias -a) flag as well.

    Display summary of task

    Running task --summary task-name will show a summary of a task. The following +Taskfile:

    version: '3'

    tasks:
    release:
    deps: [build]
    summary: |
    Release your project to github

    It will build your project before starting the release.
    Please make sure that you have set GITHUB_TOKEN before starting.
    cmds:
    - your-release-tool

    build:
    cmds:
    - your-build-tool

    with running task --summary release would print the following output:

    task: release

    Release your project to github

    It will build your project before starting the release.
    Please make sure that you have set GITHUB_TOKEN before starting.

    dependencies:
    - build

    commands:
    - your-release-tool

    If a summary is missing, the description will be printed. If the task does not +have a summary or a description, a warning is printed.

    Please note: showing the summary will not execute the command.

    Task aliases

    Aliases are alternative names for tasks. They can be used to make it easier and quicker to run tasks with long or hard-to-type names. You can use them on the command line, when calling sub-tasks in your Taskfile and when including tasks with aliases from another -Taskfile. They can also be used together with namespace -aliases.

    version: '3'

    tasks:
    generate:
    aliases: [gen]
    cmds:
    - task: gen-mocks

    generate-mocks:
    aliases: [gen-mocks]
    cmds:
    - echo "generating..."

    Overriding task name

    Sometimes you may want to override the task name printed on the summary, up-to-date -messages to STDOUT, etc. In this case, you can just set label:, which can also -be interpolated with variables:

    version: '3'

    tasks:
    default:
    - task: print
    vars:
    MESSAGE: hello
    - task: print
    vars:
    MESSAGE: world

    print:
    label: 'print-{{.MESSAGE}}'
    cmds:
    - echo "{{.MESSAGE}}"

    Silent mode

    Silent mode disables the echoing of commands before Task runs it. -For the following Taskfile:

    version: '3'

    tasks:
    echo:
    cmds:
    - echo "Print something"

    Normally this will be printed:

    echo "Print something"
    Print something

    With silent mode on, the below will be printed instead:

    Print something

    There are four ways to enable silent mode:

    • At command level:
    version: '3'

    tasks:
    echo:
    cmds:
    - cmd: echo "Print something"
    silent: true
    • At task level:
    version: '3'

    tasks:
    echo:
    cmds:
    - echo "Print something"
    silent: true
    • Globally at Taskfile level:
    version: '3'

    silent: true

    tasks:
    echo:
    cmds:
    - echo "Print something"
    • Or globally with --silent or -s flag

    If you want to suppress STDOUT instead, just redirect a command to /dev/null:

    version: '3'

    tasks:
    echo:
    cmds:
    - echo "This will print nothing" > /dev/null

    Dry run mode

    Dry run mode (--dry) compiles and steps through each task, printing the commands -that would be run without executing them. This is useful for debugging your Taskfiles.

    Ignore errors

    You have the option to ignore errors during command execution. -Given the following Taskfile:

    version: '3'

    tasks:
    echo:
    cmds:
    - exit 1
    - echo "Hello World"

    Task will abort the execution after running exit 1 because the status code 1 stands for EXIT_FAILURE. -However, it is possible to continue with execution using ignore_error:

    version: '3'

    tasks:
    echo:
    cmds:
    - cmd: exit 1
    ignore_error: true
    - echo "Hello World"

    ignore_error can also be set for a task, which means errors will be suppressed -for all commands. Nevertheless, keep in mind that this option will not propagate to other tasks -called either by deps or cmds!

    Output syntax

    By default, Task just redirects the STDOUT and STDERR of the running commands -to the shell in real-time. This is good for having live feedback for logging +Taskfile. They can also be used together with +namespace aliases.

    version: '3'

    tasks:
    generate:
    aliases: [gen]
    cmds:
    - task: gen-mocks

    generate-mocks:
    aliases: [gen-mocks]
    cmds:
    - echo "generating..."

    Overriding task name

    Sometimes you may want to override the task name printed on the summary, +up-to-date messages to STDOUT, etc. In this case, you can just set label:, +which can also be interpolated with variables:

    version: '3'

    tasks:
    default:
    - task: print
    vars:
    MESSAGE: hello
    - task: print
    vars:
    MESSAGE: world

    print:
    label: 'print-{{.MESSAGE}}'
    cmds:
    - echo "{{.MESSAGE}}"

    Silent mode

    Silent mode disables the echoing of commands before Task runs it. For the +following Taskfile:

    version: '3'

    tasks:
    echo:
    cmds:
    - echo "Print something"

    Normally this will be printed:

    echo "Print something"
    Print something

    With silent mode on, the below will be printed instead:

    Print something

    There are four ways to enable silent mode:

    • At command level:
    version: '3'

    tasks:
    echo:
    cmds:
    - cmd: echo "Print something"
    silent: true
    • At task level:
    version: '3'

    tasks:
    echo:
    cmds:
    - echo "Print something"
    silent: true
    • Globally at Taskfile level:
    version: '3'

    silent: true

    tasks:
    echo:
    cmds:
    - echo "Print something"
    • Or globally with --silent or -s flag

    If you want to suppress STDOUT instead, just redirect a command to /dev/null:

    version: '3'

    tasks:
    echo:
    cmds:
    - echo "This will print nothing" > /dev/null

    Dry run mode

    Dry run mode (--dry) compiles and steps through each task, printing the +commands that would be run without executing them. This is useful for debugging +your Taskfiles.

    Ignore errors

    You have the option to ignore errors during command execution. Given the +following Taskfile:

    version: '3'

    tasks:
    echo:
    cmds:
    - exit 1
    - echo "Hello World"

    Task will abort the execution after running exit 1 because the status code 1 +stands for EXIT_FAILURE. However, it is possible to continue with execution +using ignore_error:

    version: '3'

    tasks:
    echo:
    cmds:
    - cmd: exit 1
    ignore_error: true
    - echo "Hello World"

    ignore_error can also be set for a task, which means errors will be suppressed +for all commands. Nevertheless, keep in mind that this option will not propagate +to other tasks called either by deps or cmds!

    Output syntax

    By default, Task just redirects the STDOUT and STDERR of the running commands to +the shell in real-time. This is good for having live feedback for logging printed by commands, but the output can become messy if you have multiple commands running simultaneously and printing lots of stuff.

    To make this more customizable, there are currently three different output options you can choose:

    • interleaved (default)
    • group
    • prefixed

    To choose another one, just set it to root in the Taskfile:

    version: '3'

    output: 'group'

    tasks:
    # ...

    The group output will print the entire output of a command once after it finishes, so you will not have live feedback for commands that take a long time -to run.

    When using the group output, you can optionally provide a templated message -to print at the start and end of the group. This can be useful for instructing -CI systems to group all of the output for a given task, such as with +to run.

    When using the group output, you can optionally provide a templated message to +print at the start and end of the group. This can be useful for instructing CI +systems to group all of the output for a given task, such as with GitHub Actions' ::group:: command -or Azure Pipelines.

    version: '3'

    output:
    group:
    begin: '::group::{{.TASK}}'
    end: '::endgroup::'

    tasks:
    default:
    cmds:
    - echo 'Hello, World!'
    silent: true
    $ task default
    ::group::default
    Hello, World!
    ::endgroup::

    When using the group output, you may swallow the output of the executed command -on standard output and standard error if it does not fail (zero exit code).

    version: '3'

    silent: true

    output:
    group:
    error_only: true

    tasks:
    passes: echo 'output-of-passes'
    errors: echo 'output-of-errors' && exit 1
    $ task passes
    $ task errors
    output-of-errors
    task: Failed to run task "errors": exit status 1

    The prefix output will prefix every line printed by a command with +or +Azure Pipelines.

    version: '3'

    output:
    group:
    begin: '::group::{{.TASK}}'
    end: '::endgroup::'

    tasks:
    default:
    cmds:
    - echo 'Hello, World!'
    silent: true
    $ task default
    ::group::default
    Hello, World!
    ::endgroup::

    When using the group output, you may swallow the output of the executed +command on standard output and standard error if it does not fail (zero exit +code).

    version: '3'

    silent: true

    output:
    group:
    error_only: true

    tasks:
    passes: echo 'output-of-passes'
    errors: echo 'output-of-errors' && exit 1
    $ task passes
    $ task errors
    output-of-errors
    task: Failed to run task "errors": exit status 1

    The prefix output will prefix every line printed by a command with [task-name] as the prefix, but you can customize the prefix for a command -with the prefix: attribute:

    version: '3'

    output: prefixed

    tasks:
    default:
    deps:
    - task: print
    vars: {TEXT: foo}
    - task: print
    vars: {TEXT: bar}
    - task: print
    vars: {TEXT: baz}

    print:
    cmds:
    - echo "{{.TEXT}}"
    prefix: "print-{{.TEXT}}"
    silent: true
    $ task default
    [print-foo] foo
    [print-bar] bar
    [print-baz] baz
    tip

    The output option can also be specified by the --output or -o flags.

    Interactive CLI application

    When running interactive CLI applications inside Task they can sometimes behave +with the prefix: attribute:

    version: '3'

    output: prefixed

    tasks:
    default:
    deps:
    - task: print
    vars: { TEXT: foo }
    - task: print
    vars: { TEXT: bar }
    - task: print
    vars: { TEXT: baz }

    print:
    cmds:
    - echo "{{.TEXT}}"
    prefix: 'print-{{.TEXT}}'
    silent: true
    $ task default
    [print-foo] foo
    [print-bar] bar
    [print-baz] baz
    tip

    The output option can also be specified by the --output or -o flags.

    Interactive CLI application

    When running interactive CLI applications inside Task they can sometimes behave weirdly, especially when the output mode is set to something other than interleaved (the default), or when interactive apps are run in parallel with other tasks.

    The interactive: true tells Task this is an interactive application and Task will try to optimize for it:

    version: '3'

    tasks:
    default:
    cmds:
    - vim my-file.txt
    interactive: true

    If you still have problems running an interactive app through Task, please open -an issue about it.

    Short task syntax

    Starting on Task v3, you can now write tasks with a shorter syntax if they -have the default settings (e.g. no custom env:, vars:, desc:, silent: , etc):

    version: '3'

    tasks:
    build: go build -v -o ./app{{exeExt}} .

    run:
    - task: build
    - ./app{{exeExt}} -h localhost -p 8080

    set and shopt

    It's possible to specify options to the +an issue about it.

    Short task syntax

    Starting on Task v3, you can now write tasks with a shorter syntax if they have +the default settings (e.g. no custom env:, vars:, desc:, silent: , etc):

    version: '3'

    tasks:
    build: go build -v -o ./app{{exeExt}} .

    run:
    - task: build
    - ./app{{exeExt}} -h localhost -p 8080

    set and shopt

    It's possible to specify options to the set -and shopt +and +shopt builtins. This can be added at global, task or command level.

    version: '3'

    set: [pipefail]
    shopt: [globstar]

    tasks:
    # `globstar` required for double star globs to work
    default: echo **/*.go
    info

    Keep in mind that not all options are available in the -shell interpreter library that Task uses.

    Watch tasks

    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.

    - +shell interpreter library that Task uses.

    Watch tasks

    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.

    + \ No newline at end of file