diff --git a/fr-FR/404.html b/fr-FR/404.html index 05de04a0..5d568fd6 100644 --- a/fr-FR/404.html +++ b/fr-FR/404.html @@ -10,13 +10,13 @@ - +
Accéder directement au contenu principal

Page non trouvée

Nous n'avons pas trouvé ce que vous recherchiez.

Veuillez contacter le propriétaire du site qui vous a lié à l'URL d'origine et lui faire savoir que son lien est rompu.

- + \ No newline at end of file diff --git a/fr-FR/api/index.html b/fr-FR/api/index.html index ec35c4c9..dd3f0f96 100644 --- a/fr-FR/api/index.html +++ b/fr-FR/api/index.html @@ -10,13 +10,13 @@ - +
-
Accéder directement au contenu principal

API Reference

CLI

Task command line tool has the following syntax:

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

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.

Exit Codes

Task will sometimes exit with specific exit codes. These codes are split into three groups with the following ranges:

  • General errors (0-99)
  • Taskfile errors (100-199)
  • Task errors (200-299)

A full list of the exit codes and their descriptions can be found below:

CodeDescription
0Success
1An unknown error occurred
100No Taskfile was found
101A Taskfile already exists when trying to initialize one
102The Taskfile is invalid or cannot be parsed
200The specified task could not be found
201An error occurred while executing a command inside of a task
202The user tried to invoke a task that is internal
203There a multiple tasks with the same name or alias
204A task was called too many times

These codes can also be found in the repository in errors/errors.go.

info

When Task is run with the -x/--exit-code flag, the exit code of any failed commands will be passed through to the user instead.

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.
conseils

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.
conseils

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
- +
Accéder directement au contenu principal

API Reference

CLI

Task command line tool has the following syntax:

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

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.

Exit Codes

Task will sometimes exit with specific exit codes. These codes are split into three groups with the following ranges:

  • General errors (0-99)
  • Taskfile errors (100-199)
  • Task errors (200-299)

A full list of the exit codes and their descriptions can be found below:

CodeDescription
0Success
1An unknown error occurred
100No Taskfile was found
101A Taskfile already exists when trying to initialize one
102The Taskfile is invalid or cannot be parsed
200The specified task could not be found
201An error occurred while executing a command inside of a task
202The user tried to invoke a task that is internal
203There a multiple tasks with the same name or alias
204A task was called too many times

These codes can also be found in the repository in errors/errors.go.

info

When Task is run with the -x/--exit-code flag, the exit code of any failed commands will be passed through to the user instead.

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.
silentboolfalseHides task name and command from output. The command's output will still be redirected to STDOUT and STDERR.
conseils

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.
conseils

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/fr-FR/assets/js/0b932adf.f10a9864.js b/fr-FR/assets/js/0b932adf.f10a9864.js deleted file mode 100644 index ecfa4309..00000000 --- a/fr-FR/assets/js/0b932adf.f10a9864.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[459],{3905:function(t,e,a){a.d(e,{Zo:function(){return h},kt:function(){return d}});var i=a(7294);function s(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function n(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,i)}return a}function l(t){for(var e=1;e=0||(s[a]=t[a]);return s}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(s[a]=t[a])}return s}var o=i.createContext({}),k=function(t){var e=i.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},h=function(t){var e=k(t.components);return i.createElement(o.Provider,{value:e},t.children)},m="mdxType",p={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},u=i.forwardRef((function(t,e){var a=t.components,s=t.mdxType,n=t.originalType,o=t.parentName,h=r(t,["components","mdxType","originalType","parentName"]),m=k(a),u=s,d=m["".concat(o,".").concat(u)]||m[u]||p[u]||n;return a?i.createElement(d,l(l({ref:e},h),{},{components:a})):i.createElement(d,l({ref:e},h))}));function d(t,e){var a=arguments,s=e&&e.mdxType;if("string"==typeof t||s){var n=a.length,l=new Array(n);l[0]=u;var r={};for(var o in e)hasOwnProperty.call(e,o)&&(r[o]=e[o]);r.originalType=t,r[m]="string"==typeof t?t:s,l[1]=r;for(var k=2;k=0||(s[a]=t[a]);return s}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(s[a]=t[a])}return s}var o=i.createContext({}),k=function(t){var e=i.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},h=function(t){var e=k(t.components);return i.createElement(o.Provider,{value:e},t.children)},m="mdxType",p={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},u=i.forwardRef((function(t,e){var a=t.components,s=t.mdxType,n=t.originalType,o=t.parentName,h=r(t,["components","mdxType","originalType","parentName"]),m=k(a),u=s,d=m["".concat(o,".").concat(u)]||m[u]||p[u]||n;return a?i.createElement(d,l(l({ref:e},h),{},{components:a})):i.createElement(d,l({ref:e},h))}));function d(t,e){var a=arguments,s=e&&e.mdxType;if("string"==typeof t||s){var n=a.length,l=new Array(n);l[0]=u;var r={};for(var o in e)hasOwnProperty.call(e,o)&&(r[o]=e[o]);r.originalType=t,r[m]="string"==typeof t?t:s,l[1]=r;for(var k=2;k=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=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")," attribute should contain the commands of a task. The example below allows compiling a Go app and uses ",(0,i.kt)("a",{parentName:"p",href:"https://esbuild.github.io/"},"esbuild")," to concat and 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 interpreter. So you can write sh/bash commands, and it will work even on Windows, where ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"bash")," are usually not available. Just remember any executable 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 committed version (",(0,i.kt)("inlineCode",{parentName:"p"},".dist"),") while still allowing individual users to override the Taskfile by adding an additional ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," (which would be on ",(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 the file tree until it finds one (similar to how ",(0,i.kt)("inlineCode",{parentName:"p"},"git")," works). When running Task from a subdirectory like this, it will behave as if you ran it from the directory 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}}")," variable to create some very useful reusable tasks. For example, if you have a monorepo with directories for each microservice, you can ",(0,i.kt)("inlineCode",{parentName:"p"},"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:"),(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 ",(0,i.kt)("inlineCode",{parentName:"p"},"")," directory contains a ",(0,i.kt)("inlineCode",{parentName:"p"},"docker-compose.yml"),", the Docker composition will 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 home directory instead of your working directory. In short, Task will look for a 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 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 default, 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 variable can be very handy here to run stuff on the directory you're calling ",(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 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 just 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:")," setting:"),(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 variables 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 the 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 namespace. 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 ",(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 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")," if it exists (for example: ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_windows.yml"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_linux.yml")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"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:"),(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 the Taskfile is in another directory, but you can force its tasks to run in 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 Taskfile 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 the 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 internal as well (see the ",(0,i.kt)("a",{parentName:"p",href:"#internal-tasks"},"Internal tasks")," section below). This is useful when including utility tasks that are not intended to be used directly 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 for 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"),". This works in the same way as ",(0,i.kt)("a",{parentName:"p",href:"#task-aliases"},"task aliases")," and can be used together 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 variables in the including Taskfile! If you want a variable in an included Taskfile to be overridable, use the ",(0,i.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/defaults.html"},"default function"),": ",(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 not appear in the output when running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --list|--list-all"),". Other tasks may call internal tasks in the usual way. This is useful for creating reusable, function-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 located. But you can easily make the task run in another folder, informing ",(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 another. If you want to force tasks to run serially, take a look at the ",(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 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 ",(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 performance."),(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 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 manner 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 using the ",(0,i.kt)("inlineCode",{parentName:"p"},"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."),(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 defined by the Go language ",(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 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:"),(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")," attribute:"),(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 ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"included Taskfile"),", add a leading ",(0,i.kt)("inlineCode",{parentName:"p"},":")," like this: ",(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 files, 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 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 ",(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, instead 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. You can even combine the two. See the documentation for ",(0,i.kt)("a",{parentName:"p",href:"#using-programmatic-checks-to-indicate-a-task-is-up-to-date"},"status")," for an example."),(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 directory. Most of the time, you'll want to have this directory on ",(0,i.kt)("inlineCode",{parentName:"p"},".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)."),(0,i.kt)("p",{parentName:"admonition"},"If you want these files to be stored in another directory, you can set a ",(0,i.kt)("inlineCode",{parentName:"p"},"TASK_TEMP_DIR")," environment variable in your machine. It can contain a relative path like ",(0,i.kt)("inlineCode",{parentName:"p"},"tmp/task")," that will be interpreted as relative to the project directory, or an absolute or home path like ",(0,i.kt)("inlineCode",{parentName:"p"},"/tmp/.task")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"~/.task")," (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 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."),(0,i.kt)("p",{parentName:"admonition"},"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.")),(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 inform the source files. When 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 is 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"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 ",(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 interpolation within ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," commands, depending on the method assigned to 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 can 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 up-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 the 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")," to have a task run if either the the source/generated artifacts changes, or the programmatic 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 of ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," checks. That is, if you need a certain set of conditions to be ",(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 ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," lines, except they support ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," expansion, 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 a 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 precondition is not met - the calling task will fail. Note that a task executed with 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 executing tasks that depend on it, a ",(0,i.kt)("inlineCode",{parentName:"p"},"precondition")," will fail a task, along with 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 when 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 of the Taskfile to change 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 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 passed 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 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 (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 (Windows) tasks also accept a similar style when not at the beginning of the 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. 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."),(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 ",(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 task finishes. The difference with just putting it as the last command is that 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 well:"),(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 ",(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 commands 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. 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")," are 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", "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 "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"},"\\")," path 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 converts 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"')," 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. Task uses ",(0,i.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote"},"this Go function")," for 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 ",(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 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. The 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. If 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 quicker to run tasks with long or hard-to-type names. You can use them on the command line, when ",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"calling sub-tasks")," in your Taskfile and when ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"including tasks")," with aliases from another Taskfile. They can also be used together with ",(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, up-to-date messages to STDOUT, etc. In this case, you can just set ",(0,i.kt)("inlineCode",{parentName:"p"},"label:"),", which 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 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 that 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. Given 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"),". However, 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 for all commands. Nevertheless, keep in mind that this option will not propagate to 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 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."),(0,i.kt)("p",null,"To make this more customizable, there are currently three different output options 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 finishes, so you will not have live feedback for commands that take a long time to 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 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 ",(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")," or ",(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 on 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"[task-name]")," as the prefix, but you can customize the prefix for a command with 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 weirdly, especially when the ",(0,i.kt)("a",{parentName:"p",href:"#output-syntax"},"output mode")," is set to something other than ",(0,i.kt)("inlineCode",{parentName:"p"},"interleaved")," (the default), or when interactive apps are run in parallel 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 will 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 an 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 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 ",(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"))," and ",(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"))," builtins. 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 ",(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 task again. This requires the ",(0,i.kt)("inlineCode",{parentName:"p"},"sources")," attribute to be given, so 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 either setting ",(0,i.kt)("inlineCode",{parentName:"p"},"interval: '500ms'")," in the root of the Taskfile passing it as an argument like ",(0,i.kt)("inlineCode",{parentName:"p"},"--interval=500ms"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/fr-FR/assets/js/c7bb9a9c.cb217a16.js b/fr-FR/assets/js/c7bb9a9c.cb217a16.js new file mode 100644 index 00000000..8ba078d1 --- /dev/null +++ b/fr-FR/assets/js/c7bb9a9c.cb217a16.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[600],{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. The ",(0,i.kt)("inlineCode",{parentName:"p"},"cmds")," attribute should contain the commands of a task. The example below allows compiling a Go app and uses ",(0,i.kt)("a",{parentName:"p",href:"https://esbuild.github.io/"},"esbuild")," to concat and 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 interpreter. So you can write sh/bash commands, and it will work even on Windows, where ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"bash")," are usually not available. Just remember any executable 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 committed version (",(0,i.kt)("inlineCode",{parentName:"p"},".dist"),") while still allowing individual users to override the Taskfile by adding an additional ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," (which would be on ",(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 the file tree until it finds one (similar to how ",(0,i.kt)("inlineCode",{parentName:"p"},"git")," works). When running Task from a subdirectory like this, it will behave as if you ran it from the directory 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}}")," variable to create some very useful reusable tasks. For example, if you have a monorepo with directories for each microservice, you can ",(0,i.kt)("inlineCode",{parentName:"p"},"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:"),(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 ",(0,i.kt)("inlineCode",{parentName:"p"},"")," directory contains a ",(0,i.kt)("inlineCode",{parentName:"p"},"docker-compose.yml"),", the Docker composition will 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 home directory instead of your working directory. In short, Task will look for a 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 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 default, 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 variable can be very handy here to run stuff on the directory you're calling ",(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 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 just 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:")," setting:"),(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 variables 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 the 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 namespace. 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 ",(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 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")," if it exists (for example: ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_windows.yml"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_linux.yml")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"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:"),(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 the Taskfile is in another directory, but you can force its tasks to run in 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 Taskfile 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 the 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 internal as well (see the ",(0,i.kt)("a",{parentName:"p",href:"#internal-tasks"},"Internal tasks")," section below). This is useful when including utility tasks that are not intended to be used directly 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 for 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"),". This works in the same way as ",(0,i.kt)("a",{parentName:"p",href:"#task-aliases"},"task aliases")," and can be used together 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 variables in the including Taskfile! If you want a variable in an included Taskfile to be overridable, use the ",(0,i.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/defaults.html"},"default function"),": ",(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 not appear in the output when running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --list|--list-all"),". Other tasks may call internal tasks in the usual way. This is useful for creating reusable, function-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 located. But you can easily make the task run in another folder, informing ",(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 another. If you want to force tasks to run serially, take a look at the ",(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 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 ",(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 performance."),(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 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 manner 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 silent: true\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 using the ",(0,i.kt)("inlineCode",{parentName:"p"},"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."),(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 defined by the Go language ",(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 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:"),(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,"Using the ",(0,i.kt)("inlineCode",{parentName:"p"},"vars")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"silent")," attributes you can choose to pass variables and toggle ",(0,i.kt)("a",{parentName:"p",href:"#silent-mode"},"silent mode")," on a call-by-call basis:"),(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 silent: true\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 ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"included Taskfile"),", add a leading ",(0,i.kt)("inlineCode",{parentName:"p"},":")," like this: ",(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 files, 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 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 ",(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, instead 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. You can even combine the two. See the documentation for ",(0,i.kt)("a",{parentName:"p",href:"#using-programmatic-checks-to-indicate-a-task-is-up-to-date"},"status")," for an example."),(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 directory. Most of the time, you'll want to have this directory on ",(0,i.kt)("inlineCode",{parentName:"p"},".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)."),(0,i.kt)("p",{parentName:"admonition"},"If you want these files to be stored in another directory, you can set a ",(0,i.kt)("inlineCode",{parentName:"p"},"TASK_TEMP_DIR")," environment variable in your machine. It can contain a relative path like ",(0,i.kt)("inlineCode",{parentName:"p"},"tmp/task")," that will be interpreted as relative to the project directory, or an absolute or home path like ",(0,i.kt)("inlineCode",{parentName:"p"},"/tmp/.task")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"~/.task")," (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 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."),(0,i.kt)("p",{parentName:"admonition"},"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.")),(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 inform the source files. When 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 is 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"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 ",(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 interpolation within ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," commands, depending on the method assigned to 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 can 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 up-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 the 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")," to have a task run if either the the source/generated artifacts changes, or the programmatic 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 of ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," checks. That is, if you need a certain set of conditions to be ",(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 ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," lines, except they support ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," expansion, 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 a 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 precondition is not met - the calling task will fail. Note that a task executed with 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 executing tasks that depend on it, a ",(0,i.kt)("inlineCode",{parentName:"p"},"precondition")," will fail a task, along with 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 when 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 of the Taskfile to change 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 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 passed 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 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 (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 (Windows) tasks also accept a similar style when not at the beginning of the 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. 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."),(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 ",(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 task finishes. The difference with just putting it as the last command is that 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 well:"),(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 ",(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 commands 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. 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")," are 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", "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 "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"},"\\")," path 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 converts 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"')," 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. Task uses ",(0,i.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote"},"this Go function")," for 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 ",(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 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. The 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. If 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 quicker to run tasks with long or hard-to-type names. You can use them on the command line, when ",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"calling sub-tasks")," in your Taskfile and when ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"including tasks")," with aliases from another Taskfile. They can also be used together with ",(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, up-to-date messages to STDOUT, etc. In this case, you can just set ",(0,i.kt)("inlineCode",{parentName:"p"},"label:"),", which 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 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 that 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. Given 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"),". However, 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 for all commands. Nevertheless, keep in mind that this option will not propagate to 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 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."),(0,i.kt)("p",null,"To make this more customizable, there are currently three different output options 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 finishes, so you will not have live feedback for commands that take a long time to 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 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 ",(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")," or ",(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 on 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"[task-name]")," as the prefix, but you can customize the prefix for a command with 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 weirdly, especially when the ",(0,i.kt)("a",{parentName:"p",href:"#output-syntax"},"output mode")," is set to something other than ",(0,i.kt)("inlineCode",{parentName:"p"},"interleaved")," (the default), or when interactive apps are run in parallel 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 will 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 an 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 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 ",(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"))," and ",(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"))," builtins. 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 ",(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 task again. This requires the ",(0,i.kt)("inlineCode",{parentName:"p"},"sources")," attribute to be given, so 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 either setting ",(0,i.kt)("inlineCode",{parentName:"p"},"interval: '500ms'")," in the root of the Taskfile passing it as an argument like ",(0,i.kt)("inlineCode",{parentName:"p"},"--interval=500ms"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/fr-FR/assets/js/runtime~main.0df9689d.js b/fr-FR/assets/js/runtime~main.f0ea4364.js similarity index 95% rename from fr-FR/assets/js/runtime~main.0df9689d.js rename to fr-FR/assets/js/runtime~main.f0ea4364.js index 6a21dcd9..4fc1339d 100644 --- a/fr-FR/assets/js/runtime~main.0df9689d.js +++ b/fr-FR/assets/js/runtime~main.f0ea4364.js @@ -1 +1 @@ -!function(){"use strict";var e,t,n,r,o,a={},f={};function u(e){var t=f[e];if(void 0!==t)return t.exports;var n=f[e]={id:e,loaded:!1,exports:{}};return a[e].call(n.exports,n,n.exports,u),n.loaded=!0,n.exports}u.m=a,u.c=f,e=[],u.O=function(t,n,r,o){if(!n){var a=1/0;for(d=0;d=o)&&Object.keys(u.O).every((function(e){return u.O[e](n[i])}))?n.splice(i--,1):(f=!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 a={};t=t||[null,n({}),n([]),n(n)];for(var f=2&r&&e;"object"==typeof f&&!~t.indexOf(f);f=n(f))Object.getOwnPropertyNames(f).forEach((function(t){a[t]=function(){return e[t]}}));return a.default=function(){return e},u.d(o,a),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/"+({25:"0dcc542b",53:"935f2afb",132:"87000503",133:"f1d66b0d",138:"5a4ba766",252:"5f6ff44c",317:"a1e60667",326:"32a1682e",395:"5c204da3",459:"0b932adf",475:"4ebd4aab",514:"1be78505",595:"d0766b26",600:"c7bb9a9c",611:"5e0a7f42",622:"a0a37b13",643:"a85b9635",890:"065ba513",918:"17896441",920:"1a4e3797"}[e]||e)+"."+{25:"96f49890",53:"e1d98343",132:"ad6fb1f0",133:"6862b446",138:"0be9a6c7",252:"b8e3a8b1",317:"f813eb80",326:"ccc3bb8c",395:"5b2dfc8f",459:"f10a9864",475:"e0328154",514:"9062895a",595:"c5627647",600:"07ac91a9",611:"473ccf24",622:"d2a18122",643:"d52de0a8",780:"b979b06f",890:"a0d2bd80",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,a){if(r[e])r[e].push(t);else{var f,i;if(void 0!==n)for(var c=document.getElementsByTagName("script"),d=0;d=o)&&Object.keys(u.O).every((function(e){return u.O[e](n[i])}))?n.splice(i--,1):(f=!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 a={};t=t||[null,n({}),n([]),n(n)];for(var f=2&r&&e;"object"==typeof f&&!~t.indexOf(f);f=n(f))Object.getOwnPropertyNames(f).forEach((function(t){a[t]=function(){return e[t]}}));return a.default=function(){return e},u.d(o,a),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/"+({25:"0dcc542b",53:"935f2afb",132:"87000503",133:"f1d66b0d",138:"5a4ba766",252:"5f6ff44c",317:"a1e60667",326:"32a1682e",395:"5c204da3",459:"0b932adf",475:"4ebd4aab",514:"1be78505",595:"d0766b26",600:"c7bb9a9c",611:"5e0a7f42",622:"a0a37b13",643:"a85b9635",890:"065ba513",918:"17896441",920:"1a4e3797"}[e]||e)+"."+{25:"96f49890",53:"0c6e61c3",132:"ad6fb1f0",133:"6862b446",138:"2bc53824",252:"b8e3a8b1",317:"f813eb80",326:"ccc3bb8c",395:"5b2dfc8f",459:"f4d3e342",475:"e0328154",514:"9062895a",595:"c5627647",600:"cb217a16",611:"473ccf24",622:"d2a18122",643:"d52de0a8",780:"b979b06f",890:"a0d2bd80",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,a){if(r[e])r[e].push(t);else{var f,i;if(void 0!==n)for(var c=document.getElementsByTagName("script"),d=0;d -Changelog | Task +Changelog | Task - +
-

Changelog

v3.24.0 - 2023-04-15

v3.23.0 - 2023-03-26

Task now has an official extension for Visual Studio Code contributed by @pd93! 🎉 The extension is maintained in a new repository under the go-task organization. We're looking to gather feedback from the community so please give it a go and let us know what you think via a discussion, issue or on our Discord!

NOTE: The extension requires v3.23.0 to be installed in order to work.

  • The website was integrated with Crowdin to allow the community to contribute with translations! Chinese is the first language available (#1057, #1058 by @misitebao).
  • Added task location data to the --json flag output (#1056 by @pd93)
  • Change the name of the file generated by task --init from Taskfile.yaml to Taskfile.yml (#1062 by @misitebao).
  • Added new splitArgs template function ({{splitArgs "foo bar 'foo bar baz'"}}) to ensure string is split as arguments (#1040, #1059 by @dhanusaputra).
  • Fix the value of {{.CHECKSUM}} variable in status (#1076, #1080 by @pd93).
  • Fixed deep copy implementation (#1072 by @pd93)
  • Created a tool to assist with releases (#1086 by @pd93).

v3.22.0 - 2023-03-10

  • Add a brand new --global (-g) flag that will run a Taskfile from your $HOME directory. This is useful to have automation that you can run from anywhere in your system! (Documentation, #1029 by @andreynering).
  • Add ability to set error_only: true on the group output mode. This will instruct Task to only print a command output if it returned with a non-zero exit code (#664, #1022 by @jaedle).
  • Fixed bug where .task/checksum file was sometimes not being created when task also declares a status: (#840, #1035 by @harelwa, #1037 by @pd93).
  • Refactored and decoupled fingerprinting from the main Task executor (#1039 by @pd93).
  • Fixed deadlock issue when using run: once (#715, #1025 by @theunrepentantgeek).

v3.21.0 - 2023-02-22

  • Added new TASK_VERSION special variable (#990, #1014 by @ja1code).
  • Fixed a bug where tasks were sometimes incorrectly marked as internal (#1007 by @pd93).
  • Update to Go 1.20 (bump minimum version to 1.19) (#1010 by @pd93)
  • Added environment variable FORCE_COLOR support to force color output. Usefull for environments without TTY (#1003 by @automation-stack)

v3.20.0 - 2023-01-14

  • Improve behavior and performance of status checking when using the timestamp mode (#976, #977 by @aminya).
  • Performance optimizations were made for large Taskfiles (#982 by @pd93).
  • Add ability to configure options for the set and shopt builtins (#908, #929 by @pd93, Documentation).
  • Add new platforms: attribute to task and cmd, so it's now possible to choose in which platforms that given task or command will be run on. Possible values are operating system (GOOS), architecture (GOARCH) or a combination of the two. Example: platforms: [linux], platforms: [amd64] or platforms: [linux/amd64]. Other platforms will be skipped (#978, #980 by @leaanthony).

v3.19.1 - 2022-12-31

  • Small bug fix: closing Taskfile.yml once we're done reading it (#963, #964 by @HeCorr).
  • Fixes a bug in v2 that caused a panic when using a Taskfile_{{OS}}.yml file (#961, #971 by @pd93).
  • Fixed a bug where watch intervals set in the Taskfile were not being respected (#969, #970 by @pd93)
  • Add --json flag (alias -j) with the intent to improve support for code editors and add room to other possible integrations. This is basic for now, but we plan to add more info in the near future (#936 by @davidalpert, #764).

v3.19.0 - 2022-12-05

v3.18.0 - 2022-11-12

  • Show aliases on task --list --silent (task --ls). This means that aliases will be completed by the completion scripts (#919).
  • Tasks in the root Taskfile will now be displayed first in --list/--list-all output (#806, #890).
  • It's now possible to call a default task in an included Taskfile by using just the namespace. For example: docs:default is now automatically aliased to docs (#661, #815).

v3.17.0 - 2022-10-14

  • Add a "Did you mean ...?" suggestion when a task does not exits another one with a similar name is found (#867, #880).
  • Now YAML parse errors will print which Taskfile failed to parse (#885, #887).
  • Add ability to set aliases for tasks and namespaces (#268, #340, #879).
  • Improvements to Fish shell completion (#897).
  • Added ability to set a different watch interval by setting interval: '500ms' or using the --interval=500ms flag (#813, #865).
  • Add colored output to --list, --list-all and --summary flags (#845, #874).
  • Fix unexpected behavior where label: was being shown instead of the task name on --list (#603, #877).

v3.16.0 - 2022-09-29

  • Add npm as new installation method: npm i -g [@go](https://github.com/go)-task/cli (#870, #871, npm package).
  • Add support to marking tasks and includes as internal, which will hide them from --list and --list-all (#818).

v3.15.2 - 2022-09-08

  • Fix error when using variable in env: introduced in the previous release (#858, #866).
  • Fix handling of CLI_ARGS (--) in Bash completion (#863).
  • On zsh completion, add ability to replace --list-all with --list as already possible on the Bash completion (#861).

v3.15.0 - 2022-09-03

  • Add new special variables ROOT_DIR and TASKFILE_DIR. This was a highly requested feature (#215, #857, Documentation).
  • Follow symlinks on sources (#826, #831).
  • Improvements and fixes to Bash completion (#835, #844).

v3.14.1 - 2022-08-03

  • Always resolve relative include paths relative to the including Taskfile (#822, #823).
  • Fix ZSH and PowerShell completions to consider all tasks instead of just the public ones (those with descriptions) (#803).

v3.14.0 - 2022-07-08

  • Add ability to override the .task directory location with the TASK_TEMP_DIR environment variable.
  • Allow to override Task colors using environment variables: TASK_COLOR_RESET, TASK_COLOR_BLUE, TASK_COLOR_GREEN, TASK_COLOR_CYAN, TASK_COLOR_YELLOW, TASK_COLOR_MAGENTA and TASK_COLOR_RED (#568, #792).
  • Fixed bug when using the output: group mode where STDOUT and STDERR were being print in separated blocks instead of in the right order (#779).
  • Starting on this release, ARM architecture binaries are been released to Snap as well (#795).
  • i386 binaries won't be available anymore on Snap because Ubuntu removed the support for this architecture.
  • Upgrade mvdan.cc/sh, which fixes a bug with associative arrays (#785, mvdan/sh[#884](https://github.com/go-task/task/issues/884), mvdan/sh[#893](https://github.com/go-task/task/issues/893)).

v3.13.0 - 2022-06-13

  • Added -n as an alias to --dry (#776, #777).
  • Fix behavior of interrupt (SIGINT, SIGTERM) signals. Task will now give time for the processes running to do cleanup work (#458, #479, #728, #769).
  • Add new --exit-code (-x) flag that will pass-through the exit form the command being ran (#755).

v3.12.1 - 2022-05-10

  • Fixed bug where, on Windows, variables were ending with \r because we were only removing the final \n but not \r\n (#717).

v3.12.0 - 2022-03-31

  • The --list and --list-all flags can now be combined with the --silent flag to print the task names only, without their description (#691).
  • Added support for multi-level inclusion of Taskfiles. This means that included Taskfiles can also include other Taskfiles. Before this was limited to one level (#390, #623, #656).
  • Add ability to specify vars when including a Taskfile. Check out the documentation for more information (#677).

v3.11.0 - 2022-02-19

v3.10.0 - 2022-01-04

  • A new --list-all (alias -a) flag is now available. It's similar to the exiting --list (-l) but prints all tasks, even those without a description (#383, #401).
  • It's now possible to schedule cleanup commands to run once a task finishes with the defer: keyword (Documentation, #475, #626).
  • Remove long deprecated and undocumented $ variable prefix and ^ command prefix (#642, #644, #645).
  • Add support for .yaml extension (as an alternative to .yml). This was requested multiple times throughout the years. Enjoy! (#183, #184, #369, #584, #621).
  • Fixed error when computing a variable when the task directory do not exist yet (#481, #579).

v3.9.2 - 2021-12-02

v3.9.1 - 2021-11-28

v3.9.0 - 2021-10-02

v3.8.0 - 2021-09-26

  • Add interactive: true setting to improve support for interactive CLI apps (#217, #563).
  • Fix some nil errors (#534, #573).
  • Add ability to declare an included Taskfile as optional (#519, #552).
  • Add support for including Taskfiles in the home directory by using ~ (#539, #557).

v3.7.3 - 2021-09-04

v3.7.0 - 2021-07-31

  • Add run: setting to control if tasks should run multiple times or not. Available options are always (the default), when_changed (if a variable modified the task) and once (run only once no matter what). This is a long time requested feature. Enjoy! (#53, #359).

v3.6.0 - 2021-07-10

  • Allow using both sources: and status: in the same task (#411, #427, #477).
  • Small optimization and bug fix: don't compute variables if not needed for dotenv: (#517).

v3.5.0 - 2021-07-04

  • Add support for interpolation in dotenv: (#433, #434, #453).

v3.4.3 - 2021-05-30

v3.4.2 - 2021-04-23

  • On watch, report which file failed to read (#472).
  • Do not try to catch SIGKILL signal, which are not actually possible (#476).
  • Improve version reporting when building Task from source using Go Modules (#462, #473).

v3.4.1 - 2021-04-17

  • Improve error reporting when parsing YAML: in some situations where you would just see an generic error, you'll now see the actual error with more detail: the YAML line the failed to parse, for example (#467).
  • A JSON Schema was published here and is automatically being used by some editors like Visual Studio Code (#135).
  • Print task name before the command in the log output (#398).

v3.3.0 - 2021-03-20

  • Add support for delegating CLI arguments to commands with -- and a special CLI_ARGS variable (#327).
  • Add a --concurrency (alias -C) flag, to limit the number of tasks that run concurrently. This is useful for heavy workloads. (#345).

v3.2.2 - 2021-01-12

  • Improve performance of --list and --summary by skipping running shell variables for these flags (#332).
  • Fixed a bug where an environment in a Taskfile was not always overridable by the system environment (#425).
  • Fixed environment from .env files not being available as variables (#379).
  • The install script is now working for ARM platforms (#428).

v3.2.1 - 2021-01-09

  • Fixed some bugs and regressions regarding dynamic variables and directories (#426).
  • The slim-sprig package was updated with the upstream sprig.

v3.2.0 - 2021-01-07

  • Fix the .task directory being created in the task directory instead of the Taskfile directory (#247).
  • Fix a bug where dynamic variables (those declared with sh:) were not running in the task directory when the task has a custom dir or it was in an included Taskfile (#384).
  • The watch feature (via the --watch flag) got a few different bug fixes and should be more stable now (#423, #365).

v3.1.0 - 2021-01-03

  • Fix a bug when the checksum up-to-date resolution is used by a task with a custom label: attribute (#412).
  • Starting from this release, we're releasing official ARMv6 and ARM64 binaries for Linux (#375, #418).
  • Task now respects the order of declaration of included Taskfiles when evaluating variables declaring by them (#393).
  • set -e is now automatically set on every command. This was done to fix an issue where multiline string commands wouldn't really fail unless the sentence was in the last line (#403).

v3.0.1 - 2020-12-26

  • Allow use as a library by moving the required packages out of the internal directory (#358).
  • Do not error if a specified dotenv file does not exist (#378, #385).
  • Fix panic when you have empty tasks in your Taskfile (#338, #362).

v3.0.0 - 2020-08-16

  • On v3, all CLI variables will be considered global variables (#336, #341)
  • Add support to .env like files (#324, #356).
  • Add label: to task so you can override the task name in the logs ([#321](https://github.com/go-task/task/issues/321), #337).
  • Refactor how variables work on version 3 (#311).
  • Disallow expansions on v3 since it has no effect.
  • Taskvars.yml is not automatically included anymore.
  • Taskfile_{{OS}}.yml is not automatically included anymore.
  • Allow interpolation on includes, so you can manually include a Taskfile based on operation system, for example.
  • Expose .TASK variable in templates with the task name (#252).
  • Implement short task syntax (#194, #240).
  • Added option to make included Taskfile run commands on its own directory (#260, #144)
  • Taskfiles in version 1 are not supported anymore (#237).
  • Added global method: option. With this option, you can set a default method to all tasks in a Taskfile (#246).
  • Changed default method from timestamp to checksum (#246).
  • New magic variables are now available when using status:: .TIMESTAMP which contains the greatest modification date from the files listed in sources:, and .CHECKSUM, which contains a checksum of all files listed in status:. This is useful for manual checking when using external, or even remote, artifacts when using status: (#216).
  • We're now using slim-sprig instead of sprig, which allowed a file size reduction of about 22% (#219).
  • We now use some colors on Task output to better distinguish message types - commands are green, errors are red, etc (#207).

v2.8.1 - 2020-05-20

  • Fix error code for the --help flag (#300, #330).
  • Print version to stdout instead of stderr (#299, #329).
  • Supress context errors when using the --watch flag (#313, #317).
  • Support templating on description (#276, #283).

v2.8.0 - 2019-12-07

  • Add --parallel flag (alias -p) to run tasks given by the command line in parallel (#266).
  • Fixed bug where calling the task CLI only informing global vars would not execute the default task.
  • Add hability to silent all tasks by adding silent: true a the root of the Taskfile.

v2.7.1 - 2019-11-10

  • Fix error being raised when exit 0 was called (#251).

v2.7.0 - 2019-09-22

  • Fixed panic bug when assigning a global variable (#229, #243).
  • A task with method: checksum will now re-run if generated files are deleted (#228, #238).

v2.6.0 - 2019-07-21

  • Fixed some bugs regarding minor version checks on version:.
  • Add preconditions: to task (#205).
  • Create directory informed on dir: if it doesn't exist (#209, #211).
  • We now have a --taskfile flag (alias -t), which can be used to run another Taskfile (other than the default Taskfile.yml) (#221).
  • It's now possible to install Task using Homebrew on Linux (go-task/homebrew-tap[#1](https://github.com/go-task/task/issues/1)).

v2.5.2 - 2019-05-11

2.5.1 - 2019-04-27

  • Fixed some issues with interactive command line tools, where sometimes the output were not being shown, and similar issues (#114, #190, #200).
  • Upgraded go-yaml/yaml from v2 to v3.

v2.5.0 - 2019-03-16

v2.4.0 - 2019-02-21

  • Allow calling a task of the root Taskfile from an included Taskfile by prefixing it with : (#161, #172).
  • Add flag to override the output option (#173).
  • Fix bug where Task was persisting the new checksum on the disk when the Dry Mode is enabled (#166).
  • Fix file timestamp issue when the file name has spaces (#176).
  • Mitigating path expanding issues on Windows (#170).

v2.3.0 - 2019-01-02

  • On Windows, Task can now be installed using Scoop (#152).
  • Fixed issue with file/directory globing (#153).
  • Added ability to globally set environment variables (#138, #159).

v2.2.1 - 2018-12-09

  • This repository now uses Go Modules (#143). We'll still keep the vendor directory in sync for some time, though;
  • Fixing a bug when the Taskfile has no tasks but includes another Taskfile (#150);
  • Fix a bug when calling another task or a dependency in an included Taskfile (#151).

v2.2.0 - 2018-10-25

  • Added support for including other Taskfiles (#98)
    • This should be considered experimental. For now, only including local files is supported, but support for including remote Taskfiles is being discussed. If you have any feedback, please comment on #98.
  • Task now have a dedicated documentation site: https://taskfile.org
    • Thanks to Docsify for making this pretty easy. To check the source code, just take a look at the docs directory of this repository. Contributions to the documentation is really appreciated.

v2.1.1 - 2018-09-17

  • Fix suggestion to use task --init not being shown anymore (when a Taskfile.yml is not found)
  • Fix error when using checksum method and no file exists for a source glob (#131)
  • Fix signal handling when the --watch flag is given (#132)

v2.1.0 - 2018-08-19

  • Add a ignore_error option to task and command (#123)
  • Add a dry run mode (--dry flag) (#126)

v2.0.3 - 2018-06-24

  • Expand environment variables on "dir", "sources" and "generates" (#116)
  • Fix YAML merging syntax (#112)
  • Add ZSH completion (#111)
  • Implement new output option. Please check out the documentation

v2.0.2 - 2018-05-01

  • Fix merging of YAML anchors (#112)

v2.0.1 - 2018-03-11

  • Fixes panic on task --list

v2.0.0 - 2018-03-08

Version 2.0.0 is here, with a new Taskfile format.

Please, make sure to read the Taskfile versions document, since it describes in depth what changed for this version.

  • New Taskfile version 2 (#77)
  • Possibility to have global variables in the Taskfile.yml instead of Taskvars.yml (#66)
  • Small improvements and fixes

v1.4.4 - 2017-11-19

  • Handle SIGINT and SIGTERM (#75);
  • List: print message with there's no task with description;
  • Expand home dir ("~" symbol) on paths (#74);
  • Add Snap as an installation method;
  • Move examples to its own repo;
  • Watch: also walk on tasks called on on "cmds", and not only on "deps";
  • Print logs to stderr instead of stdout (#68);
  • Remove deprecated set keyword;
  • Add checksum based status check, alternative to timestamp based.

v1.4.3 - 2017-09-07

  • Allow assigning variables to tasks at run time via CLI (#33)
  • Added suport for multiline variables from sh (#64)
  • Fixes env: remove square braces and evaluate shell (#62)
  • Watch: change watch library and few fixes and improvements
  • When use watching, cancel and restart long running process on file change (#59 and #60)

v1.4.2 - 2017-07-30

  • Flag to set directory of execution
  • Always echo command if is verbose mode
  • Add silent mode to disable echoing of commands
  • Fixes and improvements of variables (#56)

v1.4.1 - 2017-07-15

  • Allow use of YAML for dynamic variables instead of $ prefix
    • VAR: {sh: echo Hello} instead of VAR: $echo Hello
  • Add --list (or -l) flag to print existing tasks
  • OS specific Taskvars file (e.g. Taskvars_windows.yml, Taskvars_linux.yml, etc)
  • Consider task up-to-date on equal timestamps (#49)
  • Allow absolute path in generates section (#48)
  • Bugfix: allow templating when calling deps (#42)
  • Fix panic for invalid task in cyclic dep detection
  • Better error output for dynamic variables in Taskvars.yml (#41)
  • Allow template evaluation in parameters

v1.4.0 - 2017-07-06

  • Cache dynamic variables
  • Add verbose mode (-v flag)
  • Support to task parameters (overriding vars) (#31) (#32)
  • Print command, also when "set:" is specified (#35)
  • Improve task command help text (#35)

v1.3.1 - 2017-06-14

  • Fix glob not working on commands (#28)
  • Add ExeExt template function
  • Add --init flag to create a new Taskfile
  • Add status option to prevent task from running (#27)
  • Allow interpolation on generates and sources attributes (#26)

v1.3.0 - 2017-04-24

  • Migrate from os/exec.Cmd to a native Go sh/bash interpreter
    • This is a potentially breaking change if you use Windows.
    • Now, cmd is not used anymore on Windows. Always use Bash-like syntax for your commands, even on Windows.
  • Add "ToSlash" and "FromSlash" to template functions
  • Use functions defined on github.com/Masterminds/sprig
  • Do not redirect stdin while running variables commands
  • Using context and errgroup packages (this will make other tasks to be cancelled, if one returned an error)

v1.2.0 - 2017-04-02

  • More tests and Travis integration
  • Watch a task (experimental)
  • Possibility to call another task
  • Fix "=" not being reconized in variables/environment variables
  • Tasks can now have a description, and help will print them (#10)
  • Task dependencies now run concurrently
  • Support for a default task (#16)

v1.1.0 - 2017-03-08

  • Support for YAML, TOML and JSON (#1)
  • Support running command in another directory (#4)
  • --force or -f flag to force execution of task even when it's up-to-date
  • Detection of cyclic dependencies (#5)
  • Support for variables (#6, #9, #14)
  • Operation System specific commands and variables (#13)

v1.0.0 - 2017-02-28

  • Add LICENSE file
- +

Changelog

v3.25.0 - 2023-05-22

  • Support silent: when calling another tasks (#680, #1142 by @danquah).
  • Improve PowerShell completion script (#1168 by @trim21).
  • Add more languages to the website menu and show translation progress percentage (#1173 by @misitebao).
  • Starting on this release, official binaries for FreeBSD will be available to download (#1068 by @andreynering).
  • Fix some errors being unintendedly supressed (#1134 by @clintmod).
  • Fix a nil pointer error when version is omitted from a Taskfile (#1148, #1149 by @pd93).
  • Fix duplicate error message when a task does not exists (#1141, #1144 by @pd93).

v3.24.0 - 2023-04-15

v3.23.0 - 2023-03-26

Task now has an official extension for Visual Studio Code contributed by @pd93! 🎉 The extension is maintained in a new repository under the go-task organization. We're looking to gather feedback from the community so please give it a go and let us know what you think via a discussion, issue or on our Discord!

NOTE: The extension requires v3.23.0 to be installed in order to work.

  • The website was integrated with Crowdin to allow the community to contribute with translations! Chinese is the first language available (#1057, #1058 by @misitebao).
  • Added task location data to the --json flag output (#1056 by @pd93)
  • Change the name of the file generated by task --init from Taskfile.yaml to Taskfile.yml (#1062 by @misitebao).
  • Added new splitArgs template function ({{splitArgs "foo bar 'foo bar baz'"}}) to ensure string is split as arguments (#1040, #1059 by @dhanusaputra).
  • Fix the value of {{.CHECKSUM}} variable in status (#1076, #1080 by @pd93).
  • Fixed deep copy implementation (#1072 by @pd93)
  • Created a tool to assist with releases (#1086 by @pd93).

v3.22.0 - 2023-03-10

  • Add a brand new --global (-g) flag that will run a Taskfile from your $HOME directory. This is useful to have automation that you can run from anywhere in your system! (Documentation, #1029 by @andreynering).
  • Add ability to set error_only: true on the group output mode. This will instruct Task to only print a command output if it returned with a non-zero exit code (#664, #1022 by @jaedle).
  • Fixed bug where .task/checksum file was sometimes not being created when task also declares a status: (#840, #1035 by @harelwa, #1037 by @pd93).
  • Refactored and decoupled fingerprinting from the main Task executor (#1039 by @pd93).
  • Fixed deadlock issue when using run: once (#715, #1025 by @theunrepentantgeek).

v3.21.0 - 2023-02-22

  • Added new TASK_VERSION special variable (#990, #1014 by @ja1code).
  • Fixed a bug where tasks were sometimes incorrectly marked as internal (#1007 by @pd93).
  • Update to Go 1.20 (bump minimum version to 1.19) (#1010 by @pd93)
  • Added environment variable FORCE_COLOR support to force color output. Usefull for environments without TTY (#1003 by @automation-stack)

v3.20.0 - 2023-01-14

  • Improve behavior and performance of status checking when using the timestamp mode (#976, #977 by @aminya).
  • Performance optimizations were made for large Taskfiles (#982 by @pd93).
  • Add ability to configure options for the set and shopt builtins (#908, #929 by @pd93, Documentation).
  • Add new platforms: attribute to task and cmd, so it's now possible to choose in which platforms that given task or command will be run on. Possible values are operating system (GOOS), architecture (GOARCH) or a combination of the two. Example: platforms: [linux], platforms: [amd64] or platforms: [linux/amd64]. Other platforms will be skipped (#978, #980 by @leaanthony).

v3.19.1 - 2022-12-31

  • Small bug fix: closing Taskfile.yml once we're done reading it (#963, #964 by @HeCorr).
  • Fixes a bug in v2 that caused a panic when using a Taskfile_{{OS}}.yml file (#961, #971 by @pd93).
  • Fixed a bug where watch intervals set in the Taskfile were not being respected (#969, #970 by @pd93)
  • Add --json flag (alias -j) with the intent to improve support for code editors and add room to other possible integrations. This is basic for now, but we plan to add more info in the near future (#936 by @davidalpert, #764).

v3.19.0 - 2022-12-05

v3.18.0 - 2022-11-12

  • Show aliases on task --list --silent (task --ls). This means that aliases will be completed by the completion scripts (#919).
  • Tasks in the root Taskfile will now be displayed first in --list/--list-all output (#806, #890).
  • It's now possible to call a default task in an included Taskfile by using just the namespace. For example: docs:default is now automatically aliased to docs (#661, #815).

v3.17.0 - 2022-10-14

  • Add a "Did you mean ...?" suggestion when a task does not exits another one with a similar name is found (#867, #880).
  • Now YAML parse errors will print which Taskfile failed to parse (#885, #887).
  • Add ability to set aliases for tasks and namespaces (#268, #340, #879).
  • Improvements to Fish shell completion (#897).
  • Added ability to set a different watch interval by setting interval: '500ms' or using the --interval=500ms flag (#813, #865).
  • Add colored output to --list, --list-all and --summary flags (#845, #874).
  • Fix unexpected behavior where label: was being shown instead of the task name on --list (#603, #877).

v3.16.0 - 2022-09-29

  • Add npm as new installation method: npm i -g [@go](https://github.com/go)-task/cli (#870, #871, npm package).
  • Add support to marking tasks and includes as internal, which will hide them from --list and --list-all (#818).

v3.15.2 - 2022-09-08

  • Fix error when using variable in env: introduced in the previous release (#858, #866).
  • Fix handling of CLI_ARGS (--) in Bash completion (#863).
  • On zsh completion, add ability to replace --list-all with --list as already possible on the Bash completion (#861).

v3.15.0 - 2022-09-03

  • Add new special variables ROOT_DIR and TASKFILE_DIR. This was a highly requested feature (#215, #857, Documentation).
  • Follow symlinks on sources (#826, #831).
  • Improvements and fixes to Bash completion (#835, #844).

v3.14.1 - 2022-08-03

  • Always resolve relative include paths relative to the including Taskfile (#822, #823).
  • Fix ZSH and PowerShell completions to consider all tasks instead of just the public ones (those with descriptions) (#803).

v3.14.0 - 2022-07-08

  • Add ability to override the .task directory location with the TASK_TEMP_DIR environment variable.
  • Allow to override Task colors using environment variables: TASK_COLOR_RESET, TASK_COLOR_BLUE, TASK_COLOR_GREEN, TASK_COLOR_CYAN, TASK_COLOR_YELLOW, TASK_COLOR_MAGENTA and TASK_COLOR_RED (#568, #792).
  • Fixed bug when using the output: group mode where STDOUT and STDERR were being print in separated blocks instead of in the right order (#779).
  • Starting on this release, ARM architecture binaries are been released to Snap as well (#795).
  • i386 binaries won't be available anymore on Snap because Ubuntu removed the support for this architecture.
  • Upgrade mvdan.cc/sh, which fixes a bug with associative arrays (#785, mvdan/sh[#884](https://github.com/go-task/task/issues/884), mvdan/sh[#893](https://github.com/go-task/task/issues/893)).

v3.13.0 - 2022-06-13

  • Added -n as an alias to --dry (#776, #777).
  • Fix behavior of interrupt (SIGINT, SIGTERM) signals. Task will now give time for the processes running to do cleanup work (#458, #479, #728, #769).
  • Add new --exit-code (-x) flag that will pass-through the exit form the command being ran (#755).

v3.12.1 - 2022-05-10

  • Fixed bug where, on Windows, variables were ending with \r because we were only removing the final \n but not \r\n (#717).

v3.12.0 - 2022-03-31

  • The --list and --list-all flags can now be combined with the --silent flag to print the task names only, without their description (#691).
  • Added support for multi-level inclusion of Taskfiles. This means that included Taskfiles can also include other Taskfiles. Before this was limited to one level (#390, #623, #656).
  • Add ability to specify vars when including a Taskfile. Check out the documentation for more information (#677).

v3.11.0 - 2022-02-19

v3.10.0 - 2022-01-04

  • A new --list-all (alias -a) flag is now available. It's similar to the exiting --list (-l) but prints all tasks, even those without a description (#383, #401).
  • It's now possible to schedule cleanup commands to run once a task finishes with the defer: keyword (Documentation, #475, #626).
  • Remove long deprecated and undocumented $ variable prefix and ^ command prefix (#642, #644, #645).
  • Add support for .yaml extension (as an alternative to .yml). This was requested multiple times throughout the years. Enjoy! (#183, #184, #369, #584, #621).
  • Fixed error when computing a variable when the task directory do not exist yet (#481, #579).

v3.9.2 - 2021-12-02

v3.9.1 - 2021-11-28

v3.9.0 - 2021-10-02

v3.8.0 - 2021-09-26

  • Add interactive: true setting to improve support for interactive CLI apps (#217, #563).
  • Fix some nil errors (#534, #573).
  • Add ability to declare an included Taskfile as optional (#519, #552).
  • Add support for including Taskfiles in the home directory by using ~ (#539, #557).

v3.7.3 - 2021-09-04

v3.7.0 - 2021-07-31

  • Add run: setting to control if tasks should run multiple times or not. Available options are always (the default), when_changed (if a variable modified the task) and once (run only once no matter what). This is a long time requested feature. Enjoy! (#53, #359).

v3.6.0 - 2021-07-10

  • Allow using both sources: and status: in the same task (#411, #427, #477).
  • Small optimization and bug fix: don't compute variables if not needed for dotenv: (#517).

v3.5.0 - 2021-07-04

  • Add support for interpolation in dotenv: (#433, #434, #453).

v3.4.3 - 2021-05-30

v3.4.2 - 2021-04-23

  • On watch, report which file failed to read (#472).
  • Do not try to catch SIGKILL signal, which are not actually possible (#476).
  • Improve version reporting when building Task from source using Go Modules (#462, #473).

v3.4.1 - 2021-04-17

  • Improve error reporting when parsing YAML: in some situations where you would just see an generic error, you'll now see the actual error with more detail: the YAML line the failed to parse, for example (#467).
  • A JSON Schema was published here and is automatically being used by some editors like Visual Studio Code (#135).
  • Print task name before the command in the log output (#398).

v3.3.0 - 2021-03-20

  • Add support for delegating CLI arguments to commands with -- and a special CLI_ARGS variable (#327).
  • Add a --concurrency (alias -C) flag, to limit the number of tasks that run concurrently. This is useful for heavy workloads. (#345).

v3.2.2 - 2021-01-12

  • Improve performance of --list and --summary by skipping running shell variables for these flags (#332).
  • Fixed a bug where an environment in a Taskfile was not always overridable by the system environment (#425).
  • Fixed environment from .env files not being available as variables (#379).
  • The install script is now working for ARM platforms (#428).

v3.2.1 - 2021-01-09

  • Fixed some bugs and regressions regarding dynamic variables and directories (#426).
  • The slim-sprig package was updated with the upstream sprig.

v3.2.0 - 2021-01-07

  • Fix the .task directory being created in the task directory instead of the Taskfile directory (#247).
  • Fix a bug where dynamic variables (those declared with sh:) were not running in the task directory when the task has a custom dir or it was in an included Taskfile (#384).
  • The watch feature (via the --watch flag) got a few different bug fixes and should be more stable now (#423, #365).

v3.1.0 - 2021-01-03

  • Fix a bug when the checksum up-to-date resolution is used by a task with a custom label: attribute (#412).
  • Starting from this release, we're releasing official ARMv6 and ARM64 binaries for Linux (#375, #418).
  • Task now respects the order of declaration of included Taskfiles when evaluating variables declaring by them (#393).
  • set -e is now automatically set on every command. This was done to fix an issue where multiline string commands wouldn't really fail unless the sentence was in the last line (#403).

v3.0.1 - 2020-12-26

  • Allow use as a library by moving the required packages out of the internal directory (#358).
  • Do not error if a specified dotenv file does not exist (#378, #385).
  • Fix panic when you have empty tasks in your Taskfile (#338, #362).

v3.0.0 - 2020-08-16

  • On v3, all CLI variables will be considered global variables (#336, #341)
  • Add support to .env like files (#324, #356).
  • Add label: to task so you can override the task name in the logs ([#321](https://github.com/go-task/task/issues/321), #337).
  • Refactor how variables work on version 3 (#311).
  • Disallow expansions on v3 since it has no effect.
  • Taskvars.yml is not automatically included anymore.
  • Taskfile_{{OS}}.yml is not automatically included anymore.
  • Allow interpolation on includes, so you can manually include a Taskfile based on operation system, for example.
  • Expose .TASK variable in templates with the task name (#252).
  • Implement short task syntax (#194, #240).
  • Added option to make included Taskfile run commands on its own directory (#260, #144)
  • Taskfiles in version 1 are not supported anymore (#237).
  • Added global method: option. With this option, you can set a default method to all tasks in a Taskfile (#246).
  • Changed default method from timestamp to checksum (#246).
  • New magic variables are now available when using status:: .TIMESTAMP which contains the greatest modification date from the files listed in sources:, and .CHECKSUM, which contains a checksum of all files listed in status:. This is useful for manual checking when using external, or even remote, artifacts when using status: (#216).
  • We're now using slim-sprig instead of sprig, which allowed a file size reduction of about 22% (#219).
  • We now use some colors on Task output to better distinguish message types - commands are green, errors are red, etc (#207).

v2.8.1 - 2020-05-20

  • Fix error code for the --help flag (#300, #330).
  • Print version to stdout instead of stderr (#299, #329).
  • Supress context errors when using the --watch flag (#313, #317).
  • Support templating on description (#276, #283).

v2.8.0 - 2019-12-07

  • Add --parallel flag (alias -p) to run tasks given by the command line in parallel (#266).
  • Fixed bug where calling the task CLI only informing global vars would not execute the default task.
  • Add hability to silent all tasks by adding silent: true a the root of the Taskfile.

v2.7.1 - 2019-11-10

  • Fix error being raised when exit 0 was called (#251).

v2.7.0 - 2019-09-22

  • Fixed panic bug when assigning a global variable (#229, #243).
  • A task with method: checksum will now re-run if generated files are deleted (#228, #238).

v2.6.0 - 2019-07-21

  • Fixed some bugs regarding minor version checks on version:.
  • Add preconditions: to task (#205).
  • Create directory informed on dir: if it doesn't exist (#209, #211).
  • We now have a --taskfile flag (alias -t), which can be used to run another Taskfile (other than the default Taskfile.yml) (#221).
  • It's now possible to install Task using Homebrew on Linux (go-task/homebrew-tap[#1](https://github.com/go-task/task/issues/1)).

v2.5.2 - 2019-05-11

2.5.1 - 2019-04-27

  • Fixed some issues with interactive command line tools, where sometimes the output were not being shown, and similar issues (#114, #190, #200).
  • Upgraded go-yaml/yaml from v2 to v3.

v2.5.0 - 2019-03-16

v2.4.0 - 2019-02-21

  • Allow calling a task of the root Taskfile from an included Taskfile by prefixing it with : (#161, #172).
  • Add flag to override the output option (#173).
  • Fix bug where Task was persisting the new checksum on the disk when the Dry Mode is enabled (#166).
  • Fix file timestamp issue when the file name has spaces (#176).
  • Mitigating path expanding issues on Windows (#170).

v2.3.0 - 2019-01-02

  • On Windows, Task can now be installed using Scoop (#152).
  • Fixed issue with file/directory globing (#153).
  • Added ability to globally set environment variables (#138, #159).

v2.2.1 - 2018-12-09

  • This repository now uses Go Modules (#143). We'll still keep the vendor directory in sync for some time, though;
  • Fixing a bug when the Taskfile has no tasks but includes another Taskfile (#150);
  • Fix a bug when calling another task or a dependency in an included Taskfile (#151).

v2.2.0 - 2018-10-25

  • Added support for including other Taskfiles (#98)
    • This should be considered experimental. For now, only including local files is supported, but support for including remote Taskfiles is being discussed. If you have any feedback, please comment on #98.
  • Task now have a dedicated documentation site: https://taskfile.org
    • Thanks to Docsify for making this pretty easy. To check the source code, just take a look at the docs directory of this repository. Contributions to the documentation is really appreciated.

v2.1.1 - 2018-09-17

  • Fix suggestion to use task --init not being shown anymore (when a Taskfile.yml is not found)
  • Fix error when using checksum method and no file exists for a source glob (#131)
  • Fix signal handling when the --watch flag is given (#132)

v2.1.0 - 2018-08-19

  • Add a ignore_error option to task and command (#123)
  • Add a dry run mode (--dry flag) (#126)

v2.0.3 - 2018-06-24

  • Expand environment variables on "dir", "sources" and "generates" (#116)
  • Fix YAML merging syntax (#112)
  • Add ZSH completion (#111)
  • Implement new output option. Please check out the documentation

v2.0.2 - 2018-05-01

  • Fix merging of YAML anchors (#112)

v2.0.1 - 2018-03-11

  • Fixes panic on task --list

v2.0.0 - 2018-03-08

Version 2.0.0 is here, with a new Taskfile format.

Please, make sure to read the Taskfile versions document, since it describes in depth what changed for this version.

  • New Taskfile version 2 (#77)
  • Possibility to have global variables in the Taskfile.yml instead of Taskvars.yml (#66)
  • Small improvements and fixes

v1.4.4 - 2017-11-19

  • Handle SIGINT and SIGTERM (#75);
  • List: print message with there's no task with description;
  • Expand home dir ("~" symbol) on paths (#74);
  • Add Snap as an installation method;
  • Move examples to its own repo;
  • Watch: also walk on tasks called on on "cmds", and not only on "deps";
  • Print logs to stderr instead of stdout (#68);
  • Remove deprecated set keyword;
  • Add checksum based status check, alternative to timestamp based.

v1.4.3 - 2017-09-07

  • Allow assigning variables to tasks at run time via CLI (#33)
  • Added suport for multiline variables from sh (#64)
  • Fixes env: remove square braces and evaluate shell (#62)
  • Watch: change watch library and few fixes and improvements
  • When use watching, cancel and restart long running process on file change (#59 and #60)

v1.4.2 - 2017-07-30

  • Flag to set directory of execution
  • Always echo command if is verbose mode
  • Add silent mode to disable echoing of commands
  • Fixes and improvements of variables (#56)

v1.4.1 - 2017-07-15

  • Allow use of YAML for dynamic variables instead of $ prefix
    • VAR: {sh: echo Hello} instead of VAR: $echo Hello
  • Add --list (or -l) flag to print existing tasks
  • OS specific Taskvars file (e.g. Taskvars_windows.yml, Taskvars_linux.yml, etc)
  • Consider task up-to-date on equal timestamps (#49)
  • Allow absolute path in generates section (#48)
  • Bugfix: allow templating when calling deps (#42)
  • Fix panic for invalid task in cyclic dep detection
  • Better error output for dynamic variables in Taskvars.yml (#41)
  • Allow template evaluation in parameters

v1.4.0 - 2017-07-06

  • Cache dynamic variables
  • Add verbose mode (-v flag)
  • Support to task parameters (overriding vars) (#31) (#32)
  • Print command, also when "set:" is specified (#35)
  • Improve task command help text (#35)

v1.3.1 - 2017-06-14

  • Fix glob not working on commands (#28)
  • Add ExeExt template function
  • Add --init flag to create a new Taskfile
  • Add status option to prevent task from running (#27)
  • Allow interpolation on generates and sources attributes (#26)

v1.3.0 - 2017-04-24

  • Migrate from os/exec.Cmd to a native Go sh/bash interpreter
    • This is a potentially breaking change if you use Windows.
    • Now, cmd is not used anymore on Windows. Always use Bash-like syntax for your commands, even on Windows.
  • Add "ToSlash" and "FromSlash" to template functions
  • Use functions defined on github.com/Masterminds/sprig
  • Do not redirect stdin while running variables commands
  • Using context and errgroup packages (this will make other tasks to be cancelled, if one returned an error)

v1.2.0 - 2017-04-02

  • More tests and Travis integration
  • Watch a task (experimental)
  • Possibility to call another task
  • Fix "=" not being reconized in variables/environment variables
  • Tasks can now have a description, and help will print them (#10)
  • Task dependencies now run concurrently
  • Support for a default task (#16)

v1.1.0 - 2017-03-08

  • Support for YAML, TOML and JSON (#1)
  • Support running command in another directory (#4)
  • --force or -f flag to force execution of task even when it's up-to-date
  • Detection of cyclic dependencies (#5)
  • Support for variables (#6, #9, #14)
  • Operation System specific commands and variables (#13)

v1.0.0 - 2017-02-28

  • Add LICENSE file
+ \ No newline at end of file diff --git a/fr-FR/community/index.html b/fr-FR/community/index.html index 711415ef..e676c94a 100644 --- a/fr-FR/community/index.html +++ b/fr-FR/community/index.html @@ -10,13 +10,13 @@ - +

Communauté

Certains travaux d'amélioration de l'écosystème Task sont réalisés par la communauté, que ce soit des méthodes d'installation ou des intégrations avec l'éditeur de code. Moi (l'auteur) suis reconnaissant envers tout le monde qui m'aide à améliorer l'expérience globale.

Traductions

@DeronW maintient la traduction Chinoise du site sur ce dépôt.

Intégrations

Un grand nombre de nos intégrations sont apportées et maintenues par la communauté. Vous pouvez voir la liste complète des intégrations de la communauté ici.

Méthodes d'installation

Certaines méthodes d'installation sont maintenues par un tiers :

Plus d’infos

Aussi, merci à tous les contributeurs, contributeurs financiers, tous ceux qui ont signalé des bugs et ont répondu aux questions.

Si vous voyez quelque chose qui manque dans ce document, veuillez soumettre une pull request.

- + \ No newline at end of file diff --git a/fr-FR/contributing/index.html b/fr-FR/contributing/index.html index 04c81808..29ae03ba 100644 --- a/fr-FR/contributing/index.html +++ b/fr-FR/contributing/index.html @@ -10,13 +10,13 @@ - +

Contributing

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

note

This document applies to the core Task repository and Task for Visual Studio Code.

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 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. It is also required if you want to contribute to the Visual Studio Code extension.
  • 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. Go code should be formatted by gofumpt and linted using golangci-lint. Any Markdown or TypeScript files should be formatted and linted by Prettier. This style is enforced by our CI to ensure that we have a consistent style across the project. You can use the task lint command to lint the code locally and the task lint:fix command to automatically fix any issues that are found.
  • Documentation - Ensure that you add/update any relevant documentation. See 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>.

To run Task for Visual Studio Code, you can open the project in VSCode and hit F5 (or whatever you debug keybind is set to). This will open a new VSCode window with the extension running. Debugging this way is recommended as it will allow you to set breakpoints and step through the code. Otherwise, you can run task package which will generate a .vsix file that can be used to manually install the extension.

Updating documentation

Task uses Docusaurus to host a documentation server. The code for this is located in the core Task repository. 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 (enforced by Prettier).

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

A lot of Task's tests 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 should ensure that the functionality you are adding will continue to work in the future. Existing tests may also need updating if you have changed Task's behavior.

You may also consider adding unit tests for any new functions you have added. The unit tests should follow the Go convention of being location in a file named *_test.go in the same package as the code being tested.

3. Committing your code

Try to write meaningful commit messages and avoid having too many commits on the PR. Most PRs should likely have a single commit (although for bigger PRs it may be reasonable to split it in a few). Git squash and rebase is your friend!

If you're not sure how to format your commit message, check out Conventional Commits. This style is not enforced, but it is a good way to make your commit messages more readable and consistent.

4. Submitting a PR

  • Describe your changes - Ensure that you provide a comprehensive description of your changes.
  • Issue/PR links - Link any previous work such as related issues or PRs. Please describe how your changes differ to/extend this work.
  • Examples - Add any examples or screenshots that you think are useful to demonstrate the 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 for Task or Task for Visual Studio Code. 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/fr-FR/donate/index.html b/fr-FR/donate/index.html index ad875a25..4ccacfbd 100644 --- a/fr-FR/donate/index.html +++ b/fr-FR/donate/index.html @@ -10,13 +10,13 @@ - +

Faire un don

Si vous trouvez ce projet utile, vous pouvez envisager de faire un don en utilisant l'un des canaux listés ci-dessous.

C'est juste une façon de nous dire "merci", il ne vous donnera pas d'avantages comme une priorité élevée sur des problèmes ou des choses similaires.

Les entreprises qui font un don d'au moins 50$/mois seront présentées comme un "Sponsor Or" sur la page d'accueil du site and sur le README du dépôt GitHub. Prenez contact avec @andreynering avec le logo que vous voulez afficher. Cependant, les entreprises suspectes (jeux, casinos, etc) ne seront pas autorisées.

Sponsors GitHub

La façon préférée de faire un don aux mainteneurs du projet est d'utiliser les sponsors GitHub. Utilisez simplement le lien suivant pour faire votre don :

Open Collective

Si vous préférez Open Collective vous pouvez faire un don en utilisant ces liens :

PayPal

Vous pouvez aussi faire un don à @andreynering via PayPal :

PIX (Brésil uniquement)

Et si vous êtes Brésilien, vous pouvez également faire un don à @andreynering via PIX en utilisant ce QR Code.

- + \ No newline at end of file diff --git a/fr-FR/faq/index.html b/fr-FR/faq/index.html index 3c6bf426..5756dd04 100644 --- a/fr-FR/faq/index.html +++ b/fr-FR/faq/index.html @@ -10,13 +10,13 @@ - +

FAQ

Cette page contient une liste de question fréquemment posée à propos de Task.

Why won't my task update my shell environment?

This is a limitation of how shells work. Task runs as a subprocess of your current shell, so it can't change the environment of the shell that started it. This limitation is shared by other task runners and build tools too.

A common way to work around this is to create a task that will generate output that can be parsed by your shell. For example, to set an environment variable on your shell you can write a task like this:

my-shell-env:
cmds:
- echo "export FOO=foo"
- echo "export BAR=bar"

Now run eval $(task my-shell-env) and the variables $FOO and $BAR will be available in your shell.

'x' builtin command doesn't work on Windows

The default shell on Windows (cmd and powershell) do not have commands like rm and cp available as builtins. This means that these commands won't work. If you want to make your Taskfile fully cross-platform, you'll need to work around this limitation using one of the following methods:

  • Use the {{OS}} function to run an OS-specific script.
  • Use something like {{if eq OS "windows"}}powershell {{end}}<my_cmd> to detect windows and run the command in Powershell directly.
  • Use a shell on Windows that supports these commands as builtins, such as Git Bash or WSL.

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/fr-FR/index.html b/fr-FR/index.html index 370724bb..be07c528 100644 --- a/fr-FR/index.html +++ b/fr-FR/index.html @@ -10,13 +10,13 @@ - +

Task

Task est un exécuteur de tâches / de build qui vise à être plus simple et facile à utiliser que, par exemple, GNU Make.

Comme il est écrit en Go, Task n'est qu'un binaire unique et n'a aucune dépendance. Cela signifie que vous n'avez pas besoin d'une installation compliquée simplement pour utiliser un outil de build.

Une fois installé, il vous suffit de décrire vos tâches de build en utilisant un simple schéma YAML dans un fichier appelé Taskfile.yml:

Taskfile.yml
version: '3'

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

Et appelez-le en exécutant task hello depuis votre terminal.

L'exemple ci-dessus n'est que le début, vous pouvez jeter un coup d'œil au guide d'utilisation pour vérifier la documentation complète du schéma et les fonctionnalités de Task.

Fonctionnalités

  • Installation facile: il suffit de télécharger un seul binaire, ajoutez le à $PATH et vous avez terminé ! Ou vous pouvez également installer en utilisant Homebrew, Snapcraft ou Scoop si vous le souhaitez.
  • Disponible sur les CIs: en ajoutant cette commande simple à installer sur votre script CI, vous êtes prêt à utiliser Task dans le cadre de votre pipeline CI ;
  • Multi-plateforme : alors que la plupart des outils de compilation ne fonctionnent bien que sous Linux ou macOS, Task prend également en charge Windows grâce à cet interpréteur shell pour Go.
  • Idéal pour la génération de code : vous pouvez facilement empêcher une tâche de s'exécuter si un ensemble donné de fichiers n'ont pas changé depuis le dernier lancement (basé soit sur son horodatage soit son contenu).

Sponsors Or

- + \ No newline at end of file diff --git a/fr-FR/installation/index.html b/fr-FR/installation/index.html index 6cb2c03d..d9e0f8f3 100644 --- a/fr-FR/installation/index.html +++ b/fr-FR/installation/index.html @@ -10,13 +10,13 @@ - +

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 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 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 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
attention

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
conseils

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/fr-FR/integrations/index.html b/fr-FR/integrations/index.html index 4d5da29a..ee14daa5 100644 --- a/fr-FR/integrations/index.html +++ b/fr-FR/integrations/index.html @@ -10,13 +10,13 @@ - +

Integrations

Visual Studio Code Extension

Task has an official extension for Visual Studio Code. The code for this project can be found here. To use this extension, you must have Task v3.23.0+ installed on your system.

This extension provides the following features (and more):

  • View tasks in the sidebar.
  • Run tasks from the sidebar and command palette.
  • Go to definition from the sidebar and command palette.
  • Run last task command.
  • Multi-root workspace support.
  • Initialize a Taskfile in the current workspace.

To get autocompletion and validation for your Taskfile, see the Schema section below.

Task for Visual Studio Code

Schema

This was initially created by @KROSF in this Gist and is now officially maintained in this file and made available at https://taskfile.dev/schema.json. This schema can be used to validate Taskfiles and provide autocompletion in many code editors:

Visual Studio Code

To integrate the schema into VS Code, you need to install the YAML extension by Red Hat. Any Taskfile.yml in your project should automatically be detected and validation/autocompletion should work. If this doesn't work or you want to manually configure it for files with a different name, you can add the following to your settings.json:

// settings.json
{
"yaml.schemas": {
"https://taskfile.dev/schema.json": [
"**/Taskfile.yml",
"./path/to/any/other/taskfile.yml"
]
}
}

You can also configure the schema directly inside of a Taskfile by adding the following comment to the top of the file:

# yaml-language-server: $schema=https://taskfile.dev/schema.json
version: '3'

You can find more information on this in the YAML language server project.

Community Integrations

In addition to our official integrations, there is an amazing community of developers who have created their own integrations for Task:

If you have made something that integrates with Task, please feel free to open a PR to add it to this list.

- + \ No newline at end of file diff --git a/fr-FR/releasing/index.html b/fr-FR/releasing/index.html index 582d9365..dceaeb15 100644 --- a/fr-FR/releasing/index.html +++ b/fr-FR/releasing/index.html @@ -10,13 +10,13 @@ - +

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 main branch (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 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/fr-FR/search/index.html b/fr-FR/search/index.html index 1784e4b6..11461de4 100644 --- a/fr-FR/search/index.html +++ b/fr-FR/search/index.html @@ -10,13 +10,13 @@ - + - + \ No newline at end of file diff --git a/fr-FR/styleguide/index.html b/fr-FR/styleguide/index.html index 8a48120e..36b18bcf 100644 --- a/fr-FR/styleguide/index.html +++ b/fr-FR/styleguide/index.html @@ -10,13 +10,13 @@ - +

Guide de style

Ceci est le guide officiel du style Task pour les fichiers Taskfile.yml. Ce guide contient quelques instructions de base pour garder votre Taskfile propre et familier à autres utilisateurs.

Il contient des directives générales, mais elles ne doivent pas nécessairement être strictement respectées. N'hésitez pas à procéder différemment si vous en avez le besoin ou que vous le souhaitez. Aussi, n'hésitez pas à [ouvrir une issue](https://github. com/go-task/task/issues/new/choose) ou [faire une pull request](https://github. com/go-task/task/compare) pour améliorer ce guide.

Utiliser Taskfile.yml et non taskfile.yml

# bad
taskfile.yml


# good
Taskfile.yml

C'est important, surtout pour les utilisateurs Linux. Windows et MacOS ont un système de fichiers insensibles à la casse, donc taskfile.yml fonctionnera, même si ce n'est pas officiellement supporté. Sur Linux, uniquement Taskfile.yml fonctionnera.

Utiliser les mots-clés dans l'ordre correct

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

Utiliser 2 espaces pour l'indentation

C'est la convention la plus courante pour les fichiers YAML et Task suit cette convention.

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


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

Séparer les sections principales avec un retour à la ligne

# 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:
# ...

Ajouter des retours à la ligne entre les tâches

# 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'

Utiliser des noms de variables en majuscule

# 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}} .

Ne pas mettre d'espaces autour des variables lors de l'utilisation

# bad
version: '3'

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


# good
version: '3'

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

Cette convention est aussi utilisée par la plupart des gens pour n'importe quel modèle Go.

Séparer les mots du nom de la tâche par un tiret

# bad
version: '3'

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


# good
version: '3'

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

Utiliser les deux-points pour nommer les namespaces de tâche

# good
version: '3'

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

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

C'est aussi fait automatiquement quand vous incluez des Taskfiles.

- + \ No newline at end of file diff --git a/fr-FR/taskfile-versions/index.html b/fr-FR/taskfile-versions/index.html index 16cca92c..e23dcbf9 100644 --- a/fr-FR/taskfile-versions/index.html +++ b/fr-FR/taskfile-versions/index.html @@ -10,13 +10,13 @@ - +

Taskfile Versions

The Taskfile syntax and features changed with time. This document explains what changed on each version and how to upgrade your Taskfile.

What the Taskfile version mean

The Taskfile version follows the Task version. E.g. the change to Taskfile version 2 means that Task v2.0.0 should be release to support it.

The version: key on Taskfile accepts a semver string, so either 2, 2.0 or 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:

  • Task's output will now be colored
  • Added support for .env like files
  • Added label: setting to task so one can override how the task name appear in the logs
  • A global method: was added to allow setting the default method, and Task's default changed to checksum
  • Two magic variables were added when using status:: CHECKSUM and TIMESTAMP which contains, respectively, the md5 checksum and greatest modification timestamp of the files listed on sources:
  • Also, the TASK variable is always available with the current task name
  • CLI variables are always treated as global variables
  • Added dir: option to includes to allow choosing on which directory an included Taskfile will run:
includes:
docs:
taskfile: ./docs
dir: ./docs
  • Implemented short task syntax. All below syntaxes are equivalent:
version: '3'

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

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

tasks:
print: echo "Hello, World!"
  • There was a major refactor on how variables are handled. They're now easier to understand. The expansions: setting was removed as it became unncessary. This is the order in which Task will process variables, each level can see the variables set by the previous one and override those.
    • Environment variables
    • Global + CLI variables
    • Call variables
    • Task variables
- + \ No newline at end of file diff --git a/fr-FR/translate/index.html b/fr-FR/translate/index.html index 67c14a15..ef63c8e6 100644 --- a/fr-FR/translate/index.html +++ b/fr-FR/translate/index.html @@ -10,13 +10,13 @@ - +

Traduction

Vous voulez nous aider à traduire cette documentation ? Nous expliquons ci-dessous comment faire.

Ne PAS éditer directement sur le dépôt GitHub les fichiers markdown traduits ! Nous utilisons Crowdin pour permettre aux contributeurs de travailler sur les traductions. Le dépôt est périodiquement mis à jour avec la progression des traductions sur Crowdin.

Si vous voulez avoir accès au projet Crowdin pour pouvoir suggérer des traductions, veuillez demander l'accès sur le canal #traductions sur notre serveur Discord . Si une langue n'est pas encore affichée sur Crowdin, il suffit de demander et nous pouvons la configurer.

- + \ No newline at end of file diff --git a/fr-FR/usage/index.html b/fr-FR/usage/index.html index 089e941c..ba7cd3d1 100644 --- a/fr-FR/usage/index.html +++ b/fr-FR/usage/index.html @@ -10,13 +10,13 @@ - +
-

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 the file tree until it finds one (similar to how git works). When running Task from a subdirectory like this, it will behave as if you ran it from the directory containing the Taskfile.

You can use this functionality along with the special {{.USER_WORKING_DIR}} 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 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: 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 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 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: 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, function-like tasks that have no useful purpose on the command line.

version: '3'

tasks:
build-image-1:
cmds:
- task: build-image
vars:
DOCKER_IMAGE: image-1

build-image:
internal: true
cmds:
- docker build -t {{.DOCKER_IMAGE}} .

Task directory

By default, tasks will be executed in the directory where the Taskfile is located. But you can easily make the task run in another folder, informing 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 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.

conseils

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.

conseils

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. 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 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.

conseils

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 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
conseils

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 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 \ 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 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 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 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 [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
conseils

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 set 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.

- +

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 the file tree until it finds one (similar to how git works). When running Task from a subdirectory like this, it will behave as if you ran it from the directory containing the Taskfile.

You can use this functionality along with the special {{.USER_WORKING_DIR}} 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 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: 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 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 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: 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, function-like tasks that have no useful purpose on the command line.

version: '3'

tasks:
build-image-1:
cmds:
- task: build-image
vars:
DOCKER_IMAGE: image-1

build-image:
internal: true
cmds:
- docker build -t {{.DOCKER_IMAGE}} .

Task directory

By default, tasks will be executed in the directory where the Taskfile is located. But you can easily make the task run in another folder, informing 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 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.

conseils

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' }
silent: true
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"

Using the vars and silent attributes you can choose to pass variables and toggle silent mode on a call-by-call basis:

version: '3'

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

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

The above syntax is also supported in deps.

conseils

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. 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 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.

conseils

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 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
conseils

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 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 \ 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 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 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 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 [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
conseils

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 set 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.

+ \ No newline at end of file diff --git a/pt-BR/404.html b/pt-BR/404.html index 7b36fc00..8deb0827 100644 --- a/pt-BR/404.html +++ b/pt-BR/404.html @@ -10,13 +10,13 @@ - +

Página não encontrada

Não foi possível encontrar o que você está procurando.

Entre em contato com o proprietário do site que lhe trouxe para cá e lhe informe que o link está quebrado.

- + \ No newline at end of file diff --git a/pt-BR/api/index.html b/pt-BR/api/index.html index 7358b4b9..d54efd47 100644 --- a/pt-BR/api/index.html +++ b/pt-BR/api/index.html @@ -10,13 +10,13 @@ - +
-

Referência da API

CLI

O comando "task" tem a seguinte sintaxe:

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

Se -- é informado, todos os argumentos remanescentes serão atribuídos a uma variável especial chamada CLI_ARGS

AbreviaçãoModificadorTipoPredefiniçãoDescrição
-c--colorbooltrueSaída colorida. Habilitado por padrão. Defina o modificador como false ou use NO_COLOR=1 para desativar.
-C--concurrencyint0Limitar número de tarefas a serem executadas simultaneamente. Zero significa ilimitado.
-d--dirstringPasta atualDefine a pasta de execução.
-n--dryboolfalseCompila e imprime as tarefas na ordem em que elas seriam executadas, sem executá-las.
-x--exit-codeboolfalseFaz com que o código de saída do comando sendo executado seja repassado pelo Task.
-f--forceboolfalseForça a execução mesmo quando a tarefa está atualizada.
-g--globalboolfalseExecuta o Taskfile global, de $HOME/Taskfile.{yml,yaml}.
-h--helpboolfalseMostra a ajuda do Task.
-i--initboolfalseCria um novo Taskfile.yml na pasta atual.
-I--intervalstring5sDefine um intervalo de tempo diferente ao usar --watch, o padrão sendo 5 segundos. Este valor deve ser um Go Duration válido.
-l--listboolfalseLista as tarefas com descrição do Taskfile atual.
-a--list-allboolfalseLista todas as tarefas, com ou sem descrição.
--sortstringdefaultAltera a ordem das tarefas quando listadas.
--jsonboolfalseImprime a saída em JSON.
-o--outputstringO padrão é o que está definido no Taskfile, ou então intervealed.Configura o estilo de saída: [interleaved/group/prefixed].
--output-group-beginstringFormato de mensagem a imprimir antes da saída agrupada de uma tarefa.
--output-group-endstringFormato de mensagem a imprimir depois da saída agrupada de uma tarefa.
--output-group-error-onlyboolfalseOculta saída dos comandos que terminarem sem erro.
-p--parallelboolfalseExecuta as tarefas fornecidas na linha de comando em paralelo.
-s--silentboolfalseDesabilita impressão.
--statusboolfalseSai com código de saída diferente de zero se alguma das tarefas especificadas não estiver atualizada.
--summaryboolfalseMostrar resumo sobre uma tarefa.
-t--taskfilestringTaskfile.yml ou Taskfile.yaml
-v--verboseboolfalseHabilita modo verboso.
--versionboolfalseMostrar versão do Task.
-w--watchboolfalseHabilita o monitoramento de tarefas.

Códigos de saída

O Task às vezes fecha com códigos de saída específicos. Estes códigos são divididos em três grupos com os seguintes intervalos:

  • Erros gerais (0-99)
  • Erros de Taskfile (100-199)
  • Erros de execução de tarefa (200-299)

Uma lista completa dos códigos de saída e suas descrições podem ser encontradas abaixo:

CódigoDescrição
0Sucesso
1Um erro desconhecido ocorreu
100Nenhum Arquivo foi encontrado
101Um arquivo Taskfile já existe ao tentar inicializar um
102O arquivo Taskfile é inválido ou não pode ser analisado
200A tarefa especificada não pôde ser encontrada
201Ocorreu um erro ao executar um comando dentro de uma tarefa
202O usuário tentou invocar uma tarefa que é interna
203Há várias tarefas com o mesmo nome ou apelido
204Uma tarefa foi chamada muitas vezes

Esses códigos também podem ser encontrados no repositório em errors/errors.go.

info

When Task is run with the -x/--exit-code flag, the exit code of any failed commands will be passed through to the user instead.

Saída em JSON

Quando estiver usando o modificador --json em combinação com o modificador --list ou --list-all, a saída será um objeto JSON com a seguinte estrutura:

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

Variáveis Especiais

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.
dica

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.
dica

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
- +

Referência da API

CLI

O comando "task" tem a seguinte sintaxe:

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

Se -- é informado, todos os argumentos remanescentes serão atribuídos a uma variável especial chamada CLI_ARGS

AbreviaçãoModificadorTipoPredefiniçãoDescrição
-c--colorbooltrueSaída colorida. Habilitado por padrão. Defina o modificador como false ou use NO_COLOR=1 para desativar.
-C--concurrencyint0Limitar número de tarefas a serem executadas simultaneamente. Zero significa ilimitado.
-d--dirstringPasta atualDefine a pasta de execução.
-n--dryboolfalseCompila e imprime as tarefas na ordem em que elas seriam executadas, sem executá-las.
-x--exit-codeboolfalseFaz com que o código de saída do comando sendo executado seja repassado pelo Task.
-f--forceboolfalseForça a execução mesmo quando a tarefa está atualizada.
-g--globalboolfalseExecuta o Taskfile global, de $HOME/Taskfile.{yml,yaml}.
-h--helpboolfalseMostra a ajuda do Task.
-i--initboolfalseCria um novo Taskfile.yml na pasta atual.
-I--intervalstring5sDefine um intervalo de tempo diferente ao usar --watch, o padrão sendo 5 segundos. Este valor deve ser um Go Duration válido.
-l--listboolfalseLista as tarefas com descrição do Taskfile atual.
-a--list-allboolfalseLista todas as tarefas, com ou sem descrição.
--sortstringdefaultAltera a ordem das tarefas quando listadas.
--jsonboolfalseImprime a saída em JSON.
-o--outputstringO padrão é o que está definido no Taskfile, ou então intervealed.Configura o estilo de saída: [interleaved/group/prefixed].
--output-group-beginstringFormato de mensagem a imprimir antes da saída agrupada de uma tarefa.
--output-group-endstringFormato de mensagem a imprimir depois da saída agrupada de uma tarefa.
--output-group-error-onlyboolfalseOculta saída dos comandos que terminarem sem erro.
-p--parallelboolfalseExecuta as tarefas fornecidas na linha de comando em paralelo.
-s--silentboolfalseDesabilita impressão.
--statusboolfalseSai com código de saída diferente de zero se alguma das tarefas especificadas não estiver atualizada.
--summaryboolfalseMostrar resumo sobre uma tarefa.
-t--taskfilestringTaskfile.yml ou Taskfile.yaml
-v--verboseboolfalseHabilita modo verboso.
--versionboolfalseMostrar versão do Task.
-w--watchboolfalseHabilita o monitoramento de tarefas.

Códigos de saída

O Task às vezes fecha com códigos de saída específicos. Estes códigos são divididos em três grupos com os seguintes intervalos:

  • Erros gerais (0-99)
  • Erros de Taskfile (100-199)
  • Erros de execução de tarefa (200-299)

Uma lista completa dos códigos de saída e suas descrições podem ser encontradas abaixo:

CódigoDescrição
0Sucesso
1Um erro desconhecido ocorreu
100Nenhum Arquivo foi encontrado
101Um arquivo Taskfile já existe ao tentar inicializar um
102O arquivo Taskfile é inválido ou não pode ser analisado
200A tarefa especificada não pôde ser encontrada
201Ocorreu um erro ao executar um comando dentro de uma tarefa
202O usuário tentou invocar uma tarefa que é interna
203Há várias tarefas com o mesmo nome ou apelido
204Uma tarefa foi chamada muitas vezes

Esses códigos também podem ser encontrados no repositório em errors/errors.go.

info

When Task is run with the -x/--exit-code flag, the exit code of any failed commands will be passed through to the user instead.

Saída em JSON

Quando estiver usando o modificador --json em combinação com o modificador --list ou --list-all, a saída será um objeto JSON com a seguinte estrutura:

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

Variáveis Especiais

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.
silentboolfalseHides task name and command from output. The command's output will still be redirected to STDOUT and STDERR.
dica

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.
dica

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/pt-BR/assets/js/19a1e173.cc992dbe.js b/pt-BR/assets/js/19a1e173.cc992dbe.js deleted file mode 100644 index c6d28083..00000000 --- a/pt-BR/assets/js/19a1e173.cc992dbe.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[19],{3905:function(t,e,a){a.d(e,{Zo:function(){return h},kt:function(){return d}});var i=a(7294);function s(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function n(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,i)}return a}function l(t){for(var e=1;e=0||(s[a]=t[a]);return s}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(s[a]=t[a])}return s}var o=i.createContext({}),k=function(t){var e=i.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},h=function(t){var e=k(t.components);return i.createElement(o.Provider,{value:e},t.children)},m="mdxType",p={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},u=i.forwardRef((function(t,e){var a=t.components,s=t.mdxType,n=t.originalType,o=t.parentName,h=r(t,["components","mdxType","originalType","parentName"]),m=k(a),u=s,d=m["".concat(o,".").concat(u)]||m[u]||p[u]||n;return a?i.createElement(d,l(l({ref:e},h),{},{components:a})):i.createElement(d,l({ref:e},h))}));function d(t,e){var a=arguments,s=e&&e.mdxType;if("string"==typeof t||s){var n=a.length,l=new Array(n);l[0]=u;var r={};for(var o in e)hasOwnProperty.call(e,o)&&(r[o]=e[o]);r.originalType=t,r[m]="string"==typeof t?t:s,l[1]=r;for(var k=2;k=0||(s[a]=t[a]);return s}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(s[a]=t[a])}return s}var o=i.createContext({}),k=function(t){var e=i.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},h=function(t){var e=k(t.components);return i.createElement(o.Provider,{value:e},t.children)},m="mdxType",p={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},u=i.forwardRef((function(t,e){var a=t.components,s=t.mdxType,n=t.originalType,o=t.parentName,h=r(t,["components","mdxType","originalType","parentName"]),m=k(a),u=s,d=m["".concat(o,".").concat(u)]||m[u]||p[u]||n;return a?i.createElement(d,l(l({ref:e},h),{},{components:a})):i.createElement(d,l({ref:e},h))}));function d(t,e){var a=arguments,s=e&&e.mdxType;if("string"==typeof t||s){var n=a.length,l=new Array(n);l[0]=u;var r={};for(var o in e)hasOwnProperty.call(e,o)&&(r[o]=e[o]);r.originalType=t,r[m]="string"==typeof t?t:s,l[1]=r;for(var k=2;k=0||(l[a]=t[a]);return l}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(l[a]=t[a])}return l}var o=n.createContext({}),m=function(t){var e=n.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},p=function(t){var e=m(t.components);return n.createElement(o.Provider,{value:e},t.children)},k="mdxType",N={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,l=t.mdxType,r=t.originalType,o=t.parentName,p=d(t,["components","mdxType","originalType","parentName"]),k=m(a),u=l,s=k["".concat(o,".").concat(u)]||k[u]||N[u]||r;return a?n.createElement(s,i(i({ref:e},p),{},{components:a})):n.createElement(s,i({ref:e},p))}));function s(t,e){var a=arguments,l=e&&e.mdxType;if("string"==typeof t||l){var r=a.length,i=new Array(r);i[0]=u;var d={};for(var o in e)hasOwnProperty.call(e,o)&&(d[o]=e[o]);d.originalType=t,d[k]="string"==typeof t?t:l,i[1]=d;for(var m=2;m=0||(l[a]=t[a]);return l}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(l[a]=t[a])}return l}var o=n.createContext({}),m=function(t){var e=n.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},p=function(t){var e=m(t.components);return n.createElement(o.Provider,{value:e},t.children)},k="mdxType",N={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},u=n.forwardRef((function(t,e){var a=t.components,l=t.mdxType,r=t.originalType,o=t.parentName,p=d(t,["components","mdxType","originalType","parentName"]),k=m(a),u=l,s=k["".concat(o,".").concat(u)]||k[u]||N[u]||r;return a?n.createElement(s,i(i({ref:e},p),{},{components:a})):n.createElement(s,i({ref:e},p))}));function s(t,e){var a=arguments,l=e&&e.mdxType;if("string"==typeof t||l){var r=a.length,i=new Array(r);i[0]=u;var d={};for(var o in e)hasOwnProperty.call(e,o)&&(d[o]=e[o]);d.originalType=t,d[k]="string"==typeof t?t:l,i[1]=d;for(var m=2;m=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:"guia-de-uso"},"Guia de Uso"),(0,i.kt)("h2",{id:"primeiros-passos"},"Primeiros passos"),(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")," attribute should contain the commands of a task. The example below allows compiling a Go app and uses ",(0,i.kt)("a",{parentName:"p",href:"https://esbuild.github.io/"},"esbuild")," to concat and 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 interpreter. So you can write sh/bash commands, and it will work even on Windows, where ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"bash")," are usually not available. Just remember any executable 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 committed version (",(0,i.kt)("inlineCode",{parentName:"p"},".dist"),") while still allowing individual users to override the Taskfile by adding an additional ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," (which would be on ",(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 the file tree until it finds one (similar to how ",(0,i.kt)("inlineCode",{parentName:"p"},"git")," works). When running Task from a subdirectory like this, it will behave as if you ran it from the directory 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}}")," variable to create some very useful reusable tasks. For example, if you have a monorepo with directories for each microservice, you can ",(0,i.kt)("inlineCode",{parentName:"p"},"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:"),(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 ",(0,i.kt)("inlineCode",{parentName:"p"},"")," directory contains a ",(0,i.kt)("inlineCode",{parentName:"p"},"docker-compose.yml"),", the Docker composition will 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 home directory instead of your working directory. In short, Task will look for a 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 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 default, 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 variable can be very handy here to run stuff on the directory you're calling ",(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 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 just 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:")," setting:"),(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 variables 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 the 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 namespace. 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 ",(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 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")," if it exists (for example: ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_windows.yml"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_linux.yml")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"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:"),(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 the Taskfile is in another directory, but you can force its tasks to run in 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 Taskfile 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 the 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 internal as well (see the ",(0,i.kt)("a",{parentName:"p",href:"#internal-tasks"},"Internal tasks")," section below). This is useful when including utility tasks that are not intended to be used directly 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 for 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"),". This works in the same way as ",(0,i.kt)("a",{parentName:"p",href:"#task-aliases"},"task aliases")," and can be used together 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 variables in the including Taskfile! If you want a variable in an included Taskfile to be overridable, use the ",(0,i.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/defaults.html"},"default function"),": ",(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 not appear in the output when running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --list|--list-all"),". Other tasks may call internal tasks in the usual way. This is useful for creating reusable, function-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 located. But you can easily make the task run in another folder, informing ",(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 another. If you want to force tasks to run serially, take a look at the ",(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 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 ",(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 performance."),(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 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 manner 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 silent: true\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 using the ",(0,i.kt)("inlineCode",{parentName:"p"},"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."),(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 defined by the Go language ",(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 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:"),(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,"Using the ",(0,i.kt)("inlineCode",{parentName:"p"},"vars")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"silent")," attributes you can choose to pass variables and toggle ",(0,i.kt)("a",{parentName:"p",href:"#silent-mode"},"silent mode")," on a call-by-call basis:"),(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 silent: true\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 ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"included Taskfile"),", add a leading ",(0,i.kt)("inlineCode",{parentName:"p"},":")," like this: ",(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 files, 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 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 ",(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, instead 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. You can even combine the two. See the documentation for ",(0,i.kt)("a",{parentName:"p",href:"#using-programmatic-checks-to-indicate-a-task-is-up-to-date"},"status")," for an example."),(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 directory. Most of the time, you'll want to have this directory on ",(0,i.kt)("inlineCode",{parentName:"p"},".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)."),(0,i.kt)("p",{parentName:"admonition"},"If you want these files to be stored in another directory, you can set a ",(0,i.kt)("inlineCode",{parentName:"p"},"TASK_TEMP_DIR")," environment variable in your machine. It can contain a relative path like ",(0,i.kt)("inlineCode",{parentName:"p"},"tmp/task")," that will be interpreted as relative to the project directory, or an absolute or home path like ",(0,i.kt)("inlineCode",{parentName:"p"},"/tmp/.task")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"~/.task")," (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 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."),(0,i.kt)("p",{parentName:"admonition"},"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.")),(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 inform the source files. When 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 is 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"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 ",(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 interpolation within ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," commands, depending on the method assigned to 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 can 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 up-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 the 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")," to have a task run if either the the source/generated artifacts changes, or the programmatic 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 of ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," checks. That is, if you need a certain set of conditions to be ",(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 ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," lines, except they support ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," expansion, 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 a 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 precondition is not met - the calling task will fail. Note that a task executed with 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 executing tasks that depend on it, a ",(0,i.kt)("inlineCode",{parentName:"p"},"precondition")," will fail a task, along with 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 when 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 of the Taskfile to change 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 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 passed 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 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 (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 (Windows) tasks also accept a similar style when not at the beginning of the 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. 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."),(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 ",(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 task finishes. The difference with just putting it as the last command is that 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 well:"),(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 ",(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 commands 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. 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")," are 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", "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 "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"},"\\")," path 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 converts 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"')," 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. Task uses ",(0,i.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote"},"this Go function")," for 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 ",(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 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. The 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. If 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 quicker to run tasks with long or hard-to-type names. You can use them on the command line, when ",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"calling sub-tasks")," in your Taskfile and when ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"including tasks")," with aliases from another Taskfile. They can also be used together with ",(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, up-to-date messages to STDOUT, etc. In this case, you can just set ",(0,i.kt)("inlineCode",{parentName:"p"},"label:"),", which 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 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 that 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. Given 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"),". However, 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 for all commands. Nevertheless, keep in mind that this option will not propagate to 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 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."),(0,i.kt)("p",null,"To make this more customizable, there are currently three different output options 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 finishes, so you will not have live feedback for commands that take a long time to 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 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 ",(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")," or ",(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 on 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"[task-name]")," as the prefix, but you can customize the prefix for a command with 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 weirdly, especially when the ",(0,i.kt)("a",{parentName:"p",href:"#output-syntax"},"output mode")," is set to something other than ",(0,i.kt)("inlineCode",{parentName:"p"},"interleaved")," (the default), or when interactive apps are run in parallel 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 will 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 an 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 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 ",(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"))," and ",(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"))," builtins. 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 ",(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 task again. This requires the ",(0,i.kt)("inlineCode",{parentName:"p"},"sources")," attribute to be given, so 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 either setting ",(0,i.kt)("inlineCode",{parentName:"p"},"interval: '500ms'")," in the root of the Taskfile passing it as an argument like ",(0,i.kt)("inlineCode",{parentName:"p"},"--interval=500ms"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/pt-BR/assets/js/b9256968.ae378286.js b/pt-BR/assets/js/b9256968.ae378286.js deleted file mode 100644 index f9f7ae14..00000000 --- a/pt-BR/assets/js/b9256968.ae378286.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[629],{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:"guia-de-uso"},"Guia de Uso"),(0,i.kt)("h2",{id:"primeiros-passos"},"Primeiros passos"),(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")," attribute should contain the commands of a task. The example below allows compiling a Go app and uses ",(0,i.kt)("a",{parentName:"p",href:"https://esbuild.github.io/"},"esbuild")," to concat and 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 interpreter. So you can write sh/bash commands, and it will work even on Windows, where ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"bash")," are usually not available. Just remember any executable 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 committed version (",(0,i.kt)("inlineCode",{parentName:"p"},".dist"),") while still allowing individual users to override the Taskfile by adding an additional ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," (which would be on ",(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 the file tree until it finds one (similar to how ",(0,i.kt)("inlineCode",{parentName:"p"},"git")," works). When running Task from a subdirectory like this, it will behave as if you ran it from the directory 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}}")," variable to create some very useful reusable tasks. For example, if you have a monorepo with directories for each microservice, you can ",(0,i.kt)("inlineCode",{parentName:"p"},"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:"),(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 ",(0,i.kt)("inlineCode",{parentName:"p"},"")," directory contains a ",(0,i.kt)("inlineCode",{parentName:"p"},"docker-compose.yml"),", the Docker composition will 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 home directory instead of your working directory. In short, Task will look for a 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 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 default, 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 variable can be very handy here to run stuff on the directory you're calling ",(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 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 just 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:")," setting:"),(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 variables 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 the 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 namespace. 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 ",(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 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")," if it exists (for example: ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_windows.yml"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_linux.yml")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"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:"),(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 the Taskfile is in another directory, but you can force its tasks to run in 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 Taskfile 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 the 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 internal as well (see the ",(0,i.kt)("a",{parentName:"p",href:"#internal-tasks"},"Internal tasks")," section below). This is useful when including utility tasks that are not intended to be used directly 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 for 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"),". This works in the same way as ",(0,i.kt)("a",{parentName:"p",href:"#task-aliases"},"task aliases")," and can be used together 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 variables in the including Taskfile! If you want a variable in an included Taskfile to be overridable, use the ",(0,i.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/defaults.html"},"default function"),": ",(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 not appear in the output when running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --list|--list-all"),". Other tasks may call internal tasks in the usual way. This is useful for creating reusable, function-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 located. But you can easily make the task run in another folder, informing ",(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 another. If you want to force tasks to run serially, take a look at the ",(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 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 ",(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 performance."),(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 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 manner 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 using the ",(0,i.kt)("inlineCode",{parentName:"p"},"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."),(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 defined by the Go language ",(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 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:"),(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")," attribute:"),(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 ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"included Taskfile"),", add a leading ",(0,i.kt)("inlineCode",{parentName:"p"},":")," like this: ",(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 files, 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 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 ",(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, instead 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. You can even combine the two. See the documentation for ",(0,i.kt)("a",{parentName:"p",href:"#using-programmatic-checks-to-indicate-a-task-is-up-to-date"},"status")," for an example."),(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 directory. Most of the time, you'll want to have this directory on ",(0,i.kt)("inlineCode",{parentName:"p"},".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)."),(0,i.kt)("p",{parentName:"admonition"},"If you want these files to be stored in another directory, you can set a ",(0,i.kt)("inlineCode",{parentName:"p"},"TASK_TEMP_DIR")," environment variable in your machine. It can contain a relative path like ",(0,i.kt)("inlineCode",{parentName:"p"},"tmp/task")," that will be interpreted as relative to the project directory, or an absolute or home path like ",(0,i.kt)("inlineCode",{parentName:"p"},"/tmp/.task")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"~/.task")," (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 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."),(0,i.kt)("p",{parentName:"admonition"},"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.")),(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 inform the source files. When 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 is 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"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 ",(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 interpolation within ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," commands, depending on the method assigned to 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 can 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 up-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 the 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")," to have a task run if either the the source/generated artifacts changes, or the programmatic 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 of ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," checks. That is, if you need a certain set of conditions to be ",(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 ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," lines, except they support ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," expansion, 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 a 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 precondition is not met - the calling task will fail. Note that a task executed with 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 executing tasks that depend on it, a ",(0,i.kt)("inlineCode",{parentName:"p"},"precondition")," will fail a task, along with 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 when 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 of the Taskfile to change 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 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 passed 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 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 (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 (Windows) tasks also accept a similar style when not at the beginning of the 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. 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."),(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 ",(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 task finishes. The difference with just putting it as the last command is that 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 well:"),(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 ",(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 commands 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. 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")," are 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", "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 "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"},"\\")," path 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 converts 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"')," 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. Task uses ",(0,i.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote"},"this Go function")," for 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 ",(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 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. The 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. If 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 quicker to run tasks with long or hard-to-type names. You can use them on the command line, when ",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"calling sub-tasks")," in your Taskfile and when ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"including tasks")," with aliases from another Taskfile. They can also be used together with ",(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, up-to-date messages to STDOUT, etc. In this case, you can just set ",(0,i.kt)("inlineCode",{parentName:"p"},"label:"),", which 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 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 that 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. Given 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"),". However, 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 for all commands. Nevertheless, keep in mind that this option will not propagate to 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 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."),(0,i.kt)("p",null,"To make this more customizable, there are currently three different output options 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 finishes, so you will not have live feedback for commands that take a long time to 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 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 ",(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")," or ",(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 on 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"[task-name]")," as the prefix, but you can customize the prefix for a command with 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 weirdly, especially when the ",(0,i.kt)("a",{parentName:"p",href:"#output-syntax"},"output mode")," is set to something other than ",(0,i.kt)("inlineCode",{parentName:"p"},"interleaved")," (the default), or when interactive apps are run in parallel 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 will 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 an 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 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 ",(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"))," and ",(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"))," builtins. 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 ",(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 task again. This requires the ",(0,i.kt)("inlineCode",{parentName:"p"},"sources")," attribute to be given, so 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 either setting ",(0,i.kt)("inlineCode",{parentName:"p"},"interval: '500ms'")," in the root of the Taskfile passing it as an argument like ",(0,i.kt)("inlineCode",{parentName:"p"},"--interval=500ms"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/pt-BR/assets/js/runtime~main.03785978.js b/pt-BR/assets/js/runtime~main.6a16ffea.js similarity index 95% rename from pt-BR/assets/js/runtime~main.03785978.js rename to pt-BR/assets/js/runtime~main.6a16ffea.js index aecc8a71..a41f8830 100644 --- a/pt-BR/assets/js/runtime~main.03785978.js +++ b/pt-BR/assets/js/runtime~main.6a16ffea.js @@ -1 +1 @@ -!function(){"use strict";var e,t,n,r,o,f={},a={};function u(e){var t=a[e];if(void 0!==t)return t.exports;var n=a[e]={id:e,loaded:!1,exports:{}};return f[e].call(n.exports,n,n.exports,u),n.loaded=!0,n.exports}u.m=f,u.c=a,e=[],u.O=function(t,n,r,o){if(!n){var f=1/0;for(d=0;d=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/"+({19:"19a1e173",53:"935f2afb",133:"f1d66b0d",154:"4a59651f",176:"d23ae857",211:"f2ae99f3",259:"fcec3894",364:"ad872c75",385:"8420b8df",418:"19b14462",430:"6905f42e",445:"4a484b02",467:"e8ea0ffb",514:"1be78505",595:"d0766b26",629:"b9256968",791:"31fd616d",918:"17896441",920:"1a4e3797",955:"ee2b4fdf"}[e]||e)+"."+{19:"cc992dbe",53:"be6f77aa",133:"6862b446",154:"c596ac4d",176:"0e7597ef",211:"f2bfc858",259:"f0e483ef",364:"7e629dc5",385:"3538c872",418:"ffc50926",430:"bc77d8ba",445:"0b0dd730",467:"fcf3a6b5",514:"9062895a",595:"c5627647",629:"ae378286",780:"b979b06f",791:"d6792d13",894:"4bf7d380",918:"e75765f6",920:"a9132d06",945:"3694633c",955:"11b95856",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(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/"+({19:"19a1e173",53:"935f2afb",133:"f1d66b0d",154:"4a59651f",176:"d23ae857",211:"f2ae99f3",259:"fcec3894",364:"ad872c75",385:"8420b8df",418:"19b14462",430:"6905f42e",445:"4a484b02",467:"e8ea0ffb",514:"1be78505",595:"d0766b26",629:"b9256968",791:"31fd616d",918:"17896441",920:"1a4e3797",955:"ee2b4fdf"}[e]||e)+"."+{19:"fa0df646",53:"3a9c3e69",133:"6862b446",154:"97fe7e06",176:"0e7597ef",211:"f2bfc858",259:"f0e483ef",364:"7e629dc5",385:"3538c872",418:"ffc50926",430:"bc77d8ba",445:"0b0dd730",467:"fcf3a6b5",514:"9062895a",595:"c5627647",629:"a17fa1ee",780:"b979b06f",791:"d6792d13",894:"4bf7d380",918:"e75765f6",920:"a9132d06",945:"3694633c",955:"11b95856",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 -Changelog | Task +Changelog | Task - +
-

Changelog

v3.24.0 - 2023-04-15

v3.23.0 - 2023-03-26

Task now has an official extension for Visual Studio Code contributed by @pd93! 🎉 The extension is maintained in a new repository under the go-task organization. We're looking to gather feedback from the community so please give it a go and let us know what you think via a discussion, issue or on our Discord!

NOTE: The extension requires v3.23.0 to be installed in order to work.

  • The website was integrated with Crowdin to allow the community to contribute with translations! Chinese is the first language available (#1057, #1058 by @misitebao).
  • Added task location data to the --json flag output (#1056 by @pd93)
  • Change the name of the file generated by task --init from Taskfile.yaml to Taskfile.yml (#1062 by @misitebao).
  • Added new splitArgs template function ({{splitArgs "foo bar 'foo bar baz'"}}) to ensure string is split as arguments (#1040, #1059 by @dhanusaputra).
  • Fix the value of {{.CHECKSUM}} variable in status (#1076, #1080 by @pd93).
  • Fixed deep copy implementation (#1072 by @pd93)
  • Created a tool to assist with releases (#1086 by @pd93).

v3.22.0 - 2023-03-10

  • Add a brand new --global (-g) flag that will run a Taskfile from your $HOME directory. This is useful to have automation that you can run from anywhere in your system! (Documentation, #1029 by @andreynering).
  • Add ability to set error_only: true on the group output mode. This will instruct Task to only print a command output if it returned with a non-zero exit code (#664, #1022 by @jaedle).
  • Fixed bug where .task/checksum file was sometimes not being created when task also declares a status: (#840, #1035 by @harelwa, #1037 by @pd93).
  • Refactored and decoupled fingerprinting from the main Task executor (#1039 by @pd93).
  • Fixed deadlock issue when using run: once (#715, #1025 by @theunrepentantgeek).

v3.21.0 - 2023-02-22

  • Added new TASK_VERSION special variable (#990, #1014 by @ja1code).
  • Fixed a bug where tasks were sometimes incorrectly marked as internal (#1007 by @pd93).
  • Update to Go 1.20 (bump minimum version to 1.19) (#1010 by @pd93)
  • Added environment variable FORCE_COLOR support to force color output. Usefull for environments without TTY (#1003 by @automation-stack)

v3.20.0 - 2023-01-14

  • Improve behavior and performance of status checking when using the timestamp mode (#976, #977 by @aminya).
  • Performance optimizations were made for large Taskfiles (#982 by @pd93).
  • Add ability to configure options for the set and shopt builtins (#908, #929 by @pd93, Documentation).
  • Add new platforms: attribute to task and cmd, so it's now possible to choose in which platforms that given task or command will be run on. Possible values are operating system (GOOS), architecture (GOARCH) or a combination of the two. Example: platforms: [linux], platforms: [amd64] or platforms: [linux/amd64]. Other platforms will be skipped (#978, #980 by @leaanthony).

v3.19.1 - 2022-12-31

  • Small bug fix: closing Taskfile.yml once we're done reading it (#963, #964 by @HeCorr).
  • Fixes a bug in v2 that caused a panic when using a Taskfile_{{OS}}.yml file (#961, #971 by @pd93).
  • Fixed a bug where watch intervals set in the Taskfile were not being respected (#969, #970 by @pd93)
  • Add --json flag (alias -j) with the intent to improve support for code editors and add room to other possible integrations. This is basic for now, but we plan to add more info in the near future (#936 by @davidalpert, #764).

v3.19.0 - 2022-12-05

v3.18.0 - 2022-11-12

  • Show aliases on task --list --silent (task --ls). This means that aliases will be completed by the completion scripts (#919).
  • Tasks in the root Taskfile will now be displayed first in --list/--list-all output (#806, #890).
  • It's now possible to call a default task in an included Taskfile by using just the namespace. For example: docs:default is now automatically aliased to docs (#661, #815).

v3.17.0 - 2022-10-14

  • Add a "Did you mean ...?" suggestion when a task does not exits another one with a similar name is found (#867, #880).
  • Now YAML parse errors will print which Taskfile failed to parse (#885, #887).
  • Add ability to set aliases for tasks and namespaces (#268, #340, #879).
  • Improvements to Fish shell completion (#897).
  • Added ability to set a different watch interval by setting interval: '500ms' or using the --interval=500ms flag (#813, #865).
  • Add colored output to --list, --list-all and --summary flags (#845, #874).
  • Fix unexpected behavior where label: was being shown instead of the task name on --list (#603, #877).

v3.16.0 - 2022-09-29

  • Add npm as new installation method: npm i -g [@go](https://github.com/go)-task/cli (#870, #871, npm package).
  • Add support to marking tasks and includes as internal, which will hide them from --list and --list-all (#818).

v3.15.2 - 2022-09-08

  • Fix error when using variable in env: introduced in the previous release (#858, #866).
  • Fix handling of CLI_ARGS (--) in Bash completion (#863).
  • On zsh completion, add ability to replace --list-all with --list as already possible on the Bash completion (#861).

v3.15.0 - 2022-09-03

  • Add new special variables ROOT_DIR and TASKFILE_DIR. This was a highly requested feature (#215, #857, Documentation).
  • Follow symlinks on sources (#826, #831).
  • Improvements and fixes to Bash completion (#835, #844).

v3.14.1 - 2022-08-03

  • Always resolve relative include paths relative to the including Taskfile (#822, #823).
  • Fix ZSH and PowerShell completions to consider all tasks instead of just the public ones (those with descriptions) (#803).

v3.14.0 - 2022-07-08

  • Add ability to override the .task directory location with the TASK_TEMP_DIR environment variable.
  • Allow to override Task colors using environment variables: TASK_COLOR_RESET, TASK_COLOR_BLUE, TASK_COLOR_GREEN, TASK_COLOR_CYAN, TASK_COLOR_YELLOW, TASK_COLOR_MAGENTA and TASK_COLOR_RED (#568, #792).
  • Fixed bug when using the output: group mode where STDOUT and STDERR were being print in separated blocks instead of in the right order (#779).
  • Starting on this release, ARM architecture binaries are been released to Snap as well (#795).
  • i386 binaries won't be available anymore on Snap because Ubuntu removed the support for this architecture.
  • Upgrade mvdan.cc/sh, which fixes a bug with associative arrays (#785, mvdan/sh[#884](https://github.com/go-task/task/issues/884), mvdan/sh[#893](https://github.com/go-task/task/issues/893)).

v3.13.0 - 2022-06-13

  • Added -n as an alias to --dry (#776, #777).
  • Fix behavior of interrupt (SIGINT, SIGTERM) signals. Task will now give time for the processes running to do cleanup work (#458, #479, #728, #769).
  • Add new --exit-code (-x) flag that will pass-through the exit form the command being ran (#755).

v3.12.1 - 2022-05-10

  • Fixed bug where, on Windows, variables were ending with \r because we were only removing the final \n but not \r\n (#717).

v3.12.0 - 2022-03-31

  • The --list and --list-all flags can now be combined with the --silent flag to print the task names only, without their description (#691).
  • Added support for multi-level inclusion of Taskfiles. This means that included Taskfiles can also include other Taskfiles. Before this was limited to one level (#390, #623, #656).
  • Add ability to specify vars when including a Taskfile. Check out the documentation for more information (#677).

v3.11.0 - 2022-02-19

v3.10.0 - 2022-01-04

  • A new --list-all (alias -a) flag is now available. It's similar to the exiting --list (-l) but prints all tasks, even those without a description (#383, #401).
  • It's now possible to schedule cleanup commands to run once a task finishes with the defer: keyword (Documentation, #475, #626).
  • Remove long deprecated and undocumented $ variable prefix and ^ command prefix (#642, #644, #645).
  • Add support for .yaml extension (as an alternative to .yml). This was requested multiple times throughout the years. Enjoy! (#183, #184, #369, #584, #621).
  • Fixed error when computing a variable when the task directory do not exist yet (#481, #579).

v3.9.2 - 2021-12-02

v3.9.1 - 2021-11-28

v3.9.0 - 2021-10-02

v3.8.0 - 2021-09-26

  • Add interactive: true setting to improve support for interactive CLI apps (#217, #563).
  • Fix some nil errors (#534, #573).
  • Add ability to declare an included Taskfile as optional (#519, #552).
  • Add support for including Taskfiles in the home directory by using ~ (#539, #557).

v3.7.3 - 2021-09-04

v3.7.0 - 2021-07-31

  • Add run: setting to control if tasks should run multiple times or not. Available options are always (the default), when_changed (if a variable modified the task) and once (run only once no matter what). This is a long time requested feature. Enjoy! (#53, #359).

v3.6.0 - 2021-07-10

  • Allow using both sources: and status: in the same task (#411, #427, #477).
  • Small optimization and bug fix: don't compute variables if not needed for dotenv: (#517).

v3.5.0 - 2021-07-04

  • Add support for interpolation in dotenv: (#433, #434, #453).

v3.4.3 - 2021-05-30

v3.4.2 - 2021-04-23

  • On watch, report which file failed to read (#472).
  • Do not try to catch SIGKILL signal, which are not actually possible (#476).
  • Improve version reporting when building Task from source using Go Modules (#462, #473).

v3.4.1 - 2021-04-17

  • Improve error reporting when parsing YAML: in some situations where you would just see an generic error, you'll now see the actual error with more detail: the YAML line the failed to parse, for example (#467).
  • A JSON Schema was published here and is automatically being used by some editors like Visual Studio Code (#135).
  • Print task name before the command in the log output (#398).

v3.3.0 - 2021-03-20

  • Add support for delegating CLI arguments to commands with -- and a special CLI_ARGS variable (#327).
  • Add a --concurrency (alias -C) flag, to limit the number of tasks that run concurrently. This is useful for heavy workloads. (#345).

v3.2.2 - 2021-01-12

  • Improve performance of --list and --summary by skipping running shell variables for these flags (#332).
  • Fixed a bug where an environment in a Taskfile was not always overridable by the system environment (#425).
  • Fixed environment from .env files not being available as variables (#379).
  • The install script is now working for ARM platforms (#428).

v3.2.1 - 2021-01-09

  • Fixed some bugs and regressions regarding dynamic variables and directories (#426).
  • The slim-sprig package was updated with the upstream sprig.

v3.2.0 - 2021-01-07

  • Fix the .task directory being created in the task directory instead of the Taskfile directory (#247).
  • Fix a bug where dynamic variables (those declared with sh:) were not running in the task directory when the task has a custom dir or it was in an included Taskfile (#384).
  • The watch feature (via the --watch flag) got a few different bug fixes and should be more stable now (#423, #365).

v3.1.0 - 2021-01-03

  • Fix a bug when the checksum up-to-date resolution is used by a task with a custom label: attribute (#412).
  • Starting from this release, we're releasing official ARMv6 and ARM64 binaries for Linux (#375, #418).
  • Task now respects the order of declaration of included Taskfiles when evaluating variables declaring by them (#393).
  • set -e is now automatically set on every command. This was done to fix an issue where multiline string commands wouldn't really fail unless the sentence was in the last line (#403).

v3.0.1 - 2020-12-26

  • Allow use as a library by moving the required packages out of the internal directory (#358).
  • Do not error if a specified dotenv file does not exist (#378, #385).
  • Fix panic when you have empty tasks in your Taskfile (#338, #362).

v3.0.0 - 2020-08-16

  • On v3, all CLI variables will be considered global variables (#336, #341)
  • Add support to .env like files (#324, #356).
  • Add label: to task so you can override the task name in the logs ([#321](https://github.com/go-task/task/issues/321), #337).
  • Refactor how variables work on version 3 (#311).
  • Disallow expansions on v3 since it has no effect.
  • Taskvars.yml is not automatically included anymore.
  • Taskfile_{{OS}}.yml is not automatically included anymore.
  • Allow interpolation on includes, so you can manually include a Taskfile based on operation system, for example.
  • Expose .TASK variable in templates with the task name (#252).
  • Implement short task syntax (#194, #240).
  • Added option to make included Taskfile run commands on its own directory (#260, #144)
  • Taskfiles in version 1 are not supported anymore (#237).
  • Added global method: option. With this option, you can set a default method to all tasks in a Taskfile (#246).
  • Changed default method from timestamp to checksum (#246).
  • New magic variables are now available when using status:: .TIMESTAMP which contains the greatest modification date from the files listed in sources:, and .CHECKSUM, which contains a checksum of all files listed in status:. This is useful for manual checking when using external, or even remote, artifacts when using status: (#216).
  • We're now using slim-sprig instead of sprig, which allowed a file size reduction of about 22% (#219).
  • We now use some colors on Task output to better distinguish message types - commands are green, errors are red, etc (#207).

v2.8.1 - 2020-05-20

  • Fix error code for the --help flag (#300, #330).
  • Print version to stdout instead of stderr (#299, #329).
  • Supress context errors when using the --watch flag (#313, #317).
  • Support templating on description (#276, #283).

v2.8.0 - 2019-12-07

  • Add --parallel flag (alias -p) to run tasks given by the command line in parallel (#266).
  • Fixed bug where calling the task CLI only informing global vars would not execute the default task.
  • Add hability to silent all tasks by adding silent: true a the root of the Taskfile.

v2.7.1 - 2019-11-10

  • Fix error being raised when exit 0 was called (#251).

v2.7.0 - 2019-09-22

  • Fixed panic bug when assigning a global variable (#229, #243).
  • A task with method: checksum will now re-run if generated files are deleted (#228, #238).

v2.6.0 - 2019-07-21

  • Fixed some bugs regarding minor version checks on version:.
  • Add preconditions: to task (#205).
  • Create directory informed on dir: if it doesn't exist (#209, #211).
  • We now have a --taskfile flag (alias -t), which can be used to run another Taskfile (other than the default Taskfile.yml) (#221).
  • It's now possible to install Task using Homebrew on Linux (go-task/homebrew-tap[#1](https://github.com/go-task/task/issues/1)).

v2.5.2 - 2019-05-11

2.5.1 - 2019-04-27

  • Fixed some issues with interactive command line tools, where sometimes the output were not being shown, and similar issues (#114, #190, #200).
  • Upgraded go-yaml/yaml from v2 to v3.

v2.5.0 - 2019-03-16

v2.4.0 - 2019-02-21

  • Allow calling a task of the root Taskfile from an included Taskfile by prefixing it with : (#161, #172).
  • Add flag to override the output option (#173).
  • Fix bug where Task was persisting the new checksum on the disk when the Dry Mode is enabled (#166).
  • Fix file timestamp issue when the file name has spaces (#176).
  • Mitigating path expanding issues on Windows (#170).

v2.3.0 - 2019-01-02

  • On Windows, Task can now be installed using Scoop (#152).
  • Fixed issue with file/directory globing (#153).
  • Added ability to globally set environment variables (#138, #159).

v2.2.1 - 2018-12-09

  • This repository now uses Go Modules (#143). We'll still keep the vendor directory in sync for some time, though;
  • Fixing a bug when the Taskfile has no tasks but includes another Taskfile (#150);
  • Fix a bug when calling another task or a dependency in an included Taskfile (#151).

v2.2.0 - 2018-10-25

  • Added support for including other Taskfiles (#98)
    • This should be considered experimental. For now, only including local files is supported, but support for including remote Taskfiles is being discussed. If you have any feedback, please comment on #98.
  • Task now have a dedicated documentation site: https://taskfile.org
    • Thanks to Docsify for making this pretty easy. To check the source code, just take a look at the docs directory of this repository. Contributions to the documentation is really appreciated.

v2.1.1 - 2018-09-17

  • Fix suggestion to use task --init not being shown anymore (when a Taskfile.yml is not found)
  • Fix error when using checksum method and no file exists for a source glob (#131)
  • Fix signal handling when the --watch flag is given (#132)

v2.1.0 - 2018-08-19

  • Add a ignore_error option to task and command (#123)
  • Add a dry run mode (--dry flag) (#126)

v2.0.3 - 2018-06-24

  • Expand environment variables on "dir", "sources" and "generates" (#116)
  • Fix YAML merging syntax (#112)
  • Add ZSH completion (#111)
  • Implement new output option. Please check out the documentation

v2.0.2 - 2018-05-01

  • Fix merging of YAML anchors (#112)

v2.0.1 - 2018-03-11

  • Fixes panic on task --list

v2.0.0 - 2018-03-08

Version 2.0.0 is here, with a new Taskfile format.

Please, make sure to read the Taskfile versions document, since it describes in depth what changed for this version.

  • New Taskfile version 2 (#77)
  • Possibility to have global variables in the Taskfile.yml instead of Taskvars.yml (#66)
  • Small improvements and fixes

v1.4.4 - 2017-11-19

  • Handle SIGINT and SIGTERM (#75);
  • List: print message with there's no task with description;
  • Expand home dir ("~" symbol) on paths (#74);
  • Add Snap as an installation method;
  • Move examples to its own repo;
  • Watch: also walk on tasks called on on "cmds", and not only on "deps";
  • Print logs to stderr instead of stdout (#68);
  • Remove deprecated set keyword;
  • Add checksum based status check, alternative to timestamp based.

v1.4.3 - 2017-09-07

  • Allow assigning variables to tasks at run time via CLI (#33)
  • Added suport for multiline variables from sh (#64)
  • Fixes env: remove square braces and evaluate shell (#62)
  • Watch: change watch library and few fixes and improvements
  • When use watching, cancel and restart long running process on file change (#59 and #60)

v1.4.2 - 2017-07-30

  • Flag to set directory of execution
  • Always echo command if is verbose mode
  • Add silent mode to disable echoing of commands
  • Fixes and improvements of variables (#56)

v1.4.1 - 2017-07-15

  • Allow use of YAML for dynamic variables instead of $ prefix
    • VAR: {sh: echo Hello} instead of VAR: $echo Hello
  • Add --list (or -l) flag to print existing tasks
  • OS specific Taskvars file (e.g. Taskvars_windows.yml, Taskvars_linux.yml, etc)
  • Consider task up-to-date on equal timestamps (#49)
  • Allow absolute path in generates section (#48)
  • Bugfix: allow templating when calling deps (#42)
  • Fix panic for invalid task in cyclic dep detection
  • Better error output for dynamic variables in Taskvars.yml (#41)
  • Allow template evaluation in parameters

v1.4.0 - 2017-07-06

  • Cache dynamic variables
  • Add verbose mode (-v flag)
  • Support to task parameters (overriding vars) (#31) (#32)
  • Print command, also when "set:" is specified (#35)
  • Improve task command help text (#35)

v1.3.1 - 2017-06-14

  • Fix glob not working on commands (#28)
  • Add ExeExt template function
  • Add --init flag to create a new Taskfile
  • Add status option to prevent task from running (#27)
  • Allow interpolation on generates and sources attributes (#26)

v1.3.0 - 2017-04-24

  • Migrate from os/exec.Cmd to a native Go sh/bash interpreter
    • This is a potentially breaking change if you use Windows.
    • Now, cmd is not used anymore on Windows. Always use Bash-like syntax for your commands, even on Windows.
  • Add "ToSlash" and "FromSlash" to template functions
  • Use functions defined on github.com/Masterminds/sprig
  • Do not redirect stdin while running variables commands
  • Using context and errgroup packages (this will make other tasks to be cancelled, if one returned an error)

v1.2.0 - 2017-04-02

  • More tests and Travis integration
  • Watch a task (experimental)
  • Possibility to call another task
  • Fix "=" not being reconized in variables/environment variables
  • Tasks can now have a description, and help will print them (#10)
  • Task dependencies now run concurrently
  • Support for a default task (#16)

v1.1.0 - 2017-03-08

  • Support for YAML, TOML and JSON (#1)
  • Support running command in another directory (#4)
  • --force or -f flag to force execution of task even when it's up-to-date
  • Detection of cyclic dependencies (#5)
  • Support for variables (#6, #9, #14)
  • Operation System specific commands and variables (#13)

v1.0.0 - 2017-02-28

  • Add LICENSE file
- +

Changelog

v3.25.0 - 2023-05-22

  • Support silent: when calling another tasks (#680, #1142 by @danquah).
  • Improve PowerShell completion script (#1168 by @trim21).
  • Add more languages to the website menu and show translation progress percentage (#1173 by @misitebao).
  • Starting on this release, official binaries for FreeBSD will be available to download (#1068 by @andreynering).
  • Fix some errors being unintendedly supressed (#1134 by @clintmod).
  • Fix a nil pointer error when version is omitted from a Taskfile (#1148, #1149 by @pd93).
  • Fix duplicate error message when a task does not exists (#1141, #1144 by @pd93).

v3.24.0 - 2023-04-15

v3.23.0 - 2023-03-26

Task now has an official extension for Visual Studio Code contributed by @pd93! 🎉 The extension is maintained in a new repository under the go-task organization. We're looking to gather feedback from the community so please give it a go and let us know what you think via a discussion, issue or on our Discord!

NOTE: The extension requires v3.23.0 to be installed in order to work.

  • The website was integrated with Crowdin to allow the community to contribute with translations! Chinese is the first language available (#1057, #1058 by @misitebao).
  • Added task location data to the --json flag output (#1056 by @pd93)
  • Change the name of the file generated by task --init from Taskfile.yaml to Taskfile.yml (#1062 by @misitebao).
  • Added new splitArgs template function ({{splitArgs "foo bar 'foo bar baz'"}}) to ensure string is split as arguments (#1040, #1059 by @dhanusaputra).
  • Fix the value of {{.CHECKSUM}} variable in status (#1076, #1080 by @pd93).
  • Fixed deep copy implementation (#1072 by @pd93)
  • Created a tool to assist with releases (#1086 by @pd93).

v3.22.0 - 2023-03-10

  • Add a brand new --global (-g) flag that will run a Taskfile from your $HOME directory. This is useful to have automation that you can run from anywhere in your system! (Documentation, #1029 by @andreynering).
  • Add ability to set error_only: true on the group output mode. This will instruct Task to only print a command output if it returned with a non-zero exit code (#664, #1022 by @jaedle).
  • Fixed bug where .task/checksum file was sometimes not being created when task also declares a status: (#840, #1035 by @harelwa, #1037 by @pd93).
  • Refactored and decoupled fingerprinting from the main Task executor (#1039 by @pd93).
  • Fixed deadlock issue when using run: once (#715, #1025 by @theunrepentantgeek).

v3.21.0 - 2023-02-22

  • Added new TASK_VERSION special variable (#990, #1014 by @ja1code).
  • Fixed a bug where tasks were sometimes incorrectly marked as internal (#1007 by @pd93).
  • Update to Go 1.20 (bump minimum version to 1.19) (#1010 by @pd93)
  • Added environment variable FORCE_COLOR support to force color output. Usefull for environments without TTY (#1003 by @automation-stack)

v3.20.0 - 2023-01-14

  • Improve behavior and performance of status checking when using the timestamp mode (#976, #977 by @aminya).
  • Performance optimizations were made for large Taskfiles (#982 by @pd93).
  • Add ability to configure options for the set and shopt builtins (#908, #929 by @pd93, Documentation).
  • Add new platforms: attribute to task and cmd, so it's now possible to choose in which platforms that given task or command will be run on. Possible values are operating system (GOOS), architecture (GOARCH) or a combination of the two. Example: platforms: [linux], platforms: [amd64] or platforms: [linux/amd64]. Other platforms will be skipped (#978, #980 by @leaanthony).

v3.19.1 - 2022-12-31

  • Small bug fix: closing Taskfile.yml once we're done reading it (#963, #964 by @HeCorr).
  • Fixes a bug in v2 that caused a panic when using a Taskfile_{{OS}}.yml file (#961, #971 by @pd93).
  • Fixed a bug where watch intervals set in the Taskfile were not being respected (#969, #970 by @pd93)
  • Add --json flag (alias -j) with the intent to improve support for code editors and add room to other possible integrations. This is basic for now, but we plan to add more info in the near future (#936 by @davidalpert, #764).

v3.19.0 - 2022-12-05

v3.18.0 - 2022-11-12

  • Show aliases on task --list --silent (task --ls). This means that aliases will be completed by the completion scripts (#919).
  • Tasks in the root Taskfile will now be displayed first in --list/--list-all output (#806, #890).
  • It's now possible to call a default task in an included Taskfile by using just the namespace. For example: docs:default is now automatically aliased to docs (#661, #815).

v3.17.0 - 2022-10-14

  • Add a "Did you mean ...?" suggestion when a task does not exits another one with a similar name is found (#867, #880).
  • Now YAML parse errors will print which Taskfile failed to parse (#885, #887).
  • Add ability to set aliases for tasks and namespaces (#268, #340, #879).
  • Improvements to Fish shell completion (#897).
  • Added ability to set a different watch interval by setting interval: '500ms' or using the --interval=500ms flag (#813, #865).
  • Add colored output to --list, --list-all and --summary flags (#845, #874).
  • Fix unexpected behavior where label: was being shown instead of the task name on --list (#603, #877).

v3.16.0 - 2022-09-29

  • Add npm as new installation method: npm i -g [@go](https://github.com/go)-task/cli (#870, #871, npm package).
  • Add support to marking tasks and includes as internal, which will hide them from --list and --list-all (#818).

v3.15.2 - 2022-09-08

  • Fix error when using variable in env: introduced in the previous release (#858, #866).
  • Fix handling of CLI_ARGS (--) in Bash completion (#863).
  • On zsh completion, add ability to replace --list-all with --list as already possible on the Bash completion (#861).

v3.15.0 - 2022-09-03

  • Add new special variables ROOT_DIR and TASKFILE_DIR. This was a highly requested feature (#215, #857, Documentation).
  • Follow symlinks on sources (#826, #831).
  • Improvements and fixes to Bash completion (#835, #844).

v3.14.1 - 2022-08-03

  • Always resolve relative include paths relative to the including Taskfile (#822, #823).
  • Fix ZSH and PowerShell completions to consider all tasks instead of just the public ones (those with descriptions) (#803).

v3.14.0 - 2022-07-08

  • Add ability to override the .task directory location with the TASK_TEMP_DIR environment variable.
  • Allow to override Task colors using environment variables: TASK_COLOR_RESET, TASK_COLOR_BLUE, TASK_COLOR_GREEN, TASK_COLOR_CYAN, TASK_COLOR_YELLOW, TASK_COLOR_MAGENTA and TASK_COLOR_RED (#568, #792).
  • Fixed bug when using the output: group mode where STDOUT and STDERR were being print in separated blocks instead of in the right order (#779).
  • Starting on this release, ARM architecture binaries are been released to Snap as well (#795).
  • i386 binaries won't be available anymore on Snap because Ubuntu removed the support for this architecture.
  • Upgrade mvdan.cc/sh, which fixes a bug with associative arrays (#785, mvdan/sh[#884](https://github.com/go-task/task/issues/884), mvdan/sh[#893](https://github.com/go-task/task/issues/893)).

v3.13.0 - 2022-06-13

  • Added -n as an alias to --dry (#776, #777).
  • Fix behavior of interrupt (SIGINT, SIGTERM) signals. Task will now give time for the processes running to do cleanup work (#458, #479, #728, #769).
  • Add new --exit-code (-x) flag that will pass-through the exit form the command being ran (#755).

v3.12.1 - 2022-05-10

  • Fixed bug where, on Windows, variables were ending with \r because we were only removing the final \n but not \r\n (#717).

v3.12.0 - 2022-03-31

  • The --list and --list-all flags can now be combined with the --silent flag to print the task names only, without their description (#691).
  • Added support for multi-level inclusion of Taskfiles. This means that included Taskfiles can also include other Taskfiles. Before this was limited to one level (#390, #623, #656).
  • Add ability to specify vars when including a Taskfile. Check out the documentation for more information (#677).

v3.11.0 - 2022-02-19

v3.10.0 - 2022-01-04

  • A new --list-all (alias -a) flag is now available. It's similar to the exiting --list (-l) but prints all tasks, even those without a description (#383, #401).
  • It's now possible to schedule cleanup commands to run once a task finishes with the defer: keyword (Documentation, #475, #626).
  • Remove long deprecated and undocumented $ variable prefix and ^ command prefix (#642, #644, #645).
  • Add support for .yaml extension (as an alternative to .yml). This was requested multiple times throughout the years. Enjoy! (#183, #184, #369, #584, #621).
  • Fixed error when computing a variable when the task directory do not exist yet (#481, #579).

v3.9.2 - 2021-12-02

v3.9.1 - 2021-11-28

v3.9.0 - 2021-10-02

v3.8.0 - 2021-09-26

  • Add interactive: true setting to improve support for interactive CLI apps (#217, #563).
  • Fix some nil errors (#534, #573).
  • Add ability to declare an included Taskfile as optional (#519, #552).
  • Add support for including Taskfiles in the home directory by using ~ (#539, #557).

v3.7.3 - 2021-09-04

v3.7.0 - 2021-07-31

  • Add run: setting to control if tasks should run multiple times or not. Available options are always (the default), when_changed (if a variable modified the task) and once (run only once no matter what). This is a long time requested feature. Enjoy! (#53, #359).

v3.6.0 - 2021-07-10

  • Allow using both sources: and status: in the same task (#411, #427, #477).
  • Small optimization and bug fix: don't compute variables if not needed for dotenv: (#517).

v3.5.0 - 2021-07-04

  • Add support for interpolation in dotenv: (#433, #434, #453).

v3.4.3 - 2021-05-30

v3.4.2 - 2021-04-23

  • On watch, report which file failed to read (#472).
  • Do not try to catch SIGKILL signal, which are not actually possible (#476).
  • Improve version reporting when building Task from source using Go Modules (#462, #473).

v3.4.1 - 2021-04-17

  • Improve error reporting when parsing YAML: in some situations where you would just see an generic error, you'll now see the actual error with more detail: the YAML line the failed to parse, for example (#467).
  • A JSON Schema was published here and is automatically being used by some editors like Visual Studio Code (#135).
  • Print task name before the command in the log output (#398).

v3.3.0 - 2021-03-20

  • Add support for delegating CLI arguments to commands with -- and a special CLI_ARGS variable (#327).
  • Add a --concurrency (alias -C) flag, to limit the number of tasks that run concurrently. This is useful for heavy workloads. (#345).

v3.2.2 - 2021-01-12

  • Improve performance of --list and --summary by skipping running shell variables for these flags (#332).
  • Fixed a bug where an environment in a Taskfile was not always overridable by the system environment (#425).
  • Fixed environment from .env files not being available as variables (#379).
  • The install script is now working for ARM platforms (#428).

v3.2.1 - 2021-01-09

  • Fixed some bugs and regressions regarding dynamic variables and directories (#426).
  • The slim-sprig package was updated with the upstream sprig.

v3.2.0 - 2021-01-07

  • Fix the .task directory being created in the task directory instead of the Taskfile directory (#247).
  • Fix a bug where dynamic variables (those declared with sh:) were not running in the task directory when the task has a custom dir or it was in an included Taskfile (#384).
  • The watch feature (via the --watch flag) got a few different bug fixes and should be more stable now (#423, #365).

v3.1.0 - 2021-01-03

  • Fix a bug when the checksum up-to-date resolution is used by a task with a custom label: attribute (#412).
  • Starting from this release, we're releasing official ARMv6 and ARM64 binaries for Linux (#375, #418).
  • Task now respects the order of declaration of included Taskfiles when evaluating variables declaring by them (#393).
  • set -e is now automatically set on every command. This was done to fix an issue where multiline string commands wouldn't really fail unless the sentence was in the last line (#403).

v3.0.1 - 2020-12-26

  • Allow use as a library by moving the required packages out of the internal directory (#358).
  • Do not error if a specified dotenv file does not exist (#378, #385).
  • Fix panic when you have empty tasks in your Taskfile (#338, #362).

v3.0.0 - 2020-08-16

  • On v3, all CLI variables will be considered global variables (#336, #341)
  • Add support to .env like files (#324, #356).
  • Add label: to task so you can override the task name in the logs ([#321](https://github.com/go-task/task/issues/321), #337).
  • Refactor how variables work on version 3 (#311).
  • Disallow expansions on v3 since it has no effect.
  • Taskvars.yml is not automatically included anymore.
  • Taskfile_{{OS}}.yml is not automatically included anymore.
  • Allow interpolation on includes, so you can manually include a Taskfile based on operation system, for example.
  • Expose .TASK variable in templates with the task name (#252).
  • Implement short task syntax (#194, #240).
  • Added option to make included Taskfile run commands on its own directory (#260, #144)
  • Taskfiles in version 1 are not supported anymore (#237).
  • Added global method: option. With this option, you can set a default method to all tasks in a Taskfile (#246).
  • Changed default method from timestamp to checksum (#246).
  • New magic variables are now available when using status:: .TIMESTAMP which contains the greatest modification date from the files listed in sources:, and .CHECKSUM, which contains a checksum of all files listed in status:. This is useful for manual checking when using external, or even remote, artifacts when using status: (#216).
  • We're now using slim-sprig instead of sprig, which allowed a file size reduction of about 22% (#219).
  • We now use some colors on Task output to better distinguish message types - commands are green, errors are red, etc (#207).

v2.8.1 - 2020-05-20

  • Fix error code for the --help flag (#300, #330).
  • Print version to stdout instead of stderr (#299, #329).
  • Supress context errors when using the --watch flag (#313, #317).
  • Support templating on description (#276, #283).

v2.8.0 - 2019-12-07

  • Add --parallel flag (alias -p) to run tasks given by the command line in parallel (#266).
  • Fixed bug where calling the task CLI only informing global vars would not execute the default task.
  • Add hability to silent all tasks by adding silent: true a the root of the Taskfile.

v2.7.1 - 2019-11-10

  • Fix error being raised when exit 0 was called (#251).

v2.7.0 - 2019-09-22

  • Fixed panic bug when assigning a global variable (#229, #243).
  • A task with method: checksum will now re-run if generated files are deleted (#228, #238).

v2.6.0 - 2019-07-21

  • Fixed some bugs regarding minor version checks on version:.
  • Add preconditions: to task (#205).
  • Create directory informed on dir: if it doesn't exist (#209, #211).
  • We now have a --taskfile flag (alias -t), which can be used to run another Taskfile (other than the default Taskfile.yml) (#221).
  • It's now possible to install Task using Homebrew on Linux (go-task/homebrew-tap[#1](https://github.com/go-task/task/issues/1)).

v2.5.2 - 2019-05-11

2.5.1 - 2019-04-27

  • Fixed some issues with interactive command line tools, where sometimes the output were not being shown, and similar issues (#114, #190, #200).
  • Upgraded go-yaml/yaml from v2 to v3.

v2.5.0 - 2019-03-16

v2.4.0 - 2019-02-21

  • Allow calling a task of the root Taskfile from an included Taskfile by prefixing it with : (#161, #172).
  • Add flag to override the output option (#173).
  • Fix bug where Task was persisting the new checksum on the disk when the Dry Mode is enabled (#166).
  • Fix file timestamp issue when the file name has spaces (#176).
  • Mitigating path expanding issues on Windows (#170).

v2.3.0 - 2019-01-02

  • On Windows, Task can now be installed using Scoop (#152).
  • Fixed issue with file/directory globing (#153).
  • Added ability to globally set environment variables (#138, #159).

v2.2.1 - 2018-12-09

  • This repository now uses Go Modules (#143). We'll still keep the vendor directory in sync for some time, though;
  • Fixing a bug when the Taskfile has no tasks but includes another Taskfile (#150);
  • Fix a bug when calling another task or a dependency in an included Taskfile (#151).

v2.2.0 - 2018-10-25

  • Added support for including other Taskfiles (#98)
    • This should be considered experimental. For now, only including local files is supported, but support for including remote Taskfiles is being discussed. If you have any feedback, please comment on #98.
  • Task now have a dedicated documentation site: https://taskfile.org
    • Thanks to Docsify for making this pretty easy. To check the source code, just take a look at the docs directory of this repository. Contributions to the documentation is really appreciated.

v2.1.1 - 2018-09-17

  • Fix suggestion to use task --init not being shown anymore (when a Taskfile.yml is not found)
  • Fix error when using checksum method and no file exists for a source glob (#131)
  • Fix signal handling when the --watch flag is given (#132)

v2.1.0 - 2018-08-19

  • Add a ignore_error option to task and command (#123)
  • Add a dry run mode (--dry flag) (#126)

v2.0.3 - 2018-06-24

  • Expand environment variables on "dir", "sources" and "generates" (#116)
  • Fix YAML merging syntax (#112)
  • Add ZSH completion (#111)
  • Implement new output option. Please check out the documentation

v2.0.2 - 2018-05-01

  • Fix merging of YAML anchors (#112)

v2.0.1 - 2018-03-11

  • Fixes panic on task --list

v2.0.0 - 2018-03-08

Version 2.0.0 is here, with a new Taskfile format.

Please, make sure to read the Taskfile versions document, since it describes in depth what changed for this version.

  • New Taskfile version 2 (#77)
  • Possibility to have global variables in the Taskfile.yml instead of Taskvars.yml (#66)
  • Small improvements and fixes

v1.4.4 - 2017-11-19

  • Handle SIGINT and SIGTERM (#75);
  • List: print message with there's no task with description;
  • Expand home dir ("~" symbol) on paths (#74);
  • Add Snap as an installation method;
  • Move examples to its own repo;
  • Watch: also walk on tasks called on on "cmds", and not only on "deps";
  • Print logs to stderr instead of stdout (#68);
  • Remove deprecated set keyword;
  • Add checksum based status check, alternative to timestamp based.

v1.4.3 - 2017-09-07

  • Allow assigning variables to tasks at run time via CLI (#33)
  • Added suport for multiline variables from sh (#64)
  • Fixes env: remove square braces and evaluate shell (#62)
  • Watch: change watch library and few fixes and improvements
  • When use watching, cancel and restart long running process on file change (#59 and #60)

v1.4.2 - 2017-07-30

  • Flag to set directory of execution
  • Always echo command if is verbose mode
  • Add silent mode to disable echoing of commands
  • Fixes and improvements of variables (#56)

v1.4.1 - 2017-07-15

  • Allow use of YAML for dynamic variables instead of $ prefix
    • VAR: {sh: echo Hello} instead of VAR: $echo Hello
  • Add --list (or -l) flag to print existing tasks
  • OS specific Taskvars file (e.g. Taskvars_windows.yml, Taskvars_linux.yml, etc)
  • Consider task up-to-date on equal timestamps (#49)
  • Allow absolute path in generates section (#48)
  • Bugfix: allow templating when calling deps (#42)
  • Fix panic for invalid task in cyclic dep detection
  • Better error output for dynamic variables in Taskvars.yml (#41)
  • Allow template evaluation in parameters

v1.4.0 - 2017-07-06

  • Cache dynamic variables
  • Add verbose mode (-v flag)
  • Support to task parameters (overriding vars) (#31) (#32)
  • Print command, also when "set:" is specified (#35)
  • Improve task command help text (#35)

v1.3.1 - 2017-06-14

  • Fix glob not working on commands (#28)
  • Add ExeExt template function
  • Add --init flag to create a new Taskfile
  • Add status option to prevent task from running (#27)
  • Allow interpolation on generates and sources attributes (#26)

v1.3.0 - 2017-04-24

  • Migrate from os/exec.Cmd to a native Go sh/bash interpreter
    • This is a potentially breaking change if you use Windows.
    • Now, cmd is not used anymore on Windows. Always use Bash-like syntax for your commands, even on Windows.
  • Add "ToSlash" and "FromSlash" to template functions
  • Use functions defined on github.com/Masterminds/sprig
  • Do not redirect stdin while running variables commands
  • Using context and errgroup packages (this will make other tasks to be cancelled, if one returned an error)

v1.2.0 - 2017-04-02

  • More tests and Travis integration
  • Watch a task (experimental)
  • Possibility to call another task
  • Fix "=" not being reconized in variables/environment variables
  • Tasks can now have a description, and help will print them (#10)
  • Task dependencies now run concurrently
  • Support for a default task (#16)

v1.1.0 - 2017-03-08

  • Support for YAML, TOML and JSON (#1)
  • Support running command in another directory (#4)
  • --force or -f flag to force execution of task even when it's up-to-date
  • Detection of cyclic dependencies (#5)
  • Support for variables (#6, #9, #14)
  • Operation System specific commands and variables (#13)

v1.0.0 - 2017-02-28

  • Add LICENSE file
+ \ No newline at end of file diff --git a/pt-BR/community/index.html b/pt-BR/community/index.html index 7fb5fde8..b79fa882 100644 --- a/pt-BR/community/index.html +++ b/pt-BR/community/index.html @@ -10,13 +10,13 @@ - +

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.

Integrations

Many of our integrations are contributed and maintained by the community. You can view the full list of community integrations here.

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.

- + \ No newline at end of file diff --git a/pt-BR/contributing/index.html b/pt-BR/contributing/index.html index 403a9b25..7446f826 100644 --- a/pt-BR/contributing/index.html +++ b/pt-BR/contributing/index.html @@ -10,13 +10,13 @@ - +

Contributing

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

nota

This document applies to the core Task repository and Task for Visual Studio Code.

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 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. It is also required if you want to contribute to the Visual Studio Code extension.
  • 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. Go code should be formatted by gofumpt and linted using golangci-lint. Any Markdown or TypeScript files should be formatted and linted by Prettier. This style is enforced by our CI to ensure that we have a consistent style across the project. You can use the task lint command to lint the code locally and the task lint:fix command to automatically fix any issues that are found.
  • Documentation - Ensure that you add/update any relevant documentation. See 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>.

To run Task for Visual Studio Code, you can open the project in VSCode and hit F5 (or whatever you debug keybind is set to). This will open a new VSCode window with the extension running. Debugging this way is recommended as it will allow you to set breakpoints and step through the code. Otherwise, you can run task package which will generate a .vsix file that can be used to manually install the extension.

Updating documentation

Task uses Docusaurus to host a documentation server. The code for this is located in the core Task repository. 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 (enforced by Prettier).

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

A lot of Task's tests 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 should ensure that the functionality you are adding will continue to work in the future. Existing tests may also need updating if you have changed Task's behavior.

You may also consider adding unit tests for any new functions you have added. The unit tests should follow the Go convention of being location in a file named *_test.go in the same package as the code being tested.

3. Committing your code

Try to write meaningful commit messages and avoid having too many commits on the PR. Most PRs should likely have a single commit (although for bigger PRs it may be reasonable to split it in a few). Git squash and rebase is your friend!

If you're not sure how to format your commit message, check out Conventional Commits. This style is not enforced, but it is a good way to make your commit messages more readable and consistent.

4. Submitting a PR

  • Describe your changes - Ensure that you provide a comprehensive description of your changes.
  • Issue/PR links - Link any previous work such as related issues or PRs. Please describe how your changes differ to/extend this work.
  • Examples - Add any examples or screenshots that you think are useful to demonstrate the 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 for Task or Task for Visual Studio Code. 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/pt-BR/donate/index.html b/pt-BR/donate/index.html index ea2ad4eb..616bdc50 100644 --- a/pt-BR/donate/index.html +++ b/pt-BR/donate/index.html @@ -10,13 +10,13 @@ - +

Doe

Se você acha esse projeto útil, considere doar usando um dos meios listados abaixo.

Esta é apenas uma maneira de dizer "obrigado", ele não lhe dará nenhum benefício como maior prioridade em issues ou algo parecido.

As empresas que doarem pelo menos $50/mês ganharão destaque como "Patrocinador Ouro" na página do site e no README do repositório no GitHub. Faça contato com @andreynering com o logotipo que você deseja ser mostrado no site. Negócios suspeitos (apostas, cassinos, etc) não serão permitidos, porém.

GitHub Sponsors

A forma sugerida de doar para os mantenedores é através do GitHub Sponsors. Basta usar os seguintes links para fazer a sua doação:

Open Collective

Se você preferir o Open Collective você pode doar usando um destes links:

PayPal

Você pode doar para @andreynering através do PayPal também:

PIX (somente para o Brasil)

E se você é brasileiro, também pode doar para @andreynering via PIX usando este QR Code.

- + \ No newline at end of file diff --git a/pt-BR/faq/index.html b/pt-BR/faq/index.html index a31086d6..6b23fbce 100644 --- a/pt-BR/faq/index.html +++ b/pt-BR/faq/index.html @@ -10,13 +10,13 @@ - +

FAQ

This page contains a list of frequently asked questions about Task.

Why won't my task update my shell environment?

This is a limitation of how shells work. Task runs as a subprocess of your current shell, so it can't change the environment of the shell that started it. This limitation is shared by other task runners and build tools too.

A common way to work around this is to create a task that will generate output that can be parsed by your shell. For example, to set an environment variable on your shell you can write a task like this:

my-shell-env:
cmds:
- echo "export FOO=foo"
- echo "export BAR=bar"

Now run eval $(task my-shell-env) and the variables $FOO and $BAR will be available in your shell.

'x' builtin command doesn't work on Windows

The default shell on Windows (cmd and powershell) do not have commands like rm and cp available as builtins. This means that these commands won't work. If you want to make your Taskfile fully cross-platform, you'll need to work around this limitation using one of the following methods:

  • Use the {{OS}} function to run an OS-specific script.
  • Use something like {{if eq OS "windows"}}powershell {{end}}<my_cmd> to detect windows and run the command in Powershell directly.
  • Use a shell on Windows that supports these commands as builtins, such as Git Bash or WSL.

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/pt-BR/index.html b/pt-BR/index.html index 45053dd4..f2537091 100644 --- a/pt-BR/index.html +++ b/pt-BR/index.html @@ -10,13 +10,13 @@ - +

Task

Task é uma ferramenta de automatização de tarefas que foi criada para ser mais simples de usar do que outras similares, como por exemplo o GNU Make.

Por ser escrito em Go, o Task é simplesmente um binário e não possui nenhuma outra dependência, o que significa que você não precisa lidar com um processo de instalação complicado apenas para usar uma ferramenta de automação.

Uma vez instalado, você só precisa só precisa escrever suas tarefas usando um esquema YAML simples num arquivo chamado Taskfile.yml:

Taskfile.yml
version: '3'

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

E invocá-lo ao rodar task hello do seu terminal.

O exemplo acima é apenas o começo. Você pode dar uma olhada no guia de uso para conferir a documentação completa do esquema e as funcionalidades do Task.

Funcionalidades

  • Instalação fácil: apenas baixe um único binário, adicione-o a $PATH e pronto! Ou você também pode instalá-lo usando Homebrew, Snapcraft ou Scoop se você quiser.
  • Disponível em CIs: adicionando este script simples para instalá-lo no seu CI você estará pronto para usar o Task como parte do seu pipeline de CI;
  • Verdadeiramente multiplataforma: enquanto a maioria das ferramentas de compilação só funcionam bem no Linux ou macOS, o Task também suporta Windows graças a este interpretador de shell para Go.
  • Ótimo para a geração de código: você pode facilmente impedir que uma tarefa execute se um determinado conjunto de arquivos não tiver mudado desde a última execução (baseado na data de modificação ou conteúdo dos arquivos).

Patrocinadores de Ouro

- + \ No newline at end of file diff --git a/pt-BR/installation/index.html b/pt-BR/installation/index.html index d5e858f4..212b3599 100644 --- a/pt-BR/installation/index.html +++ b/pt-BR/installation/index.html @@ -10,13 +10,13 @@ - +

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 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 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 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
cuidado

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
dica

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/pt-BR/integrations/index.html b/pt-BR/integrations/index.html index 48892f45..535d0b4f 100644 --- a/pt-BR/integrations/index.html +++ b/pt-BR/integrations/index.html @@ -10,13 +10,13 @@ - +

Integrations

Visual Studio Code Extension

Task has an official extension for Visual Studio Code. The code for this project can be found here. To use this extension, you must have Task v3.23.0+ installed on your system.

This extension provides the following features (and more):

  • View tasks in the sidebar.
  • Run tasks from the sidebar and command palette.
  • Go to definition from the sidebar and command palette.
  • Run last task command.
  • Multi-root workspace support.
  • Initialize a Taskfile in the current workspace.

To get autocompletion and validation for your Taskfile, see the Schema section below.

Task for Visual Studio Code

Schema

This was initially created by @KROSF in this Gist and is now officially maintained in this file and made available at https://taskfile.dev/schema.json. This schema can be used to validate Taskfiles and provide autocompletion in many code editors:

Visual Studio Code

To integrate the schema into VS Code, you need to install the YAML extension by Red Hat. Any Taskfile.yml in your project should automatically be detected and validation/autocompletion should work. If this doesn't work or you want to manually configure it for files with a different name, you can add the following to your settings.json:

// settings.json
{
"yaml.schemas": {
"https://taskfile.dev/schema.json": [
"**/Taskfile.yml",
"./path/to/any/other/taskfile.yml"
]
}
}

You can also configure the schema directly inside of a Taskfile by adding the following comment to the top of the file:

# yaml-language-server: $schema=https://taskfile.dev/schema.json
version: '3'

You can find more information on this in the YAML language server project.

Community Integrations

In addition to our official integrations, there is an amazing community of developers who have created their own integrations for Task:

If you have made something that integrates with Task, please feel free to open a PR to add it to this list.

- + \ No newline at end of file diff --git a/pt-BR/releasing/index.html b/pt-BR/releasing/index.html index 0624d255..377e88ae 100644 --- a/pt-BR/releasing/index.html +++ b/pt-BR/releasing/index.html @@ -10,13 +10,13 @@ - +

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 main branch (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 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/pt-BR/search/index.html b/pt-BR/search/index.html index 647ee995..2ba8e0cd 100644 --- a/pt-BR/search/index.html +++ b/pt-BR/search/index.html @@ -10,13 +10,13 @@ - + - + \ No newline at end of file diff --git a/pt-BR/styleguide/index.html b/pt-BR/styleguide/index.html index 82df5178..cfa64656 100644 --- a/pt-BR/styleguide/index.html +++ b/pt-BR/styleguide/index.html @@ -10,13 +10,13 @@ - +

Styleguide

This is the official Task styleguide for Taskfile.yml files. This guide contains some basic instructions to keep your Taskfile clean and familiar to other users.

This contains general guidelines, but they don't necessarily need to be strictly followed. Feel free to disagree and proceed differently at some point if you 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/pt-BR/taskfile-versions/index.html b/pt-BR/taskfile-versions/index.html index 70aa905c..4a288f46 100644 --- a/pt-BR/taskfile-versions/index.html +++ b/pt-BR/taskfile-versions/index.html @@ -10,13 +10,13 @@ - +

Taskfile Versions

The Taskfile syntax and features changed with time. This document explains what changed on each version and how to upgrade your Taskfile.

What the Taskfile version mean

The Taskfile version follows the Task version. E.g. the change to Taskfile version 2 means that Task v2.0.0 should be release to support it.

The version: key on Taskfile accepts a semver string, so either 2, 2.0 or 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:

  • Task's output will now be colored
  • Added support for .env like files
  • Added label: setting to task so one can override how the task name appear in the logs
  • A global method: was added to allow setting the default method, and Task's default changed to checksum
  • Two magic variables were added when using status:: CHECKSUM and TIMESTAMP which contains, respectively, the md5 checksum and greatest modification timestamp of the files listed on sources:
  • Also, the TASK variable is always available with the current task name
  • CLI variables are always treated as global variables
  • Added dir: option to includes to allow choosing on which directory an included Taskfile will run:
includes:
docs:
taskfile: ./docs
dir: ./docs
  • Implemented short task syntax. All below syntaxes are equivalent:
version: '3'

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

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

tasks:
print: echo "Hello, World!"
  • There was a major refactor on how variables are handled. They're now easier to understand. The expansions: setting was removed as it became unncessary. This is the order in which Task will process variables, each level can see the variables set by the previous one and override those.
    • Environment variables
    • Global + CLI variables
    • Call variables
    • Task variables
- + \ No newline at end of file diff --git a/pt-BR/translate/index.html b/pt-BR/translate/index.html index a728888c..9d1dec4e 100644 --- a/pt-BR/translate/index.html +++ b/pt-BR/translate/index.html @@ -10,13 +10,13 @@ - +

Traduza

Quer nos ajudar a traduzir esta documentação? Neste documento, explicamos como.

NÃO edite os arquivos markdown traduzidos diretamente no repositório do GitHub! 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/pt-BR/usage/index.html b/pt-BR/usage/index.html index 86b2410a..e2ca5cfb 100644 --- a/pt-BR/usage/index.html +++ b/pt-BR/usage/index.html @@ -10,13 +10,13 @@ - +
-

Guia de Uso

Primeiros passos

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 the file tree until it finds one (similar to how git works). When running Task from a subdirectory like this, it will behave as if you ran it from the directory containing the Taskfile.

You can use this functionality along with the special {{.USER_WORKING_DIR}} 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 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: 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 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 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: 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, function-like tasks that have no useful purpose on the command line.

version: '3'

tasks:
build-image-1:
cmds:
- task: build-image
vars:
DOCKER_IMAGE: image-1

build-image:
internal: true
cmds:
- docker build -t {{.DOCKER_IMAGE}} .

Task directory

By default, tasks will be executed in the directory where the Taskfile is located. But you can easily make the task run in another folder, informing 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 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.

dica

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.

dica

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. 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 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.

dica

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 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
dica

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 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 \ 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 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 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 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 [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
dica

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 set 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.

- +

Guia de Uso

Primeiros passos

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 the file tree until it finds one (similar to how git works). When running Task from a subdirectory like this, it will behave as if you ran it from the directory containing the Taskfile.

You can use this functionality along with the special {{.USER_WORKING_DIR}} 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 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: 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 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 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: 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, function-like tasks that have no useful purpose on the command line.

version: '3'

tasks:
build-image-1:
cmds:
- task: build-image
vars:
DOCKER_IMAGE: image-1

build-image:
internal: true
cmds:
- docker build -t {{.DOCKER_IMAGE}} .

Task directory

By default, tasks will be executed in the directory where the Taskfile is located. But you can easily make the task run in another folder, informing 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 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.

dica

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' }
silent: true
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"

Using the vars and silent attributes you can choose to pass variables and toggle silent mode on a call-by-call basis:

version: '3'

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

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

The above syntax is also supported in deps.

dica

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. 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 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.

dica

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 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
dica

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 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 \ 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 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 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 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 [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
dica

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 set 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.

+ \ No newline at end of file diff --git a/ru-RU/404.html b/ru-RU/404.html index cb54080b..9cc73979 100644 --- a/ru-RU/404.html +++ b/ru-RU/404.html @@ -10,13 +10,13 @@ - +

Страница не найдена

К сожалению, мы не смогли найти запрашиваемую вами страницу.

Пожалуйста, обратитесь к владельцу сайта, с которого вы перешли на эту ссылку, чтобы сообщить ему, что ссылка не работает.

- + \ No newline at end of file diff --git a/ru-RU/api/index.html b/ru-RU/api/index.html index 093834c7..6002c3b1 100644 --- a/ru-RU/api/index.html +++ b/ru-RU/api/index.html @@ -10,13 +10,13 @@ - +
-

Справочник API

CLI

Task command line tool has the following syntax:

task [--flags] [tasks...] [-- CLI_ARGS...]
подсказка

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

СокращениеФлагТипПо умолчаниюОписание
-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.

Exit Codes

Task will sometimes exit with specific exit codes. These codes are split into three groups with the following ranges:

  • General errors (0-99)
  • Taskfile errors (100-199)
  • Task errors (200-299)

A full list of the exit codes and their descriptions can be found below:

CodeОписание
0Success
1An unknown error occurred
100No Taskfile was found
101A Taskfile already exists when trying to initialize one
102The Taskfile is invalid or cannot be parsed
200The specified task could not be found
201An error occurred while executing a command inside of a task
202The user tried to invoke a task that is internal
203There a multiple tasks with the same name or alias
204A task was called too many times

These codes can also be found in the repository in errors/errors.go.

к сведению

When Task is run with the -x/--exit-code flag, the exit code of any failed commands will be passed through to the user instead.

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"
}

Специальные переменные

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

ПеременныеОписание
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

АтрибутТипПо умолчаниюОписание
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

АтрибутТипПо умолчаниюОписание
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.
к сведению

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

includes:
foo: ./path

Variable

АтрибутТипПо умолчаниюОписание
itselfstringA static value that will be set to the variable.
shstringA shell command. The output (STDOUT) will be assigned to the variable.
к сведению

Static and dynamic variables have different syntaxes, like below:

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

Task

АтрибутТипПо умолчаниюОписание
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.
к сведению

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

АтрибутТипПо умолчаниюОписание
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.
к сведению

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

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

Dependency

АтрибутТипПо умолчаниюОписание
taskstringThe task to be execute as a dependency.
varsmap[string]VariableOptional additional variables to be passed to this task.
подсказка

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

АтрибутТипПо умолчаниюDescription
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.
подсказка

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
- +

Справочник API

CLI

Task command line tool has the following syntax:

task [--flags] [tasks...] [-- CLI_ARGS...]
подсказка

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

СокращениеФлагТипПо умолчаниюОписание
-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.

Exit Codes

Task will sometimes exit with specific exit codes. These codes are split into three groups with the following ranges:

  • General errors (0-99)
  • Taskfile errors (100-199)
  • Task errors (200-299)

A full list of the exit codes and their descriptions can be found below:

CodeОписание
0Success
1An unknown error occurred
100No Taskfile was found
101A Taskfile already exists when trying to initialize one
102The Taskfile is invalid or cannot be parsed
200The specified task could not be found
201An error occurred while executing a command inside of a task
202The user tried to invoke a task that is internal
203There a multiple tasks with the same name or alias
204A task was called too many times

These codes can also be found in the repository in errors/errors.go.

к сведению

When Task is run with the -x/--exit-code flag, the exit code of any failed commands will be passed through to the user instead.

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"
}

Специальные переменные

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

ПеременныеОписание
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

АтрибутТипПо умолчаниюОписание
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

АтрибутТипПо умолчаниюОписание
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.
к сведению

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

includes:
foo: ./path

Variable

АтрибутТипПо умолчаниюОписание
itselfstringA static value that will be set to the variable.
shstringA shell command. The output (STDOUT) will be assigned to the variable.
к сведению

Static and dynamic variables have different syntaxes, like below:

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

Task

АтрибутТипПо умолчаниюОписание
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.
к сведению

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

АтрибутТипПо умолчаниюОписание
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.
к сведению

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

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

Dependency

АтрибутТипПо умолчаниюОписание
taskstringThe task to be execute as a dependency.
varsmap[string]VariableOptional additional variables to be passed to this task.
silentboolfalseHides task name and command from output. The command's output will still be redirected to STDOUT and STDERR.
подсказка

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

АтрибутТипПо умолчаниюDescription
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.
подсказка

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/ru-RU/assets/js/27551f2e.a1c1ab2d.js b/ru-RU/assets/js/27551f2e.b7dd53df.js similarity index 50% rename from ru-RU/assets/js/27551f2e.a1c1ab2d.js rename to ru-RU/assets/js/27551f2e.b7dd53df.js index c17b133c..4507a836 100644 --- a/ru-RU/assets/js/27551f2e.a1c1ab2d.js +++ b/ru-RU/assets/js/27551f2e.b7dd53df.js @@ -1 +1 @@ -"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[549],{3905:function(e,n,t){t.d(n,{Zo:function(){return d},kt:function(){return c}});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)},m="mdxType",u={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,i=e.mdxType,l=e.originalType,r=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),m=p(t),k=i,c=m["".concat(r,".").concat(k)]||m[k]||u[k]||l;return t?a.createElement(c,s(s({ref:n},d),{},{components:t})):a.createElement(c,s({ref:n},d))}));function c(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var l=t.length,s=new Array(l);s[0]=k;var o={};for(var r in n)hasOwnProperty.call(n,r)&&(o[r]=n[r]);o.originalType=e,o[m]="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 m(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:"\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435"},"\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435"),(0,i.kt)("h2",{id:"\u043d\u0430\u0447\u0430\u043b\u043e-\u0440\u0430\u0431\u043e\u0442\u044b"},"\u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0431\u043e\u0442\u044b"),(0,i.kt)("p",null,"\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," \u0432 \u043a\u043e\u0440\u043d\u0435 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0410\u0442\u0440\u0438\u0431\u0443\u0442 ",(0,i.kt)("inlineCode",{parentName:"p"},"cmds")," \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0437\u0430\u0434\u0430\u0447\u0438. \u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0438\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Go \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c ",(0,i.kt)("a",{parentName:"p",href:"https://esbuild.github.io/"},"esbuild")," \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438 \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e CSS \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043e\u0434\u0438\u043d."),(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,"\u0417\u0430\u043f\u0443\u0441\u043a \u0437\u0430\u0434\u0430\u0447 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442, \u0447\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"task assets build\n")),(0,i.kt)("p",null,"Task \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 ",(0,i.kt)("a",{parentName:"p",href:"https://mvdan.cc/sh/"},"mvdan.cc/sh")," - \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 sh \u043d\u0430 Go. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b sh / bash, \u0438 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u0430\u0436\u0435 \u0432 Windows, \u0433\u0434\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," \u0438\u043b\u0438 ",(0,i.kt)("inlineCode",{parentName:"p"},"bash"),". \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e \u043b\u044e\u0431\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u041e\u0421 \u0438\u043b\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 PATH."),(0,i.kt)("p",null,'\u0415\u0441\u043b\u0438 \u0432\u044b \u043e\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u0438\u043c\u044f \u0437\u0430\u0434\u0430\u0447\u0438, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043c\u044f "default".'),(0,i.kt)("h2",{id:"\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435-\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f-\u0444\u0430\u0439\u043b\u043e\u0432"},"\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432"),(0,i.kt)("p",null,"Task \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0444\u0430\u0439\u043b\u044b, \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430:"),(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,"\u0418\u0434\u0435\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 ",(0,i.kt)("inlineCode",{parentName:"p"},".dist")," \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u043d\u0443 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e (",(0,i.kt)("inlineCode",{parentName:"p"},".dist"),"), \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c Taskfile, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 ",(0,i.kt)("inlineCode",{parentName:"p"},".gitignore"),")."),(0,i.kt)("h3",{id:"\u0437\u0430\u043f\u0443\u0441\u043a-taskfile-\u0438\u0437-\u043f\u043e\u0434\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438"},"\u0417\u0430\u043f\u0443\u0441\u043a Taskfile \u0438\u0437 \u043f\u043e\u0434\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438"),(0,i.kt)("p",null,"\u0415\u0441\u043b\u0438 Taskfile \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0440\u0430\u0431\u043e\u0447\u0435\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u0435\u0433\u043e \u0432\u0432\u0435\u0440\u0445 \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 \u0444\u0430\u0439\u043b\u043e\u0432, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u0442 \u0435\u0433\u043e (\u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u0442\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 ",(0,i.kt)("inlineCode",{parentName:"p"},"git"),"). \u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 Task \u0438\u0437 \u043f\u043e\u0434\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u0430\u043a, \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0435\u0433\u043e \u0438\u0437 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e Taskfile."),(0,i.kt)("p",null,"\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}"),", \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043c\u043e\u043d\u043e\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430\u043c\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 ",(0,i.kt)("inlineCode",{parentName:"p"},"cd")," \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0437\u0430\u0434\u0430\u0447\u0438, \u0431\u0435\u0437 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0438\u043b\u0438 Taskfile \u0441 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:"),(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,"\u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c ",(0,i.kt)("inlineCode",{parentName:"p"},"cd ")," \u0438 ",(0,i.kt)("inlineCode",{parentName:"p"},"task up"),", \u0438 \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438, \u0447\u0442\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433 ",(0,i.kt)("inlineCode",{parentName:"p"},"")," \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u0430\u0439\u043b ",(0,i.kt)("inlineCode",{parentName:"p"},"docker-compose.yml"),", Docker composition \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0449\u0435\u043d."),(0,i.kt)("h3",{id:"\u0437\u0430\u043f\u0443\u0441\u043a-\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e-taskfile"},"\u0417\u0430\u043f\u0443\u0441\u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e Taskfile"),(0,i.kt)("p",null,"\u0415\u0441\u043b\u0438 \u0432\u044b \u0432\u044b\u0437\u043e\u0432\u0438\u0442\u0435 Task \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u043b\u0430\u0433\u0430 ",(0,i.kt)("inlineCode",{parentName:"p"},"--global")," (\u043f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c ",(0,i.kt)("inlineCode",{parentName:"p"},"-g"),"), \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u0432\u0430\u0448 \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0432\u043c\u0435\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430. \u041f\u0440\u043e\u0449\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, Task \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u0432 ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yml")," \u0438\u043b\u0438 ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yaml"),"."),(0,i.kt)("p",null,"\u042d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u0437 \u043b\u044e\u0431\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430 \u0432\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b!"),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"\u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0435 \u0432\u0430\u0448 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 Taskfile \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e ",(0,i.kt)("inlineCode",{parentName:"p"},"-g"),", task \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME"),", \u0430 \u043d\u0435 \u0432 \u0432\u0430\u0448\u0435\u0439 \u0440\u0430\u0431\u043e\u0447\u0435\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438!"),(0,i.kt)("p",{parentName:"admonition"},"\u041a\u0430\u043a \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435, \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}")," \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 ",(0,i.kt)("inlineCode",{parentName:"p"},"task -g"),"."),(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:"\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435-\u0441\u0440\u0435\u0434\u044b"},"\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b"),(0,i.kt)("h3",{id:"task"},"Task"),(0,i.kt)("p",null,"\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c ",(0,i.kt)("inlineCode",{parentName:"p"},"env")," \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0441\u0440\u0435\u0434\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 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,"\u0422\u0430\u043a\u0436\u0435, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432\u0441\u0435\u043c task:"),(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")," \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0432\u043e\u0434\u0430 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u044b shell \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 ",(0,i.kt)("a",{parentName:"p",href:"#variables"},"\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435"),".")),(0,i.kt)("h3",{id:"env-\u0444\u0430\u0439\u043b\u044b"},".env \u0444\u0430\u0439\u043b\u044b"),(0,i.kt)("p",null,"\u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c Task \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b, \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 ",(0,i.kt)("inlineCode",{parentName:"p"},".env")," \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 ",(0,i.kt)("inlineCode",{parentName:"p"},"dotenv:"),":"),(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 \u0444\u0430\u0439\u043b\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 task:"),(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,"\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 task, \u0437\u0430\u043c\u0435\u043d\u044f\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432 dotenv \u0444\u0430\u0439\u043b\u0430\u0445:"),(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"},"\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447 ",(0,i.kt)("inlineCode",{parentName:"p"},"dotenv")," \u0432\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 Taskfile.")),(0,i.kt)("h2",{id:"\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435-\u0434\u0440\u0443\u0433\u0438\u0445-taskfile"},"\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 Taskfile"),(0,i.kt)("p",null,"\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c task \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 (Taskfile), \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0430 \u0434\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u0438\u0445 Taskfile \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e ",(0,i.kt)("inlineCode",{parentName:"p"},"includes"),":"),(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,"Task, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 Taskfile, \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e\u043c \u0438\u043c\u0435\u043d. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c ",(0,i.kt)("inlineCode",{parentName:"p"},"serve")," task \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 ",(0,i.kt)("inlineCode",{parentName:"p"},"documentation/Taskfile.yml")," \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b ",(0,i.kt)("inlineCode",{parentName:"p"},"task docs:serve"),", \u0438\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c ",(0,i.kt)("inlineCode",{parentName:"p"},"build")," task \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 ",(0,i.kt)("inlineCode",{parentName:"p"},"DockerTasks.yml")," \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b ",(0,i.kt)("inlineCode",{parentName:"p"},"task docker:build"),"."),(0,i.kt)("p",null,"\u041e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044e\u0442\u0441\u044f \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0439 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")," if it exists (for example: ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_windows.yml"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_linux.yml")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"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:"),(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 the Taskfile is in another directory, but you can force its tasks to run in 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 Taskfile 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 the 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 internal as well (see the ",(0,i.kt)("a",{parentName:"p",href:"#internal-tasks"},"Internal tasks")," section below). This is useful when including utility tasks that are not intended to be used directly 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 for 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"),". This works in the same way as ",(0,i.kt)("a",{parentName:"p",href:"#task-aliases"},"task aliases")," and can be used together 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 variables in the including Taskfile! If you want a variable in an included Taskfile to be overridable, use the ",(0,i.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/defaults.html"},"default function"),": ",(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 not appear in the output when running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --list|--list-all"),". Other tasks may call internal tasks in the usual way. This is useful for creating reusable, function-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 located. But you can easily make the task run in another folder, informing ",(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 another. If you want to force tasks to run serially, take a look at the ",(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 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 ",(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 performance."),(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 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 manner 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 using the ",(0,i.kt)("inlineCode",{parentName:"p"},"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."),(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 defined by the Go language ",(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:"\u0432\u044b\u0437\u043e\u0432-\u0434\u0440\u0443\u0433\u043e\u0439-task"},"\u0412\u044b\u0437\u043e\u0432 \u0434\u0440\u0443\u0433\u043e\u0439 task"),(0,i.kt)("p",null,"\u041a\u043e\u0433\u0434\u0430 task \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u043e\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e. \u042d\u0442\u043e \u0447\u0430\u0441\u0442\u043d\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0431\u043e\u043b\u0435\u0435 \u0431\u044b\u0441\u0442\u0440\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044e \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430. \u041e\u0434\u043d\u0430\u043a\u043e, \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445 \u0432\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 task \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441:"),(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,"\u041f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u0439 task \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 ",(0,i.kt)("inlineCode",{parentName:"p"},"vars"),":"),(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,"\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 ",(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 ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"included Taskfile"),", add a leading ",(0,i.kt)("inlineCode",{parentName:"p"},":")," like this: ",(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 files, 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 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 ",(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, instead 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. You can even combine the two. See the documentation for ",(0,i.kt)("a",{parentName:"p",href:"#using-programmatic-checks-to-indicate-a-task-is-up-to-date"},"status")," for an example."),(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 directory. Most of the time, you'll want to have this directory on ",(0,i.kt)("inlineCode",{parentName:"p"},".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)."),(0,i.kt)("p",{parentName:"admonition"},"If you want these files to be stored in another directory, you can set a ",(0,i.kt)("inlineCode",{parentName:"p"},"TASK_TEMP_DIR")," environment variable in your machine. It can contain a relative path like ",(0,i.kt)("inlineCode",{parentName:"p"},"tmp/task")," that will be interpreted as relative to the project directory, or an absolute or home path like ",(0,i.kt)("inlineCode",{parentName:"p"},"/tmp/.task")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"~/.task")," (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 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."),(0,i.kt)("p",{parentName:"admonition"},"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.")),(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 inform the source files. When 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 is 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"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 ",(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 interpolation within ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," commands, depending on the method assigned to 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 can 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 up-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 the 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")," to have a task run if either the the source/generated artifacts changes, or the programmatic 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 of ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," checks. That is, if you need a certain set of conditions to be ",(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 ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," lines, except they support ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," expansion, 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 a 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 precondition is not met - the calling task will fail. Note that a task executed with 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 executing tasks that depend on it, a ",(0,i.kt)("inlineCode",{parentName:"p"},"precondition")," will fail a task, along with 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 when 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 of the Taskfile to change 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 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 passed 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 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 (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 (Windows) tasks also accept a similar style when not at the beginning of the 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. 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."),(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 ",(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 task finishes. The difference with just putting it as the last command is that 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 well:"),(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 ",(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 commands 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. 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")," are 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", "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 "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"},"\\")," path 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 converts 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"')," 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. Task uses ",(0,i.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote"},"this Go function")," for 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 ",(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 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. The 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. If 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 quicker to run tasks with long or hard-to-type names. You can use them on the command line, when ",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"calling sub-tasks")," in your Taskfile and when ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"including tasks")," with aliases from another Taskfile. They can also be used together with ",(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, up-to-date messages to STDOUT, etc. In this case, you can just set ",(0,i.kt)("inlineCode",{parentName:"p"},"label:"),", which 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 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 that 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. Given 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"),". However, 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 for all commands. Nevertheless, keep in mind that this option will not propagate to 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 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."),(0,i.kt)("p",null,"To make this more customizable, there are currently three different output options 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 finishes, so you will not have live feedback for commands that take a long time to 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 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 ",(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")," or ",(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 on 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"[task-name]")," as the prefix, but you can customize the prefix for a command with 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 weirdly, especially when the ",(0,i.kt)("a",{parentName:"p",href:"#output-syntax"},"output mode")," is set to something other than ",(0,i.kt)("inlineCode",{parentName:"p"},"interleaved")," (the default), or when interactive apps are run in parallel 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 will 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 an 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 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 ",(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"))," and ",(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"))," builtins. 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 ",(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 task again. This requires the ",(0,i.kt)("inlineCode",{parentName:"p"},"sources")," attribute to be given, so 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 either setting ",(0,i.kt)("inlineCode",{parentName:"p"},"interval: '500ms'")," in the root of the Taskfile passing it as an argument like ",(0,i.kt)("inlineCode",{parentName:"p"},"--interval=500ms"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[549],{3905:function(e,n,t){t.d(n,{Zo:function(){return d},kt:function(){return c}});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)},m="mdxType",u={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,i=e.mdxType,l=e.originalType,r=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),m=p(t),k=i,c=m["".concat(r,".").concat(k)]||m[k]||u[k]||l;return t?a.createElement(c,s(s({ref:n},d),{},{components:t})):a.createElement(c,s({ref:n},d))}));function c(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var l=t.length,s=new Array(l);s[0]=k;var o={};for(var r in n)hasOwnProperty.call(n,r)&&(o[r]=n[r]);o.originalType=e,o[m]="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 m(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:"\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435"},"\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435"),(0,i.kt)("h2",{id:"\u043d\u0430\u0447\u0430\u043b\u043e-\u0440\u0430\u0431\u043e\u0442\u044b"},"\u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0431\u043e\u0442\u044b"),(0,i.kt)("p",null,"\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," \u0432 \u043a\u043e\u0440\u043d\u0435 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0410\u0442\u0440\u0438\u0431\u0443\u0442 ",(0,i.kt)("inlineCode",{parentName:"p"},"cmds")," \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0437\u0430\u0434\u0430\u0447\u0438. \u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0438\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Go \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c ",(0,i.kt)("a",{parentName:"p",href:"https://esbuild.github.io/"},"esbuild")," \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0438 \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e CSS \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043e\u0434\u0438\u043d."),(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,"\u0417\u0430\u043f\u0443\u0441\u043a \u0437\u0430\u0434\u0430\u0447 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442, \u0447\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"task assets build\n")),(0,i.kt)("p",null,"Task \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 ",(0,i.kt)("a",{parentName:"p",href:"https://mvdan.cc/sh/"},"mvdan.cc/sh")," - \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 sh \u043d\u0430 Go. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u044b sh / bash, \u0438 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u0430\u0436\u0435 \u0432 Windows, \u0433\u0434\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," \u0438\u043b\u0438 ",(0,i.kt)("inlineCode",{parentName:"p"},"bash"),". \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e \u043b\u044e\u0431\u043e\u0439 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u041e\u0421 \u0438\u043b\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 PATH."),(0,i.kt)("p",null,'\u0415\u0441\u043b\u0438 \u0432\u044b \u043e\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u0438\u043c\u044f \u0437\u0430\u0434\u0430\u0447\u0438, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043c\u044f "default".'),(0,i.kt)("h2",{id:"\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435-\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f-\u0444\u0430\u0439\u043b\u043e\u0432"},"\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432"),(0,i.kt)("p",null,"Task \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0444\u0430\u0439\u043b\u044b, \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430:"),(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,"\u0418\u0434\u0435\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 ",(0,i.kt)("inlineCode",{parentName:"p"},".dist")," \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u043c \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u043d\u0443 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e (",(0,i.kt)("inlineCode",{parentName:"p"},".dist"),"), \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c Taskfile, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 ",(0,i.kt)("inlineCode",{parentName:"p"},".gitignore"),")."),(0,i.kt)("h3",{id:"\u0437\u0430\u043f\u0443\u0441\u043a-taskfile-\u0438\u0437-\u043f\u043e\u0434\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438"},"\u0417\u0430\u043f\u0443\u0441\u043a Taskfile \u0438\u0437 \u043f\u043e\u0434\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438"),(0,i.kt)("p",null,"\u0415\u0441\u043b\u0438 Taskfile \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0440\u0430\u0431\u043e\u0447\u0435\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u0435\u0433\u043e \u0432\u0432\u0435\u0440\u0445 \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 \u0444\u0430\u0439\u043b\u043e\u0432, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u0442 \u0435\u0433\u043e (\u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u0442\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 ",(0,i.kt)("inlineCode",{parentName:"p"},"git"),"). \u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 Task \u0438\u0437 \u043f\u043e\u0434\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u0430\u043a, \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0435\u0433\u043e \u0438\u0437 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e Taskfile."),(0,i.kt)("p",null,"\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}"),", \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043c\u043e\u043d\u043e\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430\u043c\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 ",(0,i.kt)("inlineCode",{parentName:"p"},"cd")," \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u0437\u0430\u0434\u0430\u0447\u0438, \u0431\u0435\u0437 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u0438\u043b\u0438 Taskfile \u0441 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:"),(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,"\u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c ",(0,i.kt)("inlineCode",{parentName:"p"},"cd ")," \u0438 ",(0,i.kt)("inlineCode",{parentName:"p"},"task up"),", \u0438 \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438, \u0447\u0442\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433 ",(0,i.kt)("inlineCode",{parentName:"p"},"")," \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u0430\u0439\u043b ",(0,i.kt)("inlineCode",{parentName:"p"},"docker-compose.yml"),", Docker composition \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0449\u0435\u043d."),(0,i.kt)("h3",{id:"\u0437\u0430\u043f\u0443\u0441\u043a-\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e-taskfile"},"\u0417\u0430\u043f\u0443\u0441\u043a \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e Taskfile"),(0,i.kt)("p",null,"\u0415\u0441\u043b\u0438 \u0432\u044b \u0432\u044b\u0437\u043e\u0432\u0438\u0442\u0435 Task \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u043b\u0430\u0433\u0430 ",(0,i.kt)("inlineCode",{parentName:"p"},"--global")," (\u043f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c ",(0,i.kt)("inlineCode",{parentName:"p"},"-g"),"), \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u0432\u0430\u0448 \u0434\u043e\u043c\u0430\u0448\u043d\u0438\u0439 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0432\u043c\u0435\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430. \u041f\u0440\u043e\u0449\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, Task \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u0432 ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yml")," \u0438\u043b\u0438 ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yaml"),"."),(0,i.kt)("p",null,"\u042d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u0437 \u043b\u044e\u0431\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430 \u0432\u0430\u0448\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b!"),(0,i.kt)("admonition",{type:"info"},(0,i.kt)("p",{parentName:"admonition"},"\u041a\u043e\u0433\u0434\u0430 \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0435 \u0432\u0430\u0448 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 Taskfile \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e ",(0,i.kt)("inlineCode",{parentName:"p"},"-g"),", task \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 ",(0,i.kt)("inlineCode",{parentName:"p"},"$HOME"),", \u0430 \u043d\u0435 \u0432 \u0432\u0430\u0448\u0435\u0439 \u0440\u0430\u0431\u043e\u0447\u0435\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438!"),(0,i.kt)("p",{parentName:"admonition"},"\u041a\u0430\u043a \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435, \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f ",(0,i.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}")," \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 ",(0,i.kt)("inlineCode",{parentName:"p"},"task -g"),"."),(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:"\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435-\u0441\u0440\u0435\u0434\u044b"},"\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b"),(0,i.kt)("h3",{id:"task"},"Task"),(0,i.kt)("p",null,"\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c ",(0,i.kt)("inlineCode",{parentName:"p"},"env")," \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0441\u0440\u0435\u0434\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 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,"\u0422\u0430\u043a\u0436\u0435, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432\u0441\u0435\u043c task:"),(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")," \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0432\u043e\u0434\u0430 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u044b shell \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 ",(0,i.kt)("a",{parentName:"p",href:"#variables"},"\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435"),".")),(0,i.kt)("h3",{id:"env-\u0444\u0430\u0439\u043b\u044b"},".env \u0444\u0430\u0439\u043b\u044b"),(0,i.kt)("p",null,"\u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c Task \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b, \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 ",(0,i.kt)("inlineCode",{parentName:"p"},".env")," \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 ",(0,i.kt)("inlineCode",{parentName:"p"},"dotenv:"),":"),(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 \u0444\u0430\u0439\u043b\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 task:"),(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,"\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 task, \u0437\u0430\u043c\u0435\u043d\u044f\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432 dotenv \u0444\u0430\u0439\u043b\u0430\u0445:"),(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"},"\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447 ",(0,i.kt)("inlineCode",{parentName:"p"},"dotenv")," \u0432\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 Taskfile.")),(0,i.kt)("h2",{id:"\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435-\u0434\u0440\u0443\u0433\u0438\u0445-taskfile"},"\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 Taskfile"),(0,i.kt)("p",null,"\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c task \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 (Taskfile), \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0430 \u0434\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u0438\u0445 Taskfile \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e ",(0,i.kt)("inlineCode",{parentName:"p"},"includes"),":"),(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,"Task, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 Taskfile, \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e\u043c \u0438\u043c\u0435\u043d. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c ",(0,i.kt)("inlineCode",{parentName:"p"},"serve")," task \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 ",(0,i.kt)("inlineCode",{parentName:"p"},"documentation/Taskfile.yml")," \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b ",(0,i.kt)("inlineCode",{parentName:"p"},"task docs:serve"),", \u0438\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c ",(0,i.kt)("inlineCode",{parentName:"p"},"build")," task \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 ",(0,i.kt)("inlineCode",{parentName:"p"},"DockerTasks.yml")," \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b ",(0,i.kt)("inlineCode",{parentName:"p"},"task docker:build"),"."),(0,i.kt)("p",null,"\u041e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044e\u0442\u0441\u044f \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0439 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")," if it exists (for example: ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_windows.yml"),", ",(0,i.kt)("inlineCode",{parentName:"p"},"Taskfile_linux.yml")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"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:"),(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 the Taskfile is in another directory, but you can force its tasks to run in 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 Taskfile 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 the 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 internal as well (see the ",(0,i.kt)("a",{parentName:"p",href:"#internal-tasks"},"Internal tasks")," section below). This is useful when including utility tasks that are not intended to be used directly 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 for 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"),". This works in the same way as ",(0,i.kt)("a",{parentName:"p",href:"#task-aliases"},"task aliases")," and can be used together 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 variables in the including Taskfile! If you want a variable in an included Taskfile to be overridable, use the ",(0,i.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/defaults.html"},"default function"),": ",(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 not appear in the output when running ",(0,i.kt)("inlineCode",{parentName:"p"},"task --list|--list-all"),". Other tasks may call internal tasks in the usual way. This is useful for creating reusable, function-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 located. But you can easily make the task run in another folder, informing ",(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 another. If you want to force tasks to run serially, take a look at the ",(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 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 ",(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 performance."),(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 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 manner 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 silent: true\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 using the ",(0,i.kt)("inlineCode",{parentName:"p"},"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."),(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 defined by the Go language ",(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:"\u0432\u044b\u0437\u043e\u0432-\u0434\u0440\u0443\u0433\u043e\u0439-task"},"\u0412\u044b\u0437\u043e\u0432 \u0434\u0440\u0443\u0433\u043e\u0439 task"),(0,i.kt)("p",null,"\u041a\u043e\u0433\u0434\u0430 task \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u043e\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e. \u042d\u0442\u043e \u0447\u0430\u0441\u0442\u043d\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0431\u043e\u043b\u0435\u0435 \u0431\u044b\u0441\u0442\u0440\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044e \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430. \u041e\u0434\u043d\u0430\u043a\u043e, \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f\u0445 \u0432\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 task \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441:"),(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,"Using the ",(0,i.kt)("inlineCode",{parentName:"p"},"vars")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"silent")," attributes you can choose to pass variables and toggle ",(0,i.kt)("a",{parentName:"p",href:"#silent-mode"},"silent mode")," on a call-by-call basis:"),(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 silent: true\n")),(0,i.kt)("p",null,"\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 ",(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 ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"included Taskfile"),", add a leading ",(0,i.kt)("inlineCode",{parentName:"p"},":")," like this: ",(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 files, 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 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 ",(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, instead 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. You can even combine the two. See the documentation for ",(0,i.kt)("a",{parentName:"p",href:"#using-programmatic-checks-to-indicate-a-task-is-up-to-date"},"status")," for an example."),(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 directory. Most of the time, you'll want to have this directory on ",(0,i.kt)("inlineCode",{parentName:"p"},".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)."),(0,i.kt)("p",{parentName:"admonition"},"If you want these files to be stored in another directory, you can set a ",(0,i.kt)("inlineCode",{parentName:"p"},"TASK_TEMP_DIR")," environment variable in your machine. It can contain a relative path like ",(0,i.kt)("inlineCode",{parentName:"p"},"tmp/task")," that will be interpreted as relative to the project directory, or an absolute or home path like ",(0,i.kt)("inlineCode",{parentName:"p"},"/tmp/.task")," or ",(0,i.kt)("inlineCode",{parentName:"p"},"~/.task")," (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 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."),(0,i.kt)("p",{parentName:"admonition"},"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.")),(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 inform the source files. When 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 is 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"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 ",(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 interpolation within ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," commands, depending on the method assigned to 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 can 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 up-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 the 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")," to have a task run if either the the source/generated artifacts changes, or the programmatic 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 of ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," checks. That is, if you need a certain set of conditions to be ",(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 ",(0,i.kt)("inlineCode",{parentName:"p"},"status")," lines, except they support ",(0,i.kt)("inlineCode",{parentName:"p"},"sh")," expansion, 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 a 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 precondition is not met - the calling task will fail. Note that a task executed with 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 executing tasks that depend on it, a ",(0,i.kt)("inlineCode",{parentName:"p"},"precondition")," will fail a task, along with 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 when 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 of the Taskfile to change 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 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 passed 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 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 (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 (Windows) tasks also accept a similar style when not at the beginning of the 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. 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."),(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 ",(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 task finishes. The difference with just putting it as the last command is that 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 well:"),(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 ",(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 commands 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. 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")," are 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", "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 "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"},"\\")," path 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 converts 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"')," 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. Task uses ",(0,i.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote"},"this Go function")," for 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 ",(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 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. The 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. If 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 quicker to run tasks with long or hard-to-type names. You can use them on the command line, when ",(0,i.kt)("a",{parentName:"p",href:"#calling-another-task"},"calling sub-tasks")," in your Taskfile and when ",(0,i.kt)("a",{parentName:"p",href:"#including-other-taskfiles"},"including tasks")," with aliases from another Taskfile. They can also be used together with ",(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, up-to-date messages to STDOUT, etc. In this case, you can just set ",(0,i.kt)("inlineCode",{parentName:"p"},"label:"),", which 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 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 that 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. Given 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"),". However, 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 for all commands. Nevertheless, keep in mind that this option will not propagate to 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 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."),(0,i.kt)("p",null,"To make this more customizable, there are currently three different output options 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 finishes, so you will not have live feedback for commands that take a long time to 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 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 ",(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")," or ",(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 on 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 ",(0,i.kt)("inlineCode",{parentName:"p"},"[task-name]")," as the prefix, but you can customize the prefix for a command with 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 weirdly, especially when the ",(0,i.kt)("a",{parentName:"p",href:"#output-syntax"},"output mode")," is set to something other than ",(0,i.kt)("inlineCode",{parentName:"p"},"interleaved")," (the default), or when interactive apps are run in parallel 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 will 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 an 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 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 ",(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"))," and ",(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"))," builtins. 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 ",(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 task again. This requires the ",(0,i.kt)("inlineCode",{parentName:"p"},"sources")," attribute to be given, so 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 either setting ",(0,i.kt)("inlineCode",{parentName:"p"},"interval: '500ms'")," in the root of the Taskfile passing it as an argument like ",(0,i.kt)("inlineCode",{parentName:"p"},"--interval=500ms"),"."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/ru-RU/assets/js/5b06504c.205d429a.js b/ru-RU/assets/js/5b06504c.205d429a.js deleted file mode 100644 index 3cd22760..00000000 --- a/ru-RU/assets/js/5b06504c.205d429a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[446],{3905:function(t,e,a){a.d(e,{Zo:function(){return h},kt:function(){return d}});var i=a(7294);function s(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function n(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,i)}return a}function l(t){for(var e=1;e=0||(s[a]=t[a]);return s}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(s[a]=t[a])}return s}var o=i.createContext({}),k=function(t){var e=i.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},h=function(t){var e=k(t.components);return i.createElement(o.Provider,{value:e},t.children)},m="mdxType",p={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},u=i.forwardRef((function(t,e){var a=t.components,s=t.mdxType,n=t.originalType,o=t.parentName,h=r(t,["components","mdxType","originalType","parentName"]),m=k(a),u=s,d=m["".concat(o,".").concat(u)]||m[u]||p[u]||n;return a?i.createElement(d,l(l({ref:e},h),{},{components:a})):i.createElement(d,l({ref:e},h))}));function d(t,e){var a=arguments,s=e&&e.mdxType;if("string"==typeof t||s){var n=a.length,l=new Array(n);l[0]=u;var r={};for(var o in e)hasOwnProperty.call(e,o)&&(r[o]=e[o]);r.originalType=t,r[m]="string"==typeof t?t:s,l[1]=r;for(var k=2;k=0||(s[a]=t[a]);return s}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(s[a]=t[a])}return s}var o=i.createContext({}),k=function(t){var e=i.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},h=function(t){var e=k(t.components);return i.createElement(o.Provider,{value:e},t.children)},m="mdxType",p={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},u=i.forwardRef((function(t,e){var a=t.components,s=t.mdxType,n=t.originalType,o=t.parentName,h=r(t,["components","mdxType","originalType","parentName"]),m=k(a),u=s,d=m["".concat(o,".").concat(u)]||m[u]||p[u]||n;return a?i.createElement(d,l(l({ref:e},h),{},{components:a})):i.createElement(d,l({ref:e},h))}));function d(t,e){var a=arguments,s=e&&e.mdxType;if("string"==typeof t||s){var n=a.length,l=new Array(n);l[0]=u;var r={};for(var o in e)hasOwnProperty.call(e,o)&&(r[o]=e[o]);r.originalType=t,r[m]="string"==typeof t?t:s,l[1]=r;for(var k=2;k=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 o=a.createContext({}),p=function(t){var e=a.useContext(o),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},m=function(t){var e=p(t.components);return a.createElement(o.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,o=t.parentName,m=d(t,["components","mdxType","originalType","parentName"]),k=p(n),u=l,s=k["".concat(o,".").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 o in e)hasOwnProperty.call(e,o)&&(d[o]=e[o]);d.originalType=t,d[k]="string"==typeof t?t:l,i[1]=d;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 o=a.createContext({}),p=function(t){var e=a.useContext(o),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},m=function(t){var e=p(t.components);return a.createElement(o.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,o=t.parentName,m=d(t,["components","mdxType","originalType","parentName"]),k=p(n),u=l,s=k["".concat(o,".").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 o in e)hasOwnProperty.call(e,o)&&(d[o]=e[o]);d.originalType=t,d[k]="string"==typeof t?t:l,i[1]=d;for(var p=2;p=o)&&Object.keys(i.O).every((function(e){return i.O[e](n[c])}))?n.splice(c--,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/"+({53:"935f2afb",133:"f1d66b0d",136:"46fd883c",195:"7e61620b",299:"bb2b9890",347:"ebac4592",405:"1cf6d1c9",446:"5b06504c",514:"1be78505",549:"27551f2e",595:"d0766b26",650:"5f9d379c",710:"42e1775d",723:"54cdf684",750:"f84cc8d5",785:"8e61a1be",833:"0bbf1529",915:"a9ffebd3",918:"17896441",920:"1a4e3797"}[e]||e)+"."+{53:"c78ae141",133:"6862b446",136:"8e859cac",195:"938e94d6",299:"0b886b48",347:"d06dbb3a",405:"3efbf058",446:"205d429a",514:"9062895a",549:"a1c1ab2d",595:"c5627647",650:"c4843529",710:"64f6e20f",723:"cb421c1d",750:"bfeead5a",780:"b979b06f",785:"173b8b1e",833:"0607fb33",894:"4bf7d380",915:"79e7603c",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,c;if(void 0!==n)for(var a=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/"+({53:"935f2afb",133:"f1d66b0d",136:"46fd883c",195:"7e61620b",299:"bb2b9890",347:"ebac4592",405:"1cf6d1c9",446:"5b06504c",514:"1be78505",549:"27551f2e",595:"d0766b26",650:"5f9d379c",710:"42e1775d",723:"54cdf684",750:"f84cc8d5",785:"8e61a1be",833:"0bbf1529",915:"a9ffebd3",918:"17896441",920:"1a4e3797"}[e]||e)+"."+{53:"08870d2a",133:"6862b446",136:"8e859cac",195:"938e94d6",299:"0b886b48",347:"d06dbb3a",405:"3efbf058",446:"af6491d5",514:"9062895a",549:"b7dd53df",595:"c5627647",650:"0b353bf0",710:"64f6e20f",723:"cb421c1d",750:"bfeead5a",780:"b979b06f",785:"173b8b1e",833:"0607fb33",894:"4bf7d380",915:"79e7603c",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 -Changelog | Task +Changelog | Task - +
-

Changelog

v3.24.0 - 2023-04-15

v3.23.0 - 2023-03-26

Task now has an official extension for Visual Studio Code contributed by @pd93! 🎉 The extension is maintained in a new repository under the go-task organization. We're looking to gather feedback from the community so please give it a go and let us know what you think via a discussion, issue or on our Discord!

NOTE: The extension requires v3.23.0 to be installed in order to work.

  • The website was integrated with Crowdin to allow the community to contribute with translations! Chinese is the first language available (#1057, #1058 by @misitebao).
  • Added task location data to the --json flag output (#1056 by @pd93)
  • Change the name of the file generated by task --init from Taskfile.yaml to Taskfile.yml (#1062 by @misitebao).
  • Added new splitArgs template function ({{splitArgs "foo bar 'foo bar baz'"}}) to ensure string is split as arguments (#1040, #1059 by @dhanusaputra).
  • Fix the value of {{.CHECKSUM}} variable in status (#1076, #1080 by @pd93).
  • Fixed deep copy implementation (#1072 by @pd93)
  • Created a tool to assist with releases (#1086 by @pd93).

v3.22.0 - 2023-03-10

  • Add a brand new --global (-g) flag that will run a Taskfile from your $HOME directory. This is useful to have automation that you can run from anywhere in your system! (Documentation, #1029 by @andreynering).
  • Add ability to set error_only: true on the group output mode. This will instruct Task to only print a command output if it returned with a non-zero exit code (#664, #1022 by @jaedle).
  • Fixed bug where .task/checksum file was sometimes not being created when task also declares a status: (#840, #1035 by @harelwa, #1037 by @pd93).
  • Refactored and decoupled fingerprinting from the main Task executor (#1039 by @pd93).
  • Fixed deadlock issue when using run: once (#715, #1025 by @theunrepentantgeek).

v3.21.0 - 2023-02-22

  • Added new TASK_VERSION special variable (#990, #1014 by @ja1code).
  • Fixed a bug where tasks were sometimes incorrectly marked as internal (#1007 by @pd93).
  • Update to Go 1.20 (bump minimum version to 1.19) (#1010 by @pd93)
  • Added environment variable FORCE_COLOR support to force color output. Usefull for environments without TTY (#1003 by @automation-stack)

v3.20.0 - 2023-01-14

  • Improve behavior and performance of status checking when using the timestamp mode (#976, #977 by @aminya).
  • Performance optimizations were made for large Taskfiles (#982 by @pd93).
  • Add ability to configure options for the set and shopt builtins (#908, #929 by @pd93, Documentation).
  • Add new platforms: attribute to task and cmd, so it's now possible to choose in which platforms that given task or command will be run on. Possible values are operating system (GOOS), architecture (GOARCH) or a combination of the two. Example: platforms: [linux], platforms: [amd64] or platforms: [linux/amd64]. Other platforms will be skipped (#978, #980 by @leaanthony).

v3.19.1 - 2022-12-31

  • Small bug fix: closing Taskfile.yml once we're done reading it (#963, #964 by @HeCorr).
  • Fixes a bug in v2 that caused a panic when using a Taskfile_{{OS}}.yml file (#961, #971 by @pd93).
  • Fixed a bug where watch intervals set in the Taskfile were not being respected (#969, #970 by @pd93)
  • Add --json flag (alias -j) with the intent to improve support for code editors and add room to other possible integrations. This is basic for now, but we plan to add more info in the near future (#936 by @davidalpert, #764).

v3.19.0 - 2022-12-05

v3.18.0 - 2022-11-12

  • Show aliases on task --list --silent (task --ls). This means that aliases will be completed by the completion scripts (#919).
  • Tasks in the root Taskfile will now be displayed first in --list/--list-all output (#806, #890).
  • It's now possible to call a default task in an included Taskfile by using just the namespace. For example: docs:default is now automatically aliased to docs (#661, #815).

v3.17.0 - 2022-10-14

  • Add a "Did you mean ...?" suggestion when a task does not exits another one with a similar name is found (#867, #880).
  • Now YAML parse errors will print which Taskfile failed to parse (#885, #887).
  • Add ability to set aliases for tasks and namespaces (#268, #340, #879).
  • Improvements to Fish shell completion (#897).
  • Added ability to set a different watch interval by setting interval: '500ms' or using the --interval=500ms flag (#813, #865).
  • Add colored output to --list, --list-all and --summary flags (#845, #874).
  • Fix unexpected behavior where label: was being shown instead of the task name on --list (#603, #877).

v3.16.0 - 2022-09-29

  • Add npm as new installation method: npm i -g [@go](https://github.com/go)-task/cli (#870, #871, npm package).
  • Add support to marking tasks and includes as internal, which will hide them from --list and --list-all (#818).

v3.15.2 - 2022-09-08

  • Fix error when using variable in env: introduced in the previous release (#858, #866).
  • Fix handling of CLI_ARGS (--) in Bash completion (#863).
  • On zsh completion, add ability to replace --list-all with --list as already possible on the Bash completion (#861).

v3.15.0 - 2022-09-03

  • Add new special variables ROOT_DIR and TASKFILE_DIR. This was a highly requested feature (#215, #857, Documentation).
  • Follow symlinks on sources (#826, #831).
  • Improvements and fixes to Bash completion (#835, #844).

v3.14.1 - 2022-08-03

  • Always resolve relative include paths relative to the including Taskfile (#822, #823).
  • Fix ZSH and PowerShell completions to consider all tasks instead of just the public ones (those with descriptions) (#803).

v3.14.0 - 2022-07-08

  • Add ability to override the .task directory location with the TASK_TEMP_DIR environment variable.
  • Allow to override Task colors using environment variables: TASK_COLOR_RESET, TASK_COLOR_BLUE, TASK_COLOR_GREEN, TASK_COLOR_CYAN, TASK_COLOR_YELLOW, TASK_COLOR_MAGENTA and TASK_COLOR_RED (#568, #792).
  • Fixed bug when using the output: group mode where STDOUT and STDERR were being print in separated blocks instead of in the right order (#779).
  • Starting on this release, ARM architecture binaries are been released to Snap as well (#795).
  • i386 binaries won't be available anymore on Snap because Ubuntu removed the support for this architecture.
  • Upgrade mvdan.cc/sh, which fixes a bug with associative arrays (#785, mvdan/sh[#884](https://github.com/go-task/task/issues/884), mvdan/sh[#893](https://github.com/go-task/task/issues/893)).

v3.13.0 - 2022-06-13

  • Added -n as an alias to --dry (#776, #777).
  • Fix behavior of interrupt (SIGINT, SIGTERM) signals. Task will now give time for the processes running to do cleanup work (#458, #479, #728, #769).
  • Add new --exit-code (-x) flag that will pass-through the exit form the command being ran (#755).

v3.12.1 - 2022-05-10

  • Fixed bug where, on Windows, variables were ending with \r because we were only removing the final \n but not \r\n (#717).

v3.12.0 - 2022-03-31

  • The --list and --list-all flags can now be combined with the --silent flag to print the task names only, without their description (#691).
  • Added support for multi-level inclusion of Taskfiles. This means that included Taskfiles can also include other Taskfiles. Before this was limited to one level (#390, #623, #656).
  • Add ability to specify vars when including a Taskfile. Check out the documentation for more information (#677).

v3.11.0 - 2022-02-19

v3.10.0 - 2022-01-04

  • A new --list-all (alias -a) flag is now available. It's similar to the exiting --list (-l) but prints all tasks, even those without a description (#383, #401).
  • It's now possible to schedule cleanup commands to run once a task finishes with the defer: keyword (Documentation, #475, #626).
  • Remove long deprecated and undocumented $ variable prefix and ^ command prefix (#642, #644, #645).
  • Add support for .yaml extension (as an alternative to .yml). This was requested multiple times throughout the years. Enjoy! (#183, #184, #369, #584, #621).
  • Fixed error when computing a variable when the task directory do not exist yet (#481, #579).

v3.9.2 - 2021-12-02

v3.9.1 - 2021-11-28

v3.9.0 - 2021-10-02

v3.8.0 - 2021-09-26

  • Add interactive: true setting to improve support for interactive CLI apps (#217, #563).
  • Fix some nil errors (#534, #573).
  • Add ability to declare an included Taskfile as optional (#519, #552).
  • Add support for including Taskfiles in the home directory by using ~ (#539, #557).

v3.7.3 - 2021-09-04

v3.7.0 - 2021-07-31

  • Add run: setting to control if tasks should run multiple times or not. Available options are always (the default), when_changed (if a variable modified the task) and once (run only once no matter what). This is a long time requested feature. Enjoy! (#53, #359).

v3.6.0 - 2021-07-10

  • Allow using both sources: and status: in the same task (#411, #427, #477).
  • Small optimization and bug fix: don't compute variables if not needed for dotenv: (#517).

v3.5.0 - 2021-07-04

  • Add support for interpolation in dotenv: (#433, #434, #453).

v3.4.3 - 2021-05-30

v3.4.2 - 2021-04-23

  • On watch, report which file failed to read (#472).
  • Do not try to catch SIGKILL signal, which are not actually possible (#476).
  • Improve version reporting when building Task from source using Go Modules (#462, #473).

v3.4.1 - 2021-04-17

  • Improve error reporting when parsing YAML: in some situations where you would just see an generic error, you'll now see the actual error with more detail: the YAML line the failed to parse, for example (#467).
  • A JSON Schema was published here and is automatically being used by some editors like Visual Studio Code (#135).
  • Print task name before the command in the log output (#398).

v3.3.0 - 2021-03-20

  • Add support for delegating CLI arguments to commands with -- and a special CLI_ARGS variable (#327).
  • Add a --concurrency (alias -C) flag, to limit the number of tasks that run concurrently. This is useful for heavy workloads. (#345).

v3.2.2 - 2021-01-12

  • Improve performance of --list and --summary by skipping running shell variables for these flags (#332).
  • Fixed a bug where an environment in a Taskfile was not always overridable by the system environment (#425).
  • Fixed environment from .env files not being available as variables (#379).
  • The install script is now working for ARM platforms (#428).

v3.2.1 - 2021-01-09

  • Fixed some bugs and regressions regarding dynamic variables and directories (#426).
  • The slim-sprig package was updated with the upstream sprig.

v3.2.0 - 2021-01-07

  • Fix the .task directory being created in the task directory instead of the Taskfile directory (#247).
  • Fix a bug where dynamic variables (those declared with sh:) were not running in the task directory when the task has a custom dir or it was in an included Taskfile (#384).
  • The watch feature (via the --watch flag) got a few different bug fixes and should be more stable now (#423, #365).

v3.1.0 - 2021-01-03

  • Fix a bug when the checksum up-to-date resolution is used by a task with a custom label: attribute (#412).
  • Starting from this release, we're releasing official ARMv6 and ARM64 binaries for Linux (#375, #418).
  • Task now respects the order of declaration of included Taskfiles when evaluating variables declaring by them (#393).
  • set -e is now automatically set on every command. This was done to fix an issue where multiline string commands wouldn't really fail unless the sentence was in the last line (#403).

v3.0.1 - 2020-12-26

  • Allow use as a library by moving the required packages out of the internal directory (#358).
  • Do not error if a specified dotenv file does not exist (#378, #385).
  • Fix panic when you have empty tasks in your Taskfile (#338, #362).

v3.0.0 - 2020-08-16

  • On v3, all CLI variables will be considered global variables (#336, #341)
  • Add support to .env like files (#324, #356).
  • Add label: to task so you can override the task name in the logs ([#321](https://github.com/go-task/task/issues/321), #337).
  • Refactor how variables work on version 3 (#311).
  • Disallow expansions on v3 since it has no effect.
  • Taskvars.yml is not automatically included anymore.
  • Taskfile_{{OS}}.yml is not automatically included anymore.
  • Allow interpolation on includes, so you can manually include a Taskfile based on operation system, for example.
  • Expose .TASK variable in templates with the task name (#252).
  • Implement short task syntax (#194, #240).
  • Added option to make included Taskfile run commands on its own directory (#260, #144)
  • Taskfiles in version 1 are not supported anymore (#237).
  • Added global method: option. With this option, you can set a default method to all tasks in a Taskfile (#246).
  • Changed default method from timestamp to checksum (#246).
  • New magic variables are now available when using status:: .TIMESTAMP which contains the greatest modification date from the files listed in sources:, and .CHECKSUM, which contains a checksum of all files listed in status:. This is useful for manual checking when using external, or even remote, artifacts when using status: (#216).
  • We're now using slim-sprig instead of sprig, which allowed a file size reduction of about 22% (#219).
  • We now use some colors on Task output to better distinguish message types - commands are green, errors are red, etc (#207).

v2.8.1 - 2020-05-20

  • Fix error code for the --help flag (#300, #330).
  • Print version to stdout instead of stderr (#299, #329).
  • Supress context errors when using the --watch flag (#313, #317).
  • Support templating on description (#276, #283).

v2.8.0 - 2019-12-07

  • Add --parallel flag (alias -p) to run tasks given by the command line in parallel (#266).
  • Fixed bug where calling the task CLI only informing global vars would not execute the default task.
  • Add hability to silent all tasks by adding silent: true a the root of the Taskfile.

v2.7.1 - 2019-11-10

  • Fix error being raised when exit 0 was called (#251).

v2.7.0 - 2019-09-22

  • Fixed panic bug when assigning a global variable (#229, #243).
  • A task with method: checksum will now re-run if generated files are deleted (#228, #238).

v2.6.0 - 2019-07-21

  • Fixed some bugs regarding minor version checks on version:.
  • Add preconditions: to task (#205).
  • Create directory informed on dir: if it doesn't exist (#209, #211).
  • We now have a --taskfile flag (alias -t), which can be used to run another Taskfile (other than the default Taskfile.yml) (#221).
  • It's now possible to install Task using Homebrew on Linux (go-task/homebrew-tap[#1](https://github.com/go-task/task/issues/1)).

v2.5.2 - 2019-05-11

2.5.1 - 2019-04-27

  • Fixed some issues with interactive command line tools, where sometimes the output were not being shown, and similar issues (#114, #190, #200).
  • Upgraded go-yaml/yaml from v2 to v3.

v2.5.0 - 2019-03-16

v2.4.0 - 2019-02-21

  • Allow calling a task of the root Taskfile from an included Taskfile by prefixing it with : (#161, #172).
  • Add flag to override the output option (#173).
  • Fix bug where Task was persisting the new checksum on the disk when the Dry Mode is enabled (#166).
  • Fix file timestamp issue when the file name has spaces (#176).
  • Mitigating path expanding issues on Windows (#170).

v2.3.0 - 2019-01-02

  • On Windows, Task can now be installed using Scoop (#152).
  • Fixed issue with file/directory globing (#153).
  • Added ability to globally set environment variables (#138, #159).

v2.2.1 - 2018-12-09

  • This repository now uses Go Modules (#143). We'll still keep the vendor directory in sync for some time, though;
  • Fixing a bug when the Taskfile has no tasks but includes another Taskfile (#150);
  • Fix a bug when calling another task or a dependency in an included Taskfile (#151).

v2.2.0 - 2018-10-25

  • Added support for including other Taskfiles (#98)
    • This should be considered experimental. For now, only including local files is supported, but support for including remote Taskfiles is being discussed. If you have any feedback, please comment on #98.
  • Task now have a dedicated documentation site: https://taskfile.org
    • Thanks to Docsify for making this pretty easy. To check the source code, just take a look at the docs directory of this repository. Contributions to the documentation is really appreciated.

v2.1.1 - 2018-09-17

  • Fix suggestion to use task --init not being shown anymore (when a Taskfile.yml is not found)
  • Fix error when using checksum method and no file exists for a source glob (#131)
  • Fix signal handling when the --watch flag is given (#132)

v2.1.0 - 2018-08-19

  • Add a ignore_error option to task and command (#123)
  • Add a dry run mode (--dry flag) (#126)

v2.0.3 - 2018-06-24

  • Expand environment variables on "dir", "sources" and "generates" (#116)
  • Fix YAML merging syntax (#112)
  • Add ZSH completion (#111)
  • Implement new output option. Please check out the documentation

v2.0.2 - 2018-05-01

  • Fix merging of YAML anchors (#112)

v2.0.1 - 2018-03-11

  • Fixes panic on task --list

v2.0.0 - 2018-03-08

Version 2.0.0 is here, with a new Taskfile format.

Please, make sure to read the Taskfile versions document, since it describes in depth what changed for this version.

  • New Taskfile version 2 (#77)
  • Possibility to have global variables in the Taskfile.yml instead of Taskvars.yml (#66)
  • Small improvements and fixes

v1.4.4 - 2017-11-19

  • Handle SIGINT and SIGTERM (#75);
  • List: print message with there's no task with description;
  • Expand home dir ("~" symbol) on paths (#74);
  • Add Snap as an installation method;
  • Move examples to its own repo;
  • Watch: also walk on tasks called on on "cmds", and not only on "deps";
  • Print logs to stderr instead of stdout (#68);
  • Remove deprecated set keyword;
  • Add checksum based status check, alternative to timestamp based.

v1.4.3 - 2017-09-07

  • Allow assigning variables to tasks at run time via CLI (#33)
  • Added suport for multiline variables from sh (#64)
  • Fixes env: remove square braces and evaluate shell (#62)
  • Watch: change watch library and few fixes and improvements
  • When use watching, cancel and restart long running process on file change (#59 and #60)

v1.4.2 - 2017-07-30

  • Flag to set directory of execution
  • Always echo command if is verbose mode
  • Add silent mode to disable echoing of commands
  • Fixes and improvements of variables (#56)

v1.4.1 - 2017-07-15

  • Allow use of YAML for dynamic variables instead of $ prefix
    • VAR: {sh: echo Hello} instead of VAR: $echo Hello
  • Add --list (or -l) flag to print existing tasks
  • OS specific Taskvars file (e.g. Taskvars_windows.yml, Taskvars_linux.yml, etc)
  • Consider task up-to-date on equal timestamps (#49)
  • Allow absolute path in generates section (#48)
  • Bugfix: allow templating when calling deps (#42)
  • Fix panic for invalid task in cyclic dep detection
  • Better error output for dynamic variables in Taskvars.yml (#41)
  • Allow template evaluation in parameters

v1.4.0 - 2017-07-06

  • Cache dynamic variables
  • Add verbose mode (-v flag)
  • Support to task parameters (overriding vars) (#31) (#32)
  • Print command, also when "set:" is specified (#35)
  • Improve task command help text (#35)

v1.3.1 - 2017-06-14

  • Fix glob not working on commands (#28)
  • Add ExeExt template function
  • Add --init flag to create a new Taskfile
  • Add status option to prevent task from running (#27)
  • Allow interpolation on generates and sources attributes (#26)

v1.3.0 - 2017-04-24

  • Migrate from os/exec.Cmd to a native Go sh/bash interpreter
    • This is a potentially breaking change if you use Windows.
    • Now, cmd is not used anymore on Windows. Always use Bash-like syntax for your commands, even on Windows.
  • Add "ToSlash" and "FromSlash" to template functions
  • Use functions defined on github.com/Masterminds/sprig
  • Do not redirect stdin while running variables commands
  • Using context and errgroup packages (this will make other tasks to be cancelled, if one returned an error)

v1.2.0 - 2017-04-02

  • More tests and Travis integration
  • Watch a task (experimental)
  • Possibility to call another task
  • Fix "=" not being reconized in variables/environment variables
  • Tasks can now have a description, and help will print them (#10)
  • Task dependencies now run concurrently
  • Support for a default task (#16)

v1.1.0 - 2017-03-08

  • Support for YAML, TOML and JSON (#1)
  • Support running command in another directory (#4)
  • --force or -f flag to force execution of task even when it's up-to-date
  • Detection of cyclic dependencies (#5)
  • Support for variables (#6, #9, #14)
  • Operation System specific commands and variables (#13)

v1.0.0 - 2017-02-28

  • Add LICENSE file
- +

Changelog

v3.25.0 - 2023-05-22

  • Support silent: when calling another tasks (#680, #1142 by @danquah).
  • Improve PowerShell completion script (#1168 by @trim21).
  • Add more languages to the website menu and show translation progress percentage (#1173 by @misitebao).
  • Starting on this release, official binaries for FreeBSD will be available to download (#1068 by @andreynering).
  • Fix some errors being unintendedly supressed (#1134 by @clintmod).
  • Fix a nil pointer error when version is omitted from a Taskfile (#1148, #1149 by @pd93).
  • Fix duplicate error message when a task does not exists (#1141, #1144 by @pd93).

v3.24.0 - 2023-04-15

v3.23.0 - 2023-03-26

Task now has an official extension for Visual Studio Code contributed by @pd93! 🎉 The extension is maintained in a new repository under the go-task organization. We're looking to gather feedback from the community so please give it a go and let us know what you think via a discussion, issue or on our Discord!

NOTE: The extension requires v3.23.0 to be installed in order to work.

  • The website was integrated with Crowdin to allow the community to contribute with translations! Chinese is the first language available (#1057, #1058 by @misitebao).
  • Added task location data to the --json flag output (#1056 by @pd93)
  • Change the name of the file generated by task --init from Taskfile.yaml to Taskfile.yml (#1062 by @misitebao).
  • Added new splitArgs template function ({{splitArgs "foo bar 'foo bar baz'"}}) to ensure string is split as arguments (#1040, #1059 by @dhanusaputra).
  • Fix the value of {{.CHECKSUM}} variable in status (#1076, #1080 by @pd93).
  • Fixed deep copy implementation (#1072 by @pd93)
  • Created a tool to assist with releases (#1086 by @pd93).

v3.22.0 - 2023-03-10

  • Add a brand new --global (-g) flag that will run a Taskfile from your $HOME directory. This is useful to have automation that you can run from anywhere in your system! (Documentation, #1029 by @andreynering).
  • Add ability to set error_only: true on the group output mode. This will instruct Task to only print a command output if it returned with a non-zero exit code (#664, #1022 by @jaedle).
  • Fixed bug where .task/checksum file was sometimes not being created when task also declares a status: (#840, #1035 by @harelwa, #1037 by @pd93).
  • Refactored and decoupled fingerprinting from the main Task executor (#1039 by @pd93).
  • Fixed deadlock issue when using run: once (#715, #1025 by @theunrepentantgeek).

v3.21.0 - 2023-02-22

  • Added new TASK_VERSION special variable (#990, #1014 by @ja1code).
  • Fixed a bug where tasks were sometimes incorrectly marked as internal (#1007 by @pd93).
  • Update to Go 1.20 (bump minimum version to 1.19) (#1010 by @pd93)
  • Added environment variable FORCE_COLOR support to force color output. Usefull for environments without TTY (#1003 by @automation-stack)

v3.20.0 - 2023-01-14

  • Improve behavior and performance of status checking when using the timestamp mode (#976, #977 by @aminya).
  • Performance optimizations were made for large Taskfiles (#982 by @pd93).
  • Add ability to configure options for the set and shopt builtins (#908, #929 by @pd93, Documentation).
  • Add new platforms: attribute to task and cmd, so it's now possible to choose in which platforms that given task or command will be run on. Possible values are operating system (GOOS), architecture (GOARCH) or a combination of the two. Example: platforms: [linux], platforms: [amd64] or platforms: [linux/amd64]. Other platforms will be skipped (#978, #980 by @leaanthony).

v3.19.1 - 2022-12-31

  • Small bug fix: closing Taskfile.yml once we're done reading it (#963, #964 by @HeCorr).
  • Fixes a bug in v2 that caused a panic when using a Taskfile_{{OS}}.yml file (#961, #971 by @pd93).
  • Fixed a bug where watch intervals set in the Taskfile were not being respected (#969, #970 by @pd93)
  • Add --json flag (alias -j) with the intent to improve support for code editors and add room to other possible integrations. This is basic for now, but we plan to add more info in the near future (#936 by @davidalpert, #764).

v3.19.0 - 2022-12-05

v3.18.0 - 2022-11-12

  • Show aliases on task --list --silent (task --ls). This means that aliases will be completed by the completion scripts (#919).
  • Tasks in the root Taskfile will now be displayed first in --list/--list-all output (#806, #890).
  • It's now possible to call a default task in an included Taskfile by using just the namespace. For example: docs:default is now automatically aliased to docs (#661, #815).

v3.17.0 - 2022-10-14

  • Add a "Did you mean ...?" suggestion when a task does not exits another one with a similar name is found (#867, #880).
  • Now YAML parse errors will print which Taskfile failed to parse (#885, #887).
  • Add ability to set aliases for tasks and namespaces (#268, #340, #879).
  • Improvements to Fish shell completion (#897).
  • Added ability to set a different watch interval by setting interval: '500ms' or using the --interval=500ms flag (#813, #865).
  • Add colored output to --list, --list-all and --summary flags (#845, #874).
  • Fix unexpected behavior where label: was being shown instead of the task name on --list (#603, #877).

v3.16.0 - 2022-09-29

  • Add npm as new installation method: npm i -g [@go](https://github.com/go)-task/cli (#870, #871, npm package).
  • Add support to marking tasks and includes as internal, which will hide them from --list and --list-all (#818).

v3.15.2 - 2022-09-08

  • Fix error when using variable in env: introduced in the previous release (#858, #866).
  • Fix handling of CLI_ARGS (--) in Bash completion (#863).
  • On zsh completion, add ability to replace --list-all with --list as already possible on the Bash completion (#861).

v3.15.0 - 2022-09-03

  • Add new special variables ROOT_DIR and TASKFILE_DIR. This was a highly requested feature (#215, #857, Documentation).
  • Follow symlinks on sources (#826, #831).
  • Improvements and fixes to Bash completion (#835, #844).

v3.14.1 - 2022-08-03

  • Always resolve relative include paths relative to the including Taskfile (#822, #823).
  • Fix ZSH and PowerShell completions to consider all tasks instead of just the public ones (those with descriptions) (#803).

v3.14.0 - 2022-07-08

  • Add ability to override the .task directory location with the TASK_TEMP_DIR environment variable.
  • Allow to override Task colors using environment variables: TASK_COLOR_RESET, TASK_COLOR_BLUE, TASK_COLOR_GREEN, TASK_COLOR_CYAN, TASK_COLOR_YELLOW, TASK_COLOR_MAGENTA and TASK_COLOR_RED (#568, #792).
  • Fixed bug when using the output: group mode where STDOUT and STDERR were being print in separated blocks instead of in the right order (#779).
  • Starting on this release, ARM architecture binaries are been released to Snap as well (#795).
  • i386 binaries won't be available anymore on Snap because Ubuntu removed the support for this architecture.
  • Upgrade mvdan.cc/sh, which fixes a bug with associative arrays (#785, mvdan/sh[#884](https://github.com/go-task/task/issues/884), mvdan/sh[#893](https://github.com/go-task/task/issues/893)).

v3.13.0 - 2022-06-13

  • Added -n as an alias to --dry (#776, #777).
  • Fix behavior of interrupt (SIGINT, SIGTERM) signals. Task will now give time for the processes running to do cleanup work (#458, #479, #728, #769).
  • Add new --exit-code (-x) flag that will pass-through the exit form the command being ran (#755).

v3.12.1 - 2022-05-10

  • Fixed bug where, on Windows, variables were ending with \r because we were only removing the final \n but not \r\n (#717).

v3.12.0 - 2022-03-31

  • The --list and --list-all flags can now be combined with the --silent flag to print the task names only, without their description (#691).
  • Added support for multi-level inclusion of Taskfiles. This means that included Taskfiles can also include other Taskfiles. Before this was limited to one level (#390, #623, #656).
  • Add ability to specify vars when including a Taskfile. Check out the documentation for more information (#677).

v3.11.0 - 2022-02-19

v3.10.0 - 2022-01-04

  • A new --list-all (alias -a) flag is now available. It's similar to the exiting --list (-l) but prints all tasks, even those without a description (#383, #401).
  • It's now possible to schedule cleanup commands to run once a task finishes with the defer: keyword (Documentation, #475, #626).
  • Remove long deprecated and undocumented $ variable prefix and ^ command prefix (#642, #644, #645).
  • Add support for .yaml extension (as an alternative to .yml). This was requested multiple times throughout the years. Enjoy! (#183, #184, #369, #584, #621).
  • Fixed error when computing a variable when the task directory do not exist yet (#481, #579).

v3.9.2 - 2021-12-02

v3.9.1 - 2021-11-28

v3.9.0 - 2021-10-02

v3.8.0 - 2021-09-26

  • Add interactive: true setting to improve support for interactive CLI apps (#217, #563).
  • Fix some nil errors (#534, #573).
  • Add ability to declare an included Taskfile as optional (#519, #552).
  • Add support for including Taskfiles in the home directory by using ~ (#539, #557).

v3.7.3 - 2021-09-04

v3.7.0 - 2021-07-31

  • Add run: setting to control if tasks should run multiple times or not. Available options are always (the default), when_changed (if a variable modified the task) and once (run only once no matter what). This is a long time requested feature. Enjoy! (#53, #359).

v3.6.0 - 2021-07-10

  • Allow using both sources: and status: in the same task (#411, #427, #477).
  • Small optimization and bug fix: don't compute variables if not needed for dotenv: (#517).

v3.5.0 - 2021-07-04

  • Add support for interpolation in dotenv: (#433, #434, #453).

v3.4.3 - 2021-05-30

v3.4.2 - 2021-04-23

  • On watch, report which file failed to read (#472).
  • Do not try to catch SIGKILL signal, which are not actually possible (#476).
  • Improve version reporting when building Task from source using Go Modules (#462, #473).

v3.4.1 - 2021-04-17

  • Improve error reporting when parsing YAML: in some situations where you would just see an generic error, you'll now see the actual error with more detail: the YAML line the failed to parse, for example (#467).
  • A JSON Schema was published here and is automatically being used by some editors like Visual Studio Code (#135).
  • Print task name before the command in the log output (#398).

v3.3.0 - 2021-03-20

  • Add support for delegating CLI arguments to commands with -- and a special CLI_ARGS variable (#327).
  • Add a --concurrency (alias -C) flag, to limit the number of tasks that run concurrently. This is useful for heavy workloads. (#345).

v3.2.2 - 2021-01-12

  • Improve performance of --list and --summary by skipping running shell variables for these flags (#332).
  • Fixed a bug where an environment in a Taskfile was not always overridable by the system environment (#425).
  • Fixed environment from .env files not being available as variables (#379).
  • The install script is now working for ARM platforms (#428).

v3.2.1 - 2021-01-09

  • Fixed some bugs and regressions regarding dynamic variables and directories (#426).
  • The slim-sprig package was updated with the upstream sprig.

v3.2.0 - 2021-01-07

  • Fix the .task directory being created in the task directory instead of the Taskfile directory (#247).
  • Fix a bug where dynamic variables (those declared with sh:) were not running in the task directory when the task has a custom dir or it was in an included Taskfile (#384).
  • The watch feature (via the --watch flag) got a few different bug fixes and should be more stable now (#423, #365).

v3.1.0 - 2021-01-03

  • Fix a bug when the checksum up-to-date resolution is used by a task with a custom label: attribute (#412).
  • Starting from this release, we're releasing official ARMv6 and ARM64 binaries for Linux (#375, #418).
  • Task now respects the order of declaration of included Taskfiles when evaluating variables declaring by them (#393).
  • set -e is now automatically set on every command. This was done to fix an issue where multiline string commands wouldn't really fail unless the sentence was in the last line (#403).

v3.0.1 - 2020-12-26

  • Allow use as a library by moving the required packages out of the internal directory (#358).
  • Do not error if a specified dotenv file does not exist (#378, #385).
  • Fix panic when you have empty tasks in your Taskfile (#338, #362).

v3.0.0 - 2020-08-16

  • On v3, all CLI variables will be considered global variables (#336, #341)
  • Add support to .env like files (#324, #356).
  • Add label: to task so you can override the task name in the logs ([#321](https://github.com/go-task/task/issues/321), #337).
  • Refactor how variables work on version 3 (#311).
  • Disallow expansions on v3 since it has no effect.
  • Taskvars.yml is not automatically included anymore.
  • Taskfile_{{OS}}.yml is not automatically included anymore.
  • Allow interpolation on includes, so you can manually include a Taskfile based on operation system, for example.
  • Expose .TASK variable in templates with the task name (#252).
  • Implement short task syntax (#194, #240).
  • Added option to make included Taskfile run commands on its own directory (#260, #144)
  • Taskfiles in version 1 are not supported anymore (#237).
  • Added global method: option. With this option, you can set a default method to all tasks in a Taskfile (#246).
  • Changed default method from timestamp to checksum (#246).
  • New magic variables are now available when using status:: .TIMESTAMP which contains the greatest modification date from the files listed in sources:, and .CHECKSUM, which contains a checksum of all files listed in status:. This is useful for manual checking when using external, or even remote, artifacts when using status: (#216).
  • We're now using slim-sprig instead of sprig, which allowed a file size reduction of about 22% (#219).
  • We now use some colors on Task output to better distinguish message types - commands are green, errors are red, etc (#207).

v2.8.1 - 2020-05-20

  • Fix error code for the --help flag (#300, #330).
  • Print version to stdout instead of stderr (#299, #329).
  • Supress context errors when using the --watch flag (#313, #317).
  • Support templating on description (#276, #283).

v2.8.0 - 2019-12-07

  • Add --parallel flag (alias -p) to run tasks given by the command line in parallel (#266).
  • Fixed bug where calling the task CLI only informing global vars would not execute the default task.
  • Add hability to silent all tasks by adding silent: true a the root of the Taskfile.

v2.7.1 - 2019-11-10

  • Fix error being raised when exit 0 was called (#251).

v2.7.0 - 2019-09-22

  • Fixed panic bug when assigning a global variable (#229, #243).
  • A task with method: checksum will now re-run if generated files are deleted (#228, #238).

v2.6.0 - 2019-07-21

  • Fixed some bugs regarding minor version checks on version:.
  • Add preconditions: to task (#205).
  • Create directory informed on dir: if it doesn't exist (#209, #211).
  • We now have a --taskfile flag (alias -t), which can be used to run another Taskfile (other than the default Taskfile.yml) (#221).
  • It's now possible to install Task using Homebrew on Linux (go-task/homebrew-tap[#1](https://github.com/go-task/task/issues/1)).

v2.5.2 - 2019-05-11

2.5.1 - 2019-04-27

  • Fixed some issues with interactive command line tools, where sometimes the output were not being shown, and similar issues (#114, #190, #200).
  • Upgraded go-yaml/yaml from v2 to v3.

v2.5.0 - 2019-03-16

v2.4.0 - 2019-02-21

  • Allow calling a task of the root Taskfile from an included Taskfile by prefixing it with : (#161, #172).
  • Add flag to override the output option (#173).
  • Fix bug where Task was persisting the new checksum on the disk when the Dry Mode is enabled (#166).
  • Fix file timestamp issue when the file name has spaces (#176).
  • Mitigating path expanding issues on Windows (#170).

v2.3.0 - 2019-01-02

  • On Windows, Task can now be installed using Scoop (#152).
  • Fixed issue with file/directory globing (#153).
  • Added ability to globally set environment variables (#138, #159).

v2.2.1 - 2018-12-09

  • This repository now uses Go Modules (#143). We'll still keep the vendor directory in sync for some time, though;
  • Fixing a bug when the Taskfile has no tasks but includes another Taskfile (#150);
  • Fix a bug when calling another task or a dependency in an included Taskfile (#151).

v2.2.0 - 2018-10-25

  • Added support for including other Taskfiles (#98)
    • This should be considered experimental. For now, only including local files is supported, but support for including remote Taskfiles is being discussed. If you have any feedback, please comment on #98.
  • Task now have a dedicated documentation site: https://taskfile.org
    • Thanks to Docsify for making this pretty easy. To check the source code, just take a look at the docs directory of this repository. Contributions to the documentation is really appreciated.

v2.1.1 - 2018-09-17

  • Fix suggestion to use task --init not being shown anymore (when a Taskfile.yml is not found)
  • Fix error when using checksum method and no file exists for a source glob (#131)
  • Fix signal handling when the --watch flag is given (#132)

v2.1.0 - 2018-08-19

  • Add a ignore_error option to task and command (#123)
  • Add a dry run mode (--dry flag) (#126)

v2.0.3 - 2018-06-24

  • Expand environment variables on "dir", "sources" and "generates" (#116)
  • Fix YAML merging syntax (#112)
  • Add ZSH completion (#111)
  • Implement new output option. Please check out the documentation

v2.0.2 - 2018-05-01

  • Fix merging of YAML anchors (#112)

v2.0.1 - 2018-03-11

  • Fixes panic on task --list

v2.0.0 - 2018-03-08

Version 2.0.0 is here, with a new Taskfile format.

Please, make sure to read the Taskfile versions document, since it describes in depth what changed for this version.

  • New Taskfile version 2 (#77)
  • Possibility to have global variables in the Taskfile.yml instead of Taskvars.yml (#66)
  • Small improvements and fixes

v1.4.4 - 2017-11-19

  • Handle SIGINT and SIGTERM (#75);
  • List: print message with there's no task with description;
  • Expand home dir ("~" symbol) on paths (#74);
  • Add Snap as an installation method;
  • Move examples to its own repo;
  • Watch: also walk on tasks called on on "cmds", and not only on "deps";
  • Print logs to stderr instead of stdout (#68);
  • Remove deprecated set keyword;
  • Add checksum based status check, alternative to timestamp based.

v1.4.3 - 2017-09-07

  • Allow assigning variables to tasks at run time via CLI (#33)
  • Added suport for multiline variables from sh (#64)
  • Fixes env: remove square braces and evaluate shell (#62)
  • Watch: change watch library and few fixes and improvements
  • When use watching, cancel and restart long running process on file change (#59 and #60)

v1.4.2 - 2017-07-30

  • Flag to set directory of execution
  • Always echo command if is verbose mode
  • Add silent mode to disable echoing of commands
  • Fixes and improvements of variables (#56)

v1.4.1 - 2017-07-15

  • Allow use of YAML for dynamic variables instead of $ prefix
    • VAR: {sh: echo Hello} instead of VAR: $echo Hello
  • Add --list (or -l) flag to print existing tasks
  • OS specific Taskvars file (e.g. Taskvars_windows.yml, Taskvars_linux.yml, etc)
  • Consider task up-to-date on equal timestamps (#49)
  • Allow absolute path in generates section (#48)
  • Bugfix: allow templating when calling deps (#42)
  • Fix panic for invalid task in cyclic dep detection
  • Better error output for dynamic variables in Taskvars.yml (#41)
  • Allow template evaluation in parameters

v1.4.0 - 2017-07-06

  • Cache dynamic variables
  • Add verbose mode (-v flag)
  • Support to task parameters (overriding vars) (#31) (#32)
  • Print command, also when "set:" is specified (#35)
  • Improve task command help text (#35)

v1.3.1 - 2017-06-14

  • Fix glob not working on commands (#28)
  • Add ExeExt template function
  • Add --init flag to create a new Taskfile
  • Add status option to prevent task from running (#27)
  • Allow interpolation on generates and sources attributes (#26)

v1.3.0 - 2017-04-24

  • Migrate from os/exec.Cmd to a native Go sh/bash interpreter
    • This is a potentially breaking change if you use Windows.
    • Now, cmd is not used anymore on Windows. Always use Bash-like syntax for your commands, even on Windows.
  • Add "ToSlash" and "FromSlash" to template functions
  • Use functions defined on github.com/Masterminds/sprig
  • Do not redirect stdin while running variables commands
  • Using context and errgroup packages (this will make other tasks to be cancelled, if one returned an error)

v1.2.0 - 2017-04-02

  • More tests and Travis integration
  • Watch a task (experimental)
  • Possibility to call another task
  • Fix "=" not being reconized in variables/environment variables
  • Tasks can now have a description, and help will print them (#10)
  • Task dependencies now run concurrently
  • Support for a default task (#16)

v1.1.0 - 2017-03-08

  • Support for YAML, TOML and JSON (#1)
  • Support running command in another directory (#4)
  • --force or -f flag to force execution of task even when it's up-to-date
  • Detection of cyclic dependencies (#5)
  • Support for variables (#6, #9, #14)
  • Operation System specific commands and variables (#13)

v1.0.0 - 2017-02-28

  • Add LICENSE file
+ \ No newline at end of file diff --git a/ru-RU/community/index.html b/ru-RU/community/index.html index f2094368..86082462 100644 --- a/ru-RU/community/index.html +++ b/ru-RU/community/index.html @@ -10,13 +10,13 @@ - +

Сообщество

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.

Переводчики

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

Integrations

Many of our integrations are contributed and maintained by the community. You can view the full list of community integrations here.

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.

- + \ No newline at end of file diff --git a/ru-RU/contributing/index.html b/ru-RU/contributing/index.html index 4b0a7bd1..0f3bb963 100644 --- a/ru-RU/contributing/index.html +++ b/ru-RU/contributing/index.html @@ -10,13 +10,13 @@ - +

Помощь проекту

Любой вклад в Task очень приветствуется, но мы просим вас прочитать этот документ, прежде чем отправлять pull request(PR).

примечание

Этот документ относится к основному репозиторию Task и Task for Visual Studio Code

Введение

  • Текущее состояние разработки - Проверьте уже открытые PR. Есть ли открытые "issues", обсуждающие особенности/изменения, которые вы хотите выполнить? Пожалуйста, убедитесь, что вы учитываете результаты этих обсуждений в своей работе.
  • Обратная совместимость - Повлияют ли ваши изменения на уже существующие TaskFile'ы? Скорее всего, ваше изменение будет применено, если оно обладает обратной совместимостью. Существует ли подход, который вы можете использовать для поддержания обратной совместимости? Если нет, откройте проблему(Вот тут "Issues"), чтобы изменения API могли быть обсуждены до того, как вы потратите своё время на PR.

1. Настройка

  • Go - Task написан на Go. Мы всегда поддерживаем две последних основных версий Go, поэтому убедитесь, что у вас установлена актуальная версия.
  • Node.js - Node.js используется для хостинга сервера документации Task и требуется для локального запуска этого сервера. Node.js также необходим для того, чтобы внести свой вклад в расширение Visual Studio Code.
  • Yarn - Yarn является менеджером пакетов Node.js, используемым в Task.

2. Внести изменения

  • Code style - Настоятельно рекомендуем поддерживать существующий стиль кода по мере возможности. Код должен быть отформатирован gofumpt и проверен golangci-lint линтером. Любые файлы Markdown или TypeScript должны быть отформатированы с помощью Prettier. Стиль кода внедряется нашим CI для обеспечения того, чтобы у всех был одинаковый стиль кода в рамках проекта. Вы можете использовать команду task lint для локальной проверки линтером и task lint:fix для автоматического исправления любых обнаруженных проблем.
  • Документация - Убедитесь, что вы добавляете/обновляете любую соответствующую документацию. Секцию обновления документации можно увидеть ниже.
  • Тесты - Убедитесь, что вы добавляете/обновляете любые релевантные тесты и что все тесты проходят перед отправкой PR. Секцию написание тестов можно увидеть ниже.

Запуск ваших изменений

Чтобы запустить Task с рабочими изменениями, используйте go run ./cmd/task. Для запуска тестовой сборки задачи с Taskfile в testdata, вы можете использовать go run ./cmd/task --dir ./testdata/<my_test_dir> <task_name>.

Для запуска Task для Visual Studio кода, вы можете открыть проект в VSCode и нажать F5 (или любую другую клавишу, к которой вы привязали функцию отладки). Это откроет новое окно VSCode с запущенным расширением. Мы рекомендуем использовать функцию отладки, так как это позволит вам задать точки останова. Также вы можете запустить пакет задач task package для генерации .vsix файла, который может быть использован для ручной установки расширения.

Обновление документации

Task использует Docusaurus для размещения сервера документации. Код для неё находится в основном Task репозитории. Документация может быть настроена и запущена локально с помощью task docs (требуется установка nodejs & yarn). Все содержимое написано в Markdown и находится в директории docs/docs. Все документы Markdown должны иметь максимальную длину строки 80 символов (этого требует Prettier).

При внесении изменений подумайте, является ли необходимым изменение Руководства по использованию. Этот документ содержит описания и примеры использования Task функций. Если вы добавляете новую функцию, попробуйте найти подходящее место для добавления новой секции. Если вы обновляете существующую функцию, убедитесь, что документация и любые примеры актуальны. Убедитесь, что любые примеры следуют Taskfile Styleguide.

Если вы добавили новое поле, команду или флаг, убедитесь, что вы добавляете его в Справочник API. Новые поля также необходимо добавить в JSON схему. Описания полей в справочнике API и JSON схеме должны совпадать.

Написание тестов

Тесты расположены в файле task_test.go в корневом каталоге, рекомендуем добавлять новые тесты именно в него. Большинство этих тестов также имеют поддиректорию в testdata, где хранятся любые Taskfiles/данные, необходимые для запуска тестов.

При внесении изменений подумайте о необходимости новых тестов. Эти тесты должны гарантировать, что функционал, который вы добавили, продолжит работу в будущем. Существующие тесты также могут потребовать обновления, если вы изменили поведение Task.

Вы также можете добавить модульный тест для любых новых функций, которые добавляете. Модульные тесты должны следовать Go соглашению о местоположении в файле *_test.o в том же пакете, что и тестируемый код.

3. Внесение кода

Попробуйте написать содержательное сообщение к коммиту и не иметь слишком много коммитов в PR. Большинство PR, желательно, должны иметь один коммит (хотя для больших PR может быть разумным разделить его несколько коммитов). Используйте git squash и rebase!

Если вы не уверены, как отформатировать ваше сообщение, проверьте Соглашение о коммитах. Этот стиль не используется в проекте, но это хороший способ сделать ваше сообщение для коммита более читаемым и последовательным.

4. Отправка PR

  • Опишите ваши изменения - Убедитесь, что вы предоставили подробное описание ваших изменений.
  • Issue/PR ссылки - Укажите ссылки на предыдущую работу, которая связанна с вашим PR. Пожалуйста, опишите, как ваши изменения изменяют или расширяют эту работу.
  • Примеры - Добавьте любые примеры или скриншоты, которые демонстрируют ваши изменения.
  • Черновик PRs - Если ваши изменения не закончены, но вы хотели бы обсудить их, открыть PR как черновик и добавьте комментарии, чтобы начать обсуждение. Использование комментариев, а не PR описания позволяет обновить описание позже при сохранении любых обсуждений.

Ответы на вопросы

Я хочу внести свой вклад, с чего начать?

Ознакомьтесь со списком open issues for Task или Task for Visual Studio Code. У нас есть лейбл good first issue для простейших проблем, который идеально подходит для контрибьюторов, который первых вносят свой вклад.

Приветствуются всевозможные вклады, будь то маленький фикс или новая функция. Вы также можете внести свой вклад, комментируя вопросы, помогая ответить на вопросы или внести вклад в другие проекты сообщества.

Где можно получить помощь?

Если у вас есть вопросы, не стесняйтесь спросить их в канале #help на нашем Discord сервере или откройте Discussion на GitHub.


- + \ No newline at end of file diff --git a/ru-RU/donate/index.html b/ru-RU/donate/index.html index 069ba3f0..813336a8 100644 --- a/ru-RU/donate/index.html +++ b/ru-RU/donate/index.html @@ -10,13 +10,13 @@ - +

Поддержать

Если вам нравится этот проект, вы можете подумать о том, чтобы пожертвовать, используя один из способов, перечисленных ниже.

Это просто способ сказать "спасибо", это не дает вам никаких преимуществ, таких как высший приоритет при рассмотрении проблем или что-то подобное.

Компании, которые пожертвуют не менее $50 в месяц, будут представлены как "Золотые спонсоры" на главной странице сайта и в README репозитория на GitHub. Свяжитесь с @andreynering и предоставьте ему нужный логотип. Подозрительные бизнесы (связанные с азартными играми, казино и т.д.) не будут допущены к спонсорству.

GitHub Sponsors

Предпочтительный способ пожертвования для сопровождающих — через GitHub Sponsors. Просто используйте следующие ссылки, чтобы сделать пожертвование:

Open Collective

Если вы предпочитаете Open Collective, вы можете пожертвовать используя следующие ссылки:

PayPal

Вы можете сделать пожертвование @andreynering через PayPal:

PIX (только для Бразилии)

Если вы из Бразилии, вы можете также пожертвовать @andreynering через PIX с помощью этого QR-кода.

- + \ No newline at end of file diff --git a/ru-RU/faq/index.html b/ru-RU/faq/index.html index 416ddcd0..e08cac5f 100644 --- a/ru-RU/faq/index.html +++ b/ru-RU/faq/index.html @@ -10,13 +10,13 @@ - +

FAQ

This page contains a list of frequently asked questions about Task.

Why won't my task update my shell environment?

This is a limitation of how shells work. Task runs as a subprocess of your current shell, so it can't change the environment of the shell that started it. This limitation is shared by other task runners and build tools too.

A common way to work around this is to create a task that will generate output that can be parsed by your shell. For example, to set an environment variable on your shell you can write a task like this:

my-shell-env:
cmds:
- echo "export FOO=foo"
- echo "export BAR=bar"

Now run eval $(task my-shell-env) and the variables $FOO and $BAR will be available in your shell.

'x' builtin command doesn't work on Windows

The default shell on Windows (cmd and powershell) do not have commands like rm and cp available as builtins. This means that these commands won't work. If you want to make your Taskfile fully cross-platform, you'll need to work around this limitation using one of the following methods:

  • Use the {{OS}} function to run an OS-specific script.
  • Use something like {{if eq OS "windows"}}powershell {{end}}<my_cmd> to detect windows and run the command in Powershell directly.
  • Use a shell on Windows that supports these commands as builtins, such as Git Bash or WSL.

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/ru-RU/index.html b/ru-RU/index.html index 662755ba..1d36a443 100644 --- a/ru-RU/index.html +++ b/ru-RU/index.html @@ -10,13 +10,13 @@ - +

Task

Task - это инструмент для запуска / сборки, который стремится быть простым и удобным в использовании, чем, например, GNU Make.

Так как Task написан на Go, он представляет собой единственный исполняемый файл и не имеет других зависимостей, что означает, что вам не нужно заниматься сложной настройкой установки просто для использования инструмента сборки.

После установки вам просто нужно описать вашу задачу сборки, используя простую схему YAML в файле с именем Taskfile.yml:

Taskfile.yml
version: '3'

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

И вызвать ее, запустив task hello в вашем терминале.

Приведенный выше пример - это только начало, вы можете посмотреть на руководство по использованию, чтобы посмотреть полную документацию схемы и функций Task.

Особенности

  • Простая установка: просто загрузите единственный исполняемый файл, добавьте его в $PATH и вы готовы! Или вы можете установить с помощью Homebrew, Snapcraft или Scoop, если хотите.
  • Доступен на CI-серверах: просто добавьте эту простую команду для установки в CI-скрипт и готово! Теперь можно использовать Task в качестве части вашего CI-пайплайна.
  • Полностью кроссплатформенный: в то время как большинство инструментов сборки хорошо работают только в Linux или macOS, Task также поддерживает Windows, благодаря интерпретатору командной оболочки для Go.
  • Отлично подходит для кодогенерации: вы можете легко предотвратить запуск задачи, если необходимый набор файлов не изменился с прошлого запуска (основываясь на времени изменения или содержимом).

Золотые спонсоры

- + \ No newline at end of file diff --git a/ru-RU/installation/index.html b/ru-RU/installation/index.html index 24846ab1..b675cbf3 100644 --- a/ru-RU/installation/index.html +++ b/ru-RU/installation/index.html @@ -10,13 +10,13 @@ - +

Установка

Task имеет множество способов установки. Просмотрите доступные методы ниже.

Менеджеры пакетов

Homebrew

Если вы используете macOS или Linux и установили Homebrew, то для установки достаточно выполнить:

brew install go-task/tap/go-task

Данная Formula поддерживается нами.

Недавно Task стал доступен в официальном репозитории Homebrew, поэтому вы можете использовать:

brew install go-task

Snap

Task доступен в Snapcraft, но имейте в виду, что ваш Linux дистрибутив должен иметь классическое ограничение для Snaps, чтобы Task работал правильно:

sudo snap install task --classic

Chocolatey

Если вы используете Windows и у вас установлен Chocolatey, установка Task сводится к запуску:

choco install go-task

Этот метод установки находится под управлением сообщества.

Scoop

Если вы используете Windows и у вас установлен Scoop, установка Task сводится к запуску:

scoop install task

Этот метод установки находится под управлением сообщества. После нового релиза Task может потребоваться некоторое время, пока он станет доступен в Scoop.

AUR

Если вы используете Arch Linux, вы можете установить Task из AUR с помощью вашего любимого менеджера пакетов, такого как yay, pacaur или yaourt:

yay -S go-task-bin

В качестве альтернативы, можно использовать пакет, который устанавливается из исходного кода, а не загружает бинарный файл со страницы релизов:

yay -S go-task

Этот метод установки находится под управлением сообщества.

Fedora

Если вы используете Fedora Linux, вы можете установить Task из официального репозитория Fedora, используя dnf:

sudo dnf install go-task

Этот метод установки находится под управлением сообщества. После нового релиза Task может потребоваться некоторое время, пока он станет доступен в Fedora.

Nix

Если вы используете NixOS или у вас установлен Nix, вы можете установить Task из nixpkgs:

nix-env -iA nixpkgs.go-task

Этот метод установки находится под управлением сообщества. После нового релиза Task может потребоваться некоторое время, пока он станет доступен в nixpkgs.

npm

Для установки Task вы также можете использовать Node и npm, установив этот пакет.

npm install -g @go-task/cli

Winget

Если вы используете Windows и установили менеджер пакетов winget, вы можете установить Task из winget-pkgs.

winget install Task.Task

Установка бинарных файлов

Бинарные

Вы можете установить бинарные файлы со страницы релизов на GitHub и добавить их в ваш $PATH.

Также доступны DEB и RPM пакеты.

Файл task_checksums.txt содержит контрольные суммы SHA-256 для каждого файла.

Скрипт для установки

У нас также есть скрипт для установки, который очень полезен в некоторых случаях, таких как CI. Благодарим GoDownloader за то, что он облегчает генерацию этого скрипта.

По умолчанию он устанавливается в каталог ./bin относительно рабочего каталога:

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

Вы можете переопределить каталог установки с помощью параметра -b. В Linux распространенными вариантами являются ~/.local/bin и ~/bin, чтобы установить для текущего пользователя, или /usr/local/bin, чтобы установить для всех пользователей:

sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin
предупреждение

В macOS и Windows, ~/.local/bin и ~/bin по умолчанию не добавляются в $PATH.

GitHub Actions

Если вы хотите установить Task в GitHub Actions, вы можете попробовать использовать это действие от команды Arduino:

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

Этот метод установки находится под управлением сообщества.

Сборка из исходного кода

Go Modules

Убедитесь, что у вас правильно установлена и настроена поддерживаемая версия Go. Вы можете найти минимальную требуемую версию Go в go.mod файле.

Затем вы можете установить последнюю версию глобально, запустив:

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

Или вы можете установить в другую директорию:

env GOBIN=/bin go install github.com/go-task/task/v3/cmd/task@latest
подсказка

Для окружения CI мы рекомендуем вместо этого использовать скрипт установки, который быстрее и стабильнее, так как он просто загрузит последний выпущенный бинарный файл.

Завершение установки

Загрузите файл автодополнения, соответствующий вашей оболочке.

Все дополнения доступны в репозитории Task.

Bash

Сначала убедитесь, что вы установили bash-completion с помощью вашего менеджера пакетов.

Сделайте файл автодополнения исполняемым:

chmod +x path/to/task.bash

Затем, добавьте это в свой ~/.bash_profile:

source path/to/task.bash

ZSH

Поместите файл _task куда-нибудь в ваш $FPATH:

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

Убедитесь, что в ~/.zshrc присутствует следующее:

autoload -U compinit
compinit -i

Рекомендуется использовать ZSH версии 5.7 или выше.

Fish

Переместите скрипт автодополнения task.fish:

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

PowerShell

Откройте сценарии вашего профиля с помощью:

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

Добавьте строку и сохраните файл:

Invoke-Expression -Command path/to/task.ps1
- + \ No newline at end of file diff --git a/ru-RU/integrations/index.html b/ru-RU/integrations/index.html index bc7c1a9c..2d8e2eca 100644 --- a/ru-RU/integrations/index.html +++ b/ru-RU/integrations/index.html @@ -10,13 +10,13 @@ - +

Integrations

Visual Studio Code Extension

Task has an official extension for Visual Studio Code. The code for this project can be found here. To use this extension, you must have Task v3.23.0+ installed on your system.

This extension provides the following features (and more):

  • View tasks in the sidebar.
  • Run tasks from the sidebar and command palette.
  • Go to definition from the sidebar and command palette.
  • Run last task command.
  • Multi-root workspace support.
  • Initialize a Taskfile in the current workspace.

To get autocompletion and validation for your Taskfile, see the Schema section below.

Task for Visual Studio Code

Schema

This was initially created by @KROSF in this Gist and is now officially maintained in this file and made available at https://taskfile.dev/schema.json. This schema can be used to validate Taskfiles and provide autocompletion in many code editors:

Visual Studio Code

To integrate the schema into VS Code, you need to install the YAML extension by Red Hat. Any Taskfile.yml in your project should automatically be detected and validation/autocompletion should work. If this doesn't work or you want to manually configure it for files with a different name, you can add the following to your settings.json:

// settings.json
{
"yaml.schemas": {
"https://taskfile.dev/schema.json": [
"**/Taskfile.yml",
"./path/to/any/other/taskfile.yml"
]
}
}

You can also configure the schema directly inside of a Taskfile by adding the following comment to the top of the file:

# yaml-language-server: $schema=https://taskfile.dev/schema.json
version: '3'

You can find more information on this in the YAML language server project.

Community Integrations

In addition to our official integrations, there is an amazing community of developers who have created their own integrations for Task:

If you have made something that integrates with Task, please feel free to open a PR to add it to this list.

- + \ No newline at end of file diff --git a/ru-RU/releasing/index.html b/ru-RU/releasing/index.html index eb64f23e..0f4d2c4f 100644 --- a/ru-RU/releasing/index.html +++ b/ru-RU/releasing/index.html @@ -10,13 +10,13 @@ - +

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 main branch (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 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/ru-RU/search/index.html b/ru-RU/search/index.html index c1446811..7a3f4404 100644 --- a/ru-RU/search/index.html +++ b/ru-RU/search/index.html @@ -10,13 +10,13 @@ - + - + \ No newline at end of file diff --git a/ru-RU/styleguide/index.html b/ru-RU/styleguide/index.html index 5a9e069e..fa3487da 100644 --- a/ru-RU/styleguide/index.html +++ b/ru-RU/styleguide/index.html @@ -10,13 +10,13 @@ - +

Стайлгайд

Это официальный стайлгайд Task для Taskfile.yml файлов. Это руководство содержит некоторые базовые инструкции для того, чтобы ваш Taskfile был чистым и понятен другим пользователям.

Этот стайлгайд содержит общие рекомендации по написанию кода, но не обязательно требует их строгого соблюдения. Можете не соглашаться с правилами и использовать другой подход, если вам это нужно или хотите это сделать. Кроме того, не стесняйтесь создавать Issue или PR с улучшениями этого гида.

Используйте Taskfile.yml вместо taskfile.yml

# bad
taskfile.yml


# good
Taskfile.yml

Это особенно важно для пользователей Linux. У Windows и macOS нечувствительные файловые системы, поэтому taskfile.yml в конечном итоге будет работать, даже если официально не поддерживается. В Linux только будет работать Taskfile.yml.

Используйте правильный порядок ключевых слов

  • version:
  • includes:
  • Конфигурационные параметры, такие как output:, silent:, method: и run:
  • vars:
  • env:, dotenv:
  • tasks:

Используйте 2 пробела для отступа

Это наиболее распространенное соглашение для YAML-файлов, и Task следует ему.

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


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

Разделяйте основные секции пробелами

# 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:
# ...

Добавляйте пробелы между задачами

# 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'

Используйте имена переменных в верхнем регистре

# 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}} .

Не заключайте переменные в пробелы при использовании их в шаблонах

# bad
version: '3'

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


# good
version: '3'

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

Большинство людей использует это соглашение и для любых шаблонов в Go.

Разделяйте слова в названии задач дефисом

# bad
version: '3'

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


# good
version: '3'

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

Используйте двоеточие для неймспейсов в названиях задач

# good
version: '3'

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

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

Это также происходит автоматически при использовании включенных Taskfiles.

- + \ No newline at end of file diff --git a/ru-RU/taskfile-versions/index.html b/ru-RU/taskfile-versions/index.html index 9ed421bb..3380a255 100644 --- a/ru-RU/taskfile-versions/index.html +++ b/ru-RU/taskfile-versions/index.html @@ -10,13 +10,13 @@ - +

Версии Taskfile

Синтаксис Taskfile и функции со временем изменяются. Этот документ объясняет, что изменилось в каждой версии и как обновить свой Taskfile.

Что обозначает версия Taskfile

Версия Taskfile соответствует версии Task. Например: изменение на Taskfile версии 2 означает, что Task v2.0.0 должна быть выпущена для ее поддержки.

version: ключ Taskfile принимает semVer строку. Пример: 2, 2.0 или 2.0.0. Если вы решите использовать Task версии 2.0, то у вас не будет доступа к функциям версии 2.1, но если вы решите использовать версию 2, то любые функции версий 2.x.x будут доступны, но не 3.0.0+.

Версия 1

ПРИМЕЧАНИЕ: Taskfiles версии 1 больше не поддерживаются в версии Task >= v3.0.0.

В первой версии Taskfile поле version: не доступно, потому что задачи были в корне документа YAML. Пример:

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

Порядок приоритетов переменных также отличается:

  1. Вызов переменных
  2. Переменные среды
  3. Переменные Task
  4. Переменные Taskvars.yml

Версия 2.0

В версии 2 был добавлен ключ version: . Он позволяет выпускать обновления сохраняя обратную совместимость. Пример использования:

version: '2'

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

Версия 2 позволяет создавать глобальные переменные непосредственно в Taskfile, если вы не хотите создавать Taskvars.yml:

version: '2'

vars:
GREETING: Hello, World!

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

Порядок приоритетов переменных также отличается:

  1. Переменные Task
  2. Call variables
  3. Переменные Taskfile
  4. Переменные Taskvars.yml
  5. Переменные окружения

Добавлена новая глобальная опция для настройки количества расширений переменных (по умолчанию 2):

version: '2'

expansions: 3

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

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

Версия 2.1

В версии 2.1 появилась глобальная опция output, которая позволяет иметь больше контроля над тем, как вывод команд печатается на консоли (см. документацию):

version: '2'

output: prefixed

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

Начиная с этой версии можно игнорировать ошибки команды или задачи (смотрите документацию здесь):

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

Версия 2.2

В Версии 2.2 появилась новая глобальная опция includes, которая позволяет импортировать другие Taskfile'ы:

version: '2'

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

Версия 2.6

Версия 2.6 поставляется с preconditions опцией в задачах.

version: '2'

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

Пожалуйста, проверьте документацию

Версия 3

Основные изменения, сделанные в v3:

  • Output задачи теперь цветной
  • Добавлена поддержка .env файлов
  • Добавлен параметр label:. Появилась возможность переопределить имя задачи в логах
  • Глобальный параметр method: был добавлен для установки метода по умолчанию, а задача по умолчанию изменена на checksum
  • Добавлены 2 магические переменные, используемые в функции status: - CHECKSUM и TIMESTAMP, которые содержат, контрольную сумму md5 и наибольшую отметку времени изменения файлов, перечисленных в sources:
  • Кроме того, переменная TASK всегда доступна по имени текущей задачи
  • Переменные CLI всегда считаются глобальными переменными
  • Добавлена опция dir: в includes для того, чтобы выбрать, в каком каталоге Taskfile будет запущен:
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!"
  • Был произведён большой рефакторинг обработки переменных. Теперь всё стало более прозрачно. Параметр expansions: был удален. Это порядок, в котором Task будет обрабатывать переменные, каждый уровень может видеть переменные, объявленные на предыдущем и переопределять их.
    • Переменные окружения
    • Глобальные + CLI переменные
    • Call variables
    • Переменные Task
- + \ No newline at end of file diff --git a/ru-RU/translate/index.html b/ru-RU/translate/index.html index f47d57d5..8f693d49 100644 --- a/ru-RU/translate/index.html +++ b/ru-RU/translate/index.html @@ -10,13 +10,13 @@ - +

Перевод

Хотите помочь нам перевести эту документацию? В этом документе мы объясним каким образом.

НЕ редактируйте переведенные файлы markdown прямо в репозитории GitHub! Мы используем Crowdin, чтобы позволить участникам работать над переводами. Репозиторий периодически обновляется с прогрессом из Crowdin.

Если вы хотите получить доступ к проекту Crowdin, чтобы предложить перевод, пожалуйста, попросите доступ к каналу #translations на нашем Discord сервере. Если данный язык еще не отображается в Crowdin, просто спросите и мы сможем его настроить.

- + \ No newline at end of file diff --git a/ru-RU/usage/index.html b/ru-RU/usage/index.html index d8a71ba0..549930b0 100644 --- a/ru-RU/usage/index.html +++ b/ru-RU/usage/index.html @@ -10,13 +10,13 @@ - +
-

Использование

Начало работы

Создайте файл с именем Taskfile.yml в корне вашего проекта. Атрибут cmds должен содержать команды задачи. Пример ниже позволяет скомпилировать приложение Go и использовать esbuild чтобы собрать и минимизировать несколько CSS файлов в один.

version: '3'

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

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

Запуск задач настолько прост, что достаточно выполнить команду:

task assets build

Task использует mvdan.cc/sh - нативный интерпретатор sh на Go. Таким образом, вы можете писать команды sh / bash, и они будут работать даже в Windows, где обычно не доступны sh или bash. Просто помните, что любой исполняемый файл, который вызывается, должен быть доступен ОС или находиться в переменной PATH.

Если вы опустите имя задачи, то будет использоваться имя "default".

Поддерживаемые названия файлов

Task будет искать следующие файлы, в порядке приоритета:

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

Идея создания вариантов .dist заключается в том, чтобы позволить проектам иметь одну фиксированную версию (.dist), при этом позволяя отдельным пользователям переопределить Taskfile, добавив дополнительный Taskfile.yml (который будет находится в .gitignore).

Запуск Taskfile из поддиректории

Если Taskfile не найден в текущем рабочем каталоге, он будет искать его вверх по дереву файлов, пока не найдет его (похоже на то, как работает git). При запуске Task из подкаталога, он будет работать так, как будто вы запустили его из каталога, содержащего Taskfile.

Вы можете использовать эту функцию вместе со специальной переменной {{.USER_WORKING_DIR}}, чтобы создавать переиспользуемые задачи. Например, если у вас есть монорепозиторий с каталогами для каждого микросервиса, вы можете cd в директорию микросервиса и запустить команду задачи, без создания нескольких задач или Taskfile с идентичным содержимым. Например:

version: '3'

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

В этом примере мы можем выполнить cd <service> и task up, и при условии, что каталог <service> содержит файл docker-compose.yml, Docker composition будет запущен.

Запуск глобального Taskfile

Если вы вызовите Task с помощью флага --global (псевдоним -g), будет искать ваш домашний каталог вместо рабочего каталога. Проще говоря, Task будет искать в $HOME/Taskfile.yml или $HOME/Taskfile.yaml.

Это полезно, чтобы иметь автоматизацию, которую можно запустить из любого места вашей системы!

к сведению

Когда вы запускаете ваш глобальный Taskfile с помощью -g, task будут выполняться по умолчанию в директории $HOME, а не в вашей рабочей директории!

Как упоминалось в предыдущем разделе, специальная переменная {{.USER_WORKING_DIR}} может быть очень полезной для запуска команд в директории, из которой вы вызываете task -g.

version: '3'

tasks:
from-home:
cmds:
- pwd

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

Переменные среды

Task

Вы можете использовать env для создания своих переменных среды для конкретной task:

version: '3'

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

Также, вы можете создавать глобальные переменные окружения, которые будут доступны всем task:

version: '3'

env:
GREETING: Hey, there!

tasks:
greet:
cmds:
- echo $GREETING
к сведению

env поддерживает дополнение и извлечение вывода из команды shell или переменной, вы можете посмотреть в разделе Переменные.

.env файлы

Вы также можете попросить Task включать файлы, подобные .env используя настройку dotenv::

.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 файлы также могут быть указаны на уровне task:

version: '3'

env:
ENV: testing

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

Переменные окружения, определенные на уровне task, заменят переменные объявленные в dotenv файлах:

version: '3'

env:
ENV: testing

tasks:
greet:
dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']
env:
KEYNAME: DIFFERENT_VALUE
cmds:
- echo "Using $KEYNAME and endpoint $ENDPOINT"
к сведению

Обратите внимание, в данный момент вы не можете использовать ключ dotenv во вложенных Taskfile.

Включение других Taskfile

Если вы хотите использовать task в других проектах (Taskfile), вы можете использовать механизм импорта для включения других Taskfile используя ключевое слово includes:

version: '3'

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

Task, описанные в указанных Taskfile, будут доступны с указанным пространством имен. Таким образом, вы можете запустить serve task из файла documentation/Taskfile.yml с помощью команды task docs:serve, или запустить build task из файла DockerTasks.yml с помощью команды task docker:build.

Относительные пути разрешаются относительно каталога, содержащего включающий 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
к сведению

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]
к сведению

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, function-like tasks that have no useful purpose on the command line.

version: '3'

tasks:
build-image-1:
cmds:
- task: build-image
vars:
DOCKER_IMAGE: image-1

build-image:
internal: true
cmds:
- docker build -t {{.DOCKER_IMAGE}} .

Task directory

By default, tasks will be executed in the directory where the Taskfile is located. But you can easily make the task run in another folder, informing 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 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.

подсказка

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'

Вызов другой task

Когда task имеет много зависимостей, они выполняются параллельно. Это частно приводит к более быстрому построению пайплайна. Однако, в некоторых ситуациях вам может понадобиться вызвать другие task последовательно. В этом случае используйте следующий синтаксис:

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"

Переопределение переменных в вызываемой task делается через указание атрибута vars:

version: '3'

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

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

Указанный выше синтаксис также поддерживается в deps.

подсказка

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. You can even combine the two. See the documentation for status for an example.

к сведению

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 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'
к сведению

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.

подсказка

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

к сведению

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 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
подсказка

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 well:

version: '3'

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

cleanup: rm -rf tmpdir/
к сведению

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 \ 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 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 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 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 [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
подсказка

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 set 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
к сведению

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.

- +

Использование

Начало работы

Создайте файл с именем Taskfile.yml в корне вашего проекта. Атрибут cmds должен содержать команды задачи. Пример ниже позволяет скомпилировать приложение Go и использовать esbuild чтобы собрать и минимизировать несколько CSS файлов в один.

version: '3'

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

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

Запуск задач настолько прост, что достаточно выполнить команду:

task assets build

Task использует mvdan.cc/sh - нативный интерпретатор sh на Go. Таким образом, вы можете писать команды sh / bash, и они будут работать даже в Windows, где обычно не доступны sh или bash. Просто помните, что любой исполняемый файл, который вызывается, должен быть доступен ОС или находиться в переменной PATH.

Если вы опустите имя задачи, то будет использоваться имя "default".

Поддерживаемые названия файлов

Task будет искать следующие файлы, в порядке приоритета:

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

Идея создания вариантов .dist заключается в том, чтобы позволить проектам иметь одну фиксированную версию (.dist), при этом позволяя отдельным пользователям переопределить Taskfile, добавив дополнительный Taskfile.yml (который будет находится в .gitignore).

Запуск Taskfile из поддиректории

Если Taskfile не найден в текущем рабочем каталоге, он будет искать его вверх по дереву файлов, пока не найдет его (похоже на то, как работает git). При запуске Task из подкаталога, он будет работать так, как будто вы запустили его из каталога, содержащего Taskfile.

Вы можете использовать эту функцию вместе со специальной переменной {{.USER_WORKING_DIR}}, чтобы создавать переиспользуемые задачи. Например, если у вас есть монорепозиторий с каталогами для каждого микросервиса, вы можете cd в директорию микросервиса и запустить команду задачи, без создания нескольких задач или Taskfile с идентичным содержимым. Например:

version: '3'

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

В этом примере мы можем выполнить cd <service> и task up, и при условии, что каталог <service> содержит файл docker-compose.yml, Docker composition будет запущен.

Запуск глобального Taskfile

Если вы вызовите Task с помощью флага --global (псевдоним -g), будет искать ваш домашний каталог вместо рабочего каталога. Проще говоря, Task будет искать в $HOME/Taskfile.yml или $HOME/Taskfile.yaml.

Это полезно, чтобы иметь автоматизацию, которую можно запустить из любого места вашей системы!

к сведению

Когда вы запускаете ваш глобальный Taskfile с помощью -g, task будут выполняться по умолчанию в директории $HOME, а не в вашей рабочей директории!

Как упоминалось в предыдущем разделе, специальная переменная {{.USER_WORKING_DIR}} может быть очень полезной для запуска команд в директории, из которой вы вызываете task -g.

version: '3'

tasks:
from-home:
cmds:
- pwd

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

Переменные среды

Task

Вы можете использовать env для создания своих переменных среды для конкретной task:

version: '3'

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

Также, вы можете создавать глобальные переменные окружения, которые будут доступны всем task:

version: '3'

env:
GREETING: Hey, there!

tasks:
greet:
cmds:
- echo $GREETING
к сведению

env поддерживает дополнение и извлечение вывода из команды shell или переменной, вы можете посмотреть в разделе Переменные.

.env файлы

Вы также можете попросить Task включать файлы, подобные .env используя настройку dotenv::

.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 файлы также могут быть указаны на уровне task:

version: '3'

env:
ENV: testing

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

Переменные окружения, определенные на уровне task, заменят переменные объявленные в dotenv файлах:

version: '3'

env:
ENV: testing

tasks:
greet:
dotenv: ['.env', '{{.ENV}}/.env.', '{{.HOME}}/.env']
env:
KEYNAME: DIFFERENT_VALUE
cmds:
- echo "Using $KEYNAME and endpoint $ENDPOINT"
к сведению

Обратите внимание, в данный момент вы не можете использовать ключ dotenv во вложенных Taskfile.

Включение других Taskfile

Если вы хотите использовать task в других проектах (Taskfile), вы можете использовать механизм импорта для включения других Taskfile используя ключевое слово includes:

version: '3'

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

Task, описанные в указанных Taskfile, будут доступны с указанным пространством имен. Таким образом, вы можете запустить serve task из файла documentation/Taskfile.yml с помощью команды task docs:serve, или запустить build task из файла DockerTasks.yml с помощью команды task docker:build.

Относительные пути разрешаются относительно каталога, содержащего включающий 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
к сведению

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]
к сведению

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, function-like tasks that have no useful purpose on the command line.

version: '3'

tasks:
build-image-1:
cmds:
- task: build-image
vars:
DOCKER_IMAGE: image-1

build-image:
internal: true
cmds:
- docker build -t {{.DOCKER_IMAGE}} .

Task directory

By default, tasks will be executed in the directory where the Taskfile is located. But you can easily make the task run in another folder, informing 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 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.

подсказка

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' }
silent: true
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'

Вызов другой task

Когда task имеет много зависимостей, они выполняются параллельно. Это частно приводит к более быстрому построению пайплайна. Однако, в некоторых ситуациях вам может понадобиться вызвать другие task последовательно. В этом случае используйте следующий синтаксис:

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"

Using the vars and silent attributes you can choose to pass variables and toggle silent mode on a call-by-call basis:

version: '3'

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

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

Указанный выше синтаксис также поддерживается в deps.

подсказка

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. You can even combine the two. See the documentation for status for an example.

к сведению

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 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'
к сведению

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.

подсказка

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

к сведению

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 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
подсказка

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 well:

version: '3'

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

cleanup: rm -rf tmpdir/
к сведению

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 \ 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 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 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 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 [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
подсказка

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 set 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
к сведению

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.

+ \ No newline at end of file diff --git a/zh-Hans/404.html b/zh-Hans/404.html index 31a0c694..3dcb8370 100644 --- a/zh-Hans/404.html +++ b/zh-Hans/404.html @@ -10,13 +10,13 @@ - + - + \ No newline at end of file diff --git a/zh-Hans/api/index.html b/zh-Hans/api/index.html index a41be84c..1553d778 100644 --- a/zh-Hans/api/index.html +++ b/zh-Hans/api/index.html @@ -10,13 +10,13 @@ - +
-

API 参考

命令行

该命令的语法如下:

task [--flags] [tasks...] [-- CLI_ARGS...]
提示

如果 -- 给出,所有剩余参数将被分配给一个特殊的 CLI_ARGS 变量

缩写标志类型默认描述
-c--colorbooltrue彩色输出。 默认开启。 设置为 false 或使用 NO_COLOR=1 禁用。
-C--concurrencyint0限制并发运行的任务数。 零意味着无限。
-d--dirstring工作目录设置执行目录。
-n--dryboolfalse按运行顺序编译和打印任务,而不执行它们。
-x--exit-codeboolfalse传递任务命令的退出代码。
-f--forceboolfalse即使任务是最新的也强制执行。
-g--globalboolfalse$HOME/Taskfile.{yml,yaml} 运行全局任务文件。
-h--helpboolfalse显示任务使用情况。
-i--initboolfalse在当前目录创建一个新的 Taskfile.yml。
-I--intervalstring5s使用 --watch 设置不同的观察间隔,默认为 5 秒。 这个字符串应该是一个有效的 Go Duration
-l--listboolfalse列出当前文件的全部任务及对应描述。
-a--list-allboolfalse列出无论有没有描述的所有任务。
--sortstringdefault在列出时更改 task 的顺序。
--jsonboolfalse查看 JSON 输出
-o--outputstring在 Taskfile 中设置默认值或 intervealed设置输出样式:[interleaved/group/prefixed]
--output-group-beginstring在任务组输出前打印的消息模板。
--output-group-endstring在任务组输出后打印的消息模板。
--output-group-error-onlyboolfalse在退出码为 0 时忽略命令输出。
-p--parallelboolfalse并行执行命令行上提供的任务。
-s--silentboolfalse禁用回显。
--statusboolfalse如果任何给定任务不是最新的,则以非 0 退出码退出。
--summaryboolfalse显示有关任务的摘要。
-t--taskfilestringTaskfile.ymlTaskfile.yaml
-v--verboseboolfalse启用详细模式。
--versionboolfalse显示 Task 版本。
-w--watchboolfalse启用给定任务的观察器。

退出码

Task 有时会以特定的退出代码退出。 这些代码分为三组,范围如下:

  • 一般错误 (0-99)
  • Taskfile 错误 (100-199)
  • Task 错误 (200-299)

可以在下面找到退出代码及其描述的完整列表:

代码描述
0成功
1出现未知错误
100找不到 Taskfile
101尝试初始化一个 Taskfile 时已经存在
102Taskfile 无效或无法解析
200找不到指定的 task
201在 task 中执行命令时出错
202用户试图调用内部 task
203有多个具有相同名称或别名的 task
204一个 task 被调用了太多次

这些代码也可以在存储库的 errors/errors.go 中找到。

信息

当使用 -x/--exit-code 标志运行 Task 时,任何失败命令的退出代码都将传递给用户。

JSON 输出

--json 标志与 --list--list-all 标志结合使用时,将输出具有以下结构的 JSON 对象:

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

特殊变量

模板系统上有一些可用的特殊变量:

变量描述
CLI_ARGS当通过 CLI 调用 Task 时,传递包含在 -- 之后的所有额外参数。
TASK当前任务的名称。
ROOT_DIR根 Taskfile 的绝对路径。
TASKFILE_DIR包含 Taskfile 的绝对路径
USER_WORKING_DIR调用 task 的目录的绝对路径。
CHECKSUMsources 中列出的文件的 checksum。 仅在 status 参数中可用,并且如果方法设置为 checksum
TIMESTAMPsources 中列出的文件的最大时间戳的日期对象。 仅在 status 参数中可用,并且如果方法设置为 timestamp
TASK_VERSIONTask 的当前版本。

环境变量

可以覆盖某些环境变量以调整 Task 行为。

环境变量默认描述
TASK_TEMP_DIR.task临时目录的位置。 可以相对于项目比如 tmp/task 或绝对如 /tmp/.task~/.task
TASK_COLOR_RESET0用于白色的颜色。
TASK_COLOR_BLUE34用于蓝色的颜色。
TASK_COLOR_GREEN32用于绿色的颜色。
TASK_COLOR_CYAN36用于青色的颜色。
TASK_COLOR_YELLOW33用于黄色的颜色。
TASK_COLOR_MAGENTA35用于洋红色的颜色。
TASK_COLOR_RED31用于红色的颜色。
FORCE_COLOR强制使用颜色输出。

Taskfile Schema

属性类型默认描述
versionstringTaskfile 的版本。 当前版本是 3
outputstringinterleaved输出模式。 可用选项: interleavedgroupprefixed
methodstringchecksumTaskfile 中的默认方法。 可以在任务基础上覆盖。 可用选项:checksumtimestampnone
includesmap[string]Include要包含的其他 Taskfile。
varsmap[string]Variable一组全局变量。
envmap[string]Variable一组全局环境变量。
tasksmap[string]Task一组任务定义。
silentboolfalse此任务文件的默认“silent”选项。 如果为 false,则可以在任务的基础上用 true 覆盖。
dotenv[]string要解析的 .env 文件路径列表。
runstringalwaysTaskfile 中默认的 'run' 选项。 可用选项: alwaysoncewhen_changed
intervalstring5s设置 --watch 模式下的观察时间,默认 5 秒。 这个字符串应该是一个有效的 Go Duration
set[]string内置 set 指定选项。
shopt[]string内置 shopt 指定选项。

Include

属性类型默认描述
taskfilestring要包含的 Taskfile 或目录的路径。 如果是目录,Task 将在该目录中查找名为 Taskfile.ymlTaskfile.yaml 的文件。 如果是相对路径,则相对于包含 Taskfile 的目录进行解析。
dirstringTaskfile 文件父目录运行时包含的任务的工作目录。
optionalboolfalse设置为 true 时, 文件不存在也不会报错
internalboolfalse停止在命令行上调用包含的任务文件中的任何任务。 当与 --list 一起使用时,这些命令也将从输出中省略。
aliases[]string包含的 Taskfile 的命名空间的替代名称。
varsmap[string]Variable一组应用于包含的 Taskfile 的变量。
信息

像下面这样只赋值一个字符串,和把这个值设置到 taskfile 属性是一样的。

includes:
foo: ./path

Variable

属性类型默认描述
itselfstring将设置为变量的静态值。
shstring一个 shell 命令。 输出 (STDOUT) 将分配给变量。
信息

静态和动态变量有不同的语法,如下所示:

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

Task

属性类型默认描述
cmds[]Command要执行的 shell 命令列表。
deps[]Dependency此任务的依赖项列表。 此处定义的任务将在此任务之前并行运行。
labelstring运行任务时覆盖输出中的任务名称。 支持变量。
descstringTask 的简短描述。 这在调用 task --list 时显示。
summarystring任务的较长描述。 这在调用 task --summary [task] 时显示。
aliases[]string可以调用任务的别名列表。
sources[]string运行此任务之前要检查的源列表。 与 checksumtimestamp 相关。 可以是文件路径或星号。
generates[]string此任务要生成的文件列表。 与 timestamp 方法相关。 可以是文件路径或星号。
status[]string用于检查此 task 是否应运行的命令列表。 否则跳过该任务。 这个方法会覆盖 methodsourcesgenerates
preconditions[]Precondition用于检查此任务是否应运行的命令列表。 如果不满足条件,任务将出错。
dirstring此 task 应运行的目录。 默认为当前工作目录。
varsmap[string]Variable可在 task 中使用的一组变量。
envmap[string]Variable一组可用于 shell 命令的环境变量。
dotenv[]string要解析的 .env 文件路径列表。
silentboolfalse从输出中隐藏任务名称和命令。 命令的输出仍将重定向到 STDOUTSTDERR。 当与 --list 标志结合使用时,任务描述将被隐藏。
interactiveboolfalse告诉任务该命令是交互式的。
internalboolfalse停止在命令行上调用任务。 当与 --list 一起使用时,它也会从输出中省略。
methodstringchecksum定义用于检查任务是最新的方法。 timestamp 将比较源的时间戳并生成文件。 checksum 将检查 checksum(您可能想忽略 .gitignore 文件中的 .task 文件夹)。 none 跳过任何验证并始终运行任务。
prefixstring定义一个字符串作为并行运行 task 输出的前缀。 仅在输出模式是 prefixed 时使用。
ignore_errorboolfalse如果执行命令时发生错误,则继续执行。
runstringTaskfile 中全局声明的值或 always指定如果多次调用该任务是否应再次运行。 可用选项:alwaysoncewhen_changed
platforms[]string所有平台指定应在哪些平台上运行任务。 允许使用 有效的 GOOS 和 GOARCH 值。 否则将跳过任务。
set[]string内置 set 指定选项。
shopt[]string内置 shopt 指定选项。
信息

这些替代语法可用。 他们会将给定值设置为 cmds,其他所有内容都将设置为其默认值:

tasks:
foo: echo "foo"

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

baz:
cmd: echo "baz"

Command

属性类型默认描述
cmdstring要执行的 shell 命令
silentboolfalse跳过此命令的一些输出。 请注意,命令的 STDOUT 和 STDERR 仍将被重定向。
taskstring执行另一个 task,而不执行命令。 不能与 cmd 同时设置。
varsmap[string]Variable要传递给引用任务的可选附加变量。 仅在设置 task 而不是 cmd 时相关。
ignore_errorboolfalse执行命令的时候忽略错误,继续执行
deferstringcmd 的替代方法,但安排命令在此任务结束时执行,而不是立即执行。 不能与 cmd 一同使用。
platforms[]string所有平台指定应在哪些平台上运行该命令。 允许使用 有效的 GOOS 和 GOARCH 值。 否则将跳过命令。
set[]string内置 set 指定选项。
shopt[]string内置 shopt 指定选项。
信息

如果以字符串形式给出,该值将分配给 cmd

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

Dependency

属性类型默认描述
taskstring要作为依赖项执行的任务。
varsmap[string]Variable要传递给此任务的可选附加变量。
提示

如果你不想设置额外的变量,将依赖关系声明为一个字符串列表就足够了(它们将被分配给 task)。

tasks:
foo:
deps: [foo, bar]

Precondition

属性类型默认描述
shstring要执行的命令。 如果返回非零退出码,任务将在不执行其命令的情况下出错。
msgstring如果不满足先决条件,则打印可选消息。
提示

如果你不想设置不同的消息,你可以像这样声明一个前提条件,值将被分配给 sh

tasks:
foo:
precondition: test -f Taskfile.yml
- +

API 参考

命令行

该命令的语法如下:

task [--flags] [tasks...] [-- CLI_ARGS...]
提示

如果 -- 给出,所有剩余参数将被分配给一个特殊的 CLI_ARGS 变量

缩写标志类型默认描述
-c--colorbooltrue彩色输出。 默认开启。 设置为 false 或使用 NO_COLOR=1 禁用。
-C--concurrencyint0限制并发运行的 task 数。 零意味着无限。
-d--dirstring工作目录设置执行目录。
-n--dryboolfalse按运行顺序编译和打印 task,而不执行它们。
-x--exit-codeboolfalse传递 task 命令的退出代码。
-f--forceboolfalse即使 task 是最新的也强制执行。
-g--globalboolfalse$HOME/Taskfile.{yml,yaml} 运行全局 Taskfile。
-h--helpboolfalse显示 Task 使用情况。
-i--initboolfalse在当前目录创建一个新的 Taskfile.yml。
-I--intervalstring5s使用 --watch 设置不同的观察间隔,默认为 5 秒。 这个字符串应该是一个有效的 Go Duration
-l--listboolfalse列出当前文件的全部 task 及对应描述。
-a--list-allboolfalse列出无论有没有描述的所有 task。
--sortstringdefault在列出时更改 task 的顺序。
--jsonboolfalse查看 JSON 输出
-o--outputstring在 Taskfile 中设置默认值或 intervealed设置输出样式:[interleaved/group/prefixed]
--output-group-beginstring在任务组输出前打印的消息模板。
--output-group-endstring在任务组输出后打印的消息模板。
--output-group-error-onlyboolfalse在退出码为 0 时忽略命令输出。
-p--parallelboolfalse并行执行命令行上提供的 task。
-s--silentboolfalse禁用回显。
--statusboolfalse如果任何给定 task 不是最新的,则以非 0 退出码退出。
--summaryboolfalse显示有关 task 的摘要。
-t--taskfilestringTaskfile.ymlTaskfile.yaml
-v--verboseboolfalse启用详细模式。
--versionboolfalse显示 Task 版本。
-w--watchboolfalse启用给定 task 的观察器。

退出码

Task 有时会以特定的退出代码退出。 这些代码分为三组,范围如下:

  • 一般错误 (0-99)
  • Taskfile 错误 (100-199)
  • Task 错误 (200-299)

可以在下面找到退出代码及其描述的完整列表:

代码描述
0成功
1出现未知错误
100找不到 Taskfile
101尝试初始化一个 Taskfile 时已经存在
102Taskfile 无效或无法解析
200找不到指定的 task
201在 task 中执行命令时出错
202用户试图调用内部 task
203有多个具有相同名称或别名的 task
204一个 task 被调用了太多次

这些代码也可以在存储库的 errors/errors.go 中找到。

信息

当使用 -x/--exit-code 标志运行 Task 时,任何失败命令的退出代码都将传递给用户。

JSON 输出

--json 标志与 --list--list-all 标志结合使用时,将输出具有以下结构的 JSON 对象:

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

特殊变量

模板系统上有一些可用的特殊变量:

变量描述
CLI_ARGS当通过 CLI 调用 Task 时,传递包含在 -- 之后的所有额外参数。
TASK当前 task 的名称。
ROOT_DIR根 Taskfile 的绝对路径。
TASKFILE_DIR包含 Taskfile 的绝对路径
USER_WORKING_DIR调用 task 的目录的绝对路径。
CHECKSUMsources 中列出的文件的 checksum。 仅在 status 参数中可用,并且如果 method 设置为 checksum
TIMESTAMPsources 中列出的文件的最大时间戳的日期对象。 仅在 status 参数中可用,并且如果 method 设置为 timestamp
TASK_VERSIONTask 的当前版本。

环境变量

可以覆盖某些环境变量以调整 Task 行为。

环境变量默认描述
TASK_TEMP_DIR.task临时目录的位置。 可以相对于项目比如 tmp/task 或绝对如 /tmp/.task~/.task
TASK_COLOR_RESET0用于白色的颜色。
TASK_COLOR_BLUE34用于蓝色的颜色。
TASK_COLOR_GREEN32用于绿色的颜色。
TASK_COLOR_CYAN36用于青色的颜色。
TASK_COLOR_YELLOW33用于黄色的颜色。
TASK_COLOR_MAGENTA35用于洋红色的颜色。
TASK_COLOR_RED31用于红色的颜色。
FORCE_COLOR强制使用颜色输出。

Taskfile Schema

属性类型默认描述
versionstringTaskfile 的版本。 当前版本是 3
outputstringinterleaved输出模式。 可用选项: interleavedgroupprefixed
methodstringchecksumTaskfile 中的默认方法。 可以在 task 基础上覆盖。 可用选项:checksumtimestampnone
includesmap[string]Include要包含的其他 Taskfile。
varsmap[string]Variable一组全局变量。
envmap[string]Variable一组全局环境变量。
tasksmap[string]Task一组 task 定义。
silentboolfalse此 Taskfile 的默认“silent”选项。 如果为 false,则可以在 task 的基础上用 true 覆盖。
dotenv[]string要解析的 .env 文件路径列表。
runstringalwaysTaskfile 中默认的 'run' 选项。 可用选项: alwaysoncewhen_changed
intervalstring5s设置 --watch 模式下的观察时间,默认 5 秒。 这个字符串应该是一个有效的 Go Duration
set[]string内置 set 指定选项。
shopt[]string内置 shopt 指定选项。

Include

属性类型默认描述
taskfilestring要包含的 Taskfile 或目录的路径。 如果是目录,Task 将在该目录中查找名为 Taskfile.ymlTaskfile.yaml 的文件。 如果是相对路径,则相对于包含 Taskfile 的目录进行解析。
dirstringTaskfile 文件父目录运行时包含的 task 的工作目录。
optionalboolfalse设置为 true 时, 文件不存在也不会报错
internalboolfalse停止在命令行上调用包含的 Taskfile 中的任何 task。 当与 --list 一起使用时,这些命令也将从输出中省略。
aliases[]string包含的 Taskfile 的命名空间的替代名称。
varsmap[string]Variable一组应用于包含的 Taskfile 的变量。
信息

像下面这样只赋值一个字符串,和把这个值设置到 taskfile 属性是一样的。

includes:
foo: ./path

Variable

属性类型默认描述
itselfstring将设置为变量的静态值。
shstring一个 shell 命令。 输出 (STDOUT) 将分配给变量。
信息

静态和动态变量有不同的语法,如下所示:

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

Task

属性类型默认描述
cmds[]Command要执行的 shell 命令列表。
deps[]Dependency此 task 的依赖项列表。 此处定义的 task 将在此 task 之前并行运行。
labelstring运行 task 时覆盖输出中的 task 名称。 支持变量。
descstringtask 的简短描述。 这在调用 task --list 时显示。
summarystringtask 的较长描述。 这在调用 task --summary [task] 时显示。
aliases[]string可以调用 task 的别名列表。
sources[]string运行此 task 之前要检查的源列表。 与 checksumtimestamp 方法相关。 可以是文件路径或星号。
generates[]string此 task 要生成的文件列表。 与 timestamp 方法相关。 可以是文件路径或星号。
status[]string用于检查此 task 是否应运行的命令列表。 否则跳过该 task。 这个方法会覆盖 methodsourcesgenerates
preconditions[]Precondition用于检查此 task 是否应运行的命令列表。 如果不满足条件,task 将出错。
dirstring此 task 应运行的目录。 默认为当前工作目录。
varsmap[string]Variable可在 task 中使用的一组变量。
envmap[string]Variable一组可用于 shell 命令的环境变量。
dotenv[]string要解析的 .env 文件路径列表。
silentboolfalse从输出中隐藏 task 名称和命令。 命令的输出仍将重定向到 STDOUTSTDERR。 当与 --list 标志结合使用时,task 描述将被隐藏。
interactiveboolfalse告诉 task 该命令是交互式的。
internalboolfalse停止在命令行上调用 task。 当与 --list 一起使用时,它也会从输出中省略。
methodstringchecksum定义用于检查 task 是最新的方法。 timestamp 将比较 sources 的时间戳并生成文件。 checksum 将检查 checksum(您可能想忽略 .gitignore 文件中的 .task 文件夹)。 none 跳过任何验证并始终运行 task。
prefixstring定义一个字符串作为并行运行 task 输出的前缀。 仅在输出模式是 prefixed 时使用。
ignore_errorboolfalse如果执行命令时发生错误,则继续执行。
runstringTaskfile 中全局声明的值或 always指定如果多次调用该 task 是否应再次运行。 可用选项:alwaysoncewhen_changed
platforms[]string所有平台指定应在哪些平台上运行 task。 允许使用 有效的 GOOS 和 GOARCH 值。 否则将跳过 task。
set[]string内置 set 指定选项。
shopt[]string内置 shopt 指定选项。
信息

这些替代语法可用。 他们会将给定值设置为 cmds,其他所有内容都将设置为其默认值:

tasks:
foo: echo "foo"

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

baz:
cmd: echo "baz"

Command

属性类型默认描述
cmdstring要执行的 shell 命令
silentboolfalse跳过此命令的一些输出。 请注意,命令的 STDOUT 和 STDERR 仍将被重定向。
taskstring执行另一个 task,而不执行命令。 不能与 cmd 同时设置。
varsmap[string]Variable要传递给引用 task 的可选附加变量。 仅在设置 task 而不是 cmd 时相关。
ignore_errorboolfalse执行命令的时候忽略错误,继续执行
deferstringcmd 的替代方法,但安排命令在此 task 结束时执行,而不是立即执行。 不能与 cmd 一同使用。
platforms[]string所有平台指定应在哪些平台上运行该命令。 允许使用 有效的 GOOS 和 GOARCH 值。 否则将跳过命令。
set[]string内置 set 指定选项。
shopt[]string内置 shopt 指定选项。
信息

如果以字符串形式给出,该值将分配给 cmd

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

Dependency

属性类型默认描述
taskstring要作为依赖项执行的 task。
varsmap[string]Variable要传递给此 task 的可选附加变量。
silentboolfalse从输出中隐藏 task 名称和命令。 命令的输出仍将重定向到 STDOUTSTDERR
提示

如果你不想设置额外的变量,将依赖关系声明为一个字符串列表就足够了(它们将被分配给 task)。

tasks:
foo:
deps: [foo, bar]

Precondition

属性类型默认描述
shstring要执行的命令。 如果返回非零退出码, task 将在不执行其命令的情况下出错。
msgstring如果不满足先决条件,则打印可选消息。
提示

如果你不想设置不同的消息,你可以像这样声明一个前提条件,值将被分配给 sh

tasks:
foo:
precondition: test -f Taskfile.yml
+ \ No newline at end of file diff --git a/zh-Hans/assets/js/01713e21.8536f7d0.js b/zh-Hans/assets/js/01713e21.8536f7d0.js deleted file mode 100644 index ab69b98f..00000000 --- a/zh-Hans/assets/js/01713e21.8536f7d0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[701],{3905:function(e,n,a){a.d(n,{Zo:function(){return o},kt:function(){return c}});var t=a(7294);function l(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function s(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function i(e){for(var n=1;n=0||(l[a]=e[a]);return l}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(l[a]=e[a])}return l}var p=t.createContext({}),k=function(e){var n=t.useContext(p),a=n;return e&&(a="function"==typeof e?e(n):i(i({},n),e)),a},o=function(e){var n=k(e.components);return t.createElement(p.Provider,{value:n},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var a=e.components,l=e.mdxType,s=e.originalType,p=e.parentName,o=r(e,["components","mdxType","originalType","parentName"]),m=k(a),u=l,c=m["".concat(p,".").concat(u)]||m[u]||d[u]||s;return a?t.createElement(c,i(i({ref:n},o),{},{components:a})):t.createElement(c,i({ref:n},o))}));function c(e,n){var a=arguments,l=n&&n.mdxType;if("string"==typeof e||l){var s=a.length,i=new Array(s);i[0]=u;var r={};for(var p in n)hasOwnProperty.call(n,p)&&(r[p]=n[p]);r.originalType=e,r[m]="string"==typeof e?e:l,i[1]=r;for(var k=2;kdefer \u505a task \u6e05\u7406",id:"\u4f7f\u7528-defer-\u505a-task-\u6e05\u7406",level:2},{value:"Go \u7684\u6a21\u677f\u5f15\u64ce",id:"go-\u7684\u6a21\u677f\u5f15\u64ce",level:2},{value:"\u5e2e\u52a9",id:"\u5e2e\u52a9",level:2},{value:"\u663e\u793a\u4efb\u52a1\u6458\u8981",id:"\u663e\u793a\u4efb\u52a1\u6458\u8981",level:2},{value:"Task \u522b\u540d",id:"task-\u522b\u540d",level:2},{value:"\u8986\u76d6 Task \u540d\u79f0",id:"\u8986\u76d6-task-\u540d\u79f0",level:2},{value:"\u9759\u9ed8\u6a21\u5f0f",id:"\u9759\u9ed8\u6a21\u5f0f",level:2},{value:"\u8bd5\u8fd0\u884c\u6a21\u5f0f",id:"\u8bd5\u8fd0\u884c\u6a21\u5f0f",level:2},{value:"\u5ffd\u7565\u9519\u8bef",id:"\u5ffd\u7565\u9519\u8bef",level:2},{value:"\u8f93\u51fa\u8bed\u6cd5",id:"\u8f93\u51fa\u8bed\u6cd5",level:2},{value:"\u4ea4\u4e92\u5f0f CLI \u5e94\u7528",id:"\u4ea4\u4e92\u5f0f-cli-\u5e94\u7528",level:2},{value:"\u77ed Task \u8bed\u6cd5",id:"\u77ed-task-\u8bed\u6cd5",level:2},{value:"set \u548c shopt",id:"set-\u548c-shopt",level:2},{value:"\u89c2\u5bdf task",id:"\u89c2\u5bdf-task",level:2}],o={toc:k};function m(e){let{components:n,...a}=e;return(0,l.kt)("wrapper",(0,t.Z)({},o,a,{components:n,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"\u4f7f\u7528\u6307\u5357"},"\u4f7f\u7528\u6307\u5357"),(0,l.kt)("h2",{id:"\u5feb\u901f\u5165\u95e8"},"\u5feb\u901f\u5165\u95e8"),(0,l.kt)("p",null,"\u5728\u9879\u76ee\u7684\u6839\u76ee\u5f55\u4e2d\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a ",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," \u7684\u6587\u4ef6\u3002 ",(0,l.kt)("inlineCode",{parentName:"p"},"cmds")," \u5c5e\u6027\u5e94\u5305\u542b task \u7684\u547d\u4ee4\u3002 \u4e0b\u9762\u7684\u793a\u4f8b\u5141\u8bb8\u7f16\u8bd1 Go \u5e94\u7528\u7a0b\u5e8f\u5e76\u4f7f\u7528 ",(0,l.kt)("a",{parentName:"p",href:"https://esbuild.github.io/"},"esbuild")," \u5c06\u591a\u4e2a CSS \u6587\u4ef6\u5408\u5e76\u5e76\u7f29\u5c0f\u4e3a\u4e00\u4e2a\u6587\u4ef6\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u8fd0\u884c task \u5c31\u8fd9\u6837\u7b80\u5355\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"task assets build\n")),(0,l.kt)("p",null,"Task \u4f7f\u7528 ",(0,l.kt)("a",{parentName:"p",href:"https://mvdan.cc/sh/"},"mvdan.cc/sh"),"\uff0c\u4e00\u4e2a\u539f\u751f\u7684 Go sh \u89e3\u91ca\u5668\u3002 \u56e0\u6b64\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199 sh/bash \u547d\u4ee4\uff0c\u5b83\u751a\u81f3\u53ef\u4ee5\u5728 Windows \u4e0a\u8fd0\u884c\uff0c\u800c ",(0,l.kt)("inlineCode",{parentName:"p"},"sh")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"bash")," \u901a\u5e38\u4e0d\u53ef\u7528\u3002 \u8bf7\u8bb0\u4f4f\uff0c\u4efb\u4f55\u88ab\u8c03\u7528\u7684\u53ef\u6267\u884c\u6587\u4ef6\u90fd\u5fc5\u987b\u5728\u64cd\u4f5c\u7cfb\u7edf\u6216 PATH \u4e2d\u53ef\u7528\u3002"),(0,l.kt)("p",null,'\u5982\u679c\u4e0d\u4f20 task \u7684\u540d\u5b57\uff0c\u9ed8\u8ba4\u4f1a\u8c03\u7528 "default"\u3002'),(0,l.kt)("h2",{id:"\u652f\u6301\u7684\u6587\u4ef6\u540d\u79f0"},"\u652f\u6301\u7684\u6587\u4ef6\u540d\u79f0"),(0,l.kt)("p",null,"Task \u4f1a\u6309\u4ee5\u4e0b\u987a\u5e8f\u67e5\u627e\u914d\u7f6e\u6587\u4ef6:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Taskfile.yml"),(0,l.kt)("li",{parentName:"ul"},"Taskfile.yaml"),(0,l.kt)("li",{parentName:"ul"},"Taskfile.dist.yml"),(0,l.kt)("li",{parentName:"ul"},"Taskfile.dist.yaml")),(0,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},".dist")," \u53d8\u4f53\u7684\u76ee\u7684\u662f\u5141\u8bb8\u9879\u76ee\u6709\u4e00\u4e2a\u63d0\u4ea4\u7248\u672c (",(0,l.kt)("inlineCode",{parentName:"p"},".dist"),")\uff0c\u540c\u65f6\u4ecd\u7136\u5141\u8bb8\u4e2a\u4eba\u7528\u6237\u901a\u8fc7\u6dfb\u52a0\u989d\u5916\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile.yml"),"\uff08\u5c06\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},".gitignore")," \u4e0a\uff09\u6765\u8986\u76d6 Taskfile\u3002"),(0,l.kt)("h3",{id:"\u4ece\u5b50\u76ee\u5f55\u8fd0\u884c-taskfile"},"\u4ece\u5b50\u76ee\u5f55\u8fd0\u884c Taskfile"),(0,l.kt)("p",null,"\u5982\u679c\u5728\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u4e2d\u627e\u4e0d\u5230 Taskfile\uff0c\u5b83\u5c06\u6cbf\u7740\u6587\u4ef6\u6811\u5411\u4e0a\u67e5\u627e\uff0c\u76f4\u5230\u627e\u5230\u4e00\u4e2a\uff08\u7c7b\u4f3c\u4e8e ",(0,l.kt)("inlineCode",{parentName:"p"},"git")," \u7684\u5de5\u4f5c\u65b9\u5f0f\uff09\u3002 \u5f53\u4ece\u8fd9\u6837\u7684\u5b50\u76ee\u5f55\u8fd0\u884c Task \u65f6\uff0c\u5b83\u7684\u884c\u4e3a\u5c31\u50cf\u4ece\u5305\u542b Taskfile \u7684\u76ee\u5f55\u8fd0\u884c\u5b83\u4e00\u6837\u3002"),(0,l.kt)("p",null,"\u60a8\u53ef\u4ee5\u5c06\u6b64\u529f\u80fd\u4e0e\u7279\u6b8a\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}")," \u53d8\u91cf\u4e00\u8d77\u4f7f\u7528\u6765\u521b\u5efa\u4e00\u4e9b\u975e\u5e38\u6709\u7528\u7684\u53ef\u91cd\u7528 task\u3002 \u4f8b\u5982\uff0c\u5982\u679c\u4f60\u6709\u4e00\u4e2a\u5305\u542b\u6bcf\u4e2a\u5fae\u670d\u52a1\u76ee\u5f55\u7684 monorepo\uff0c\u4f60\u53ef\u4ee5 ",(0,l.kt)("inlineCode",{parentName:"p"},"cd")," \u8fdb\u5165\u4e00\u4e2a\u5fae\u670d\u52a1\u76ee\u5f55\u5e76\u8fd0\u884c\u4e00\u4e2a task \u547d\u4ee4\u6765\u542f\u52a8\u5b83\uff0c\u800c\u4e0d\u5fc5\u521b\u5efa\u591a\u4e2a task \u6216\u5177\u6709\u76f8\u540c\u5185\u5bb9\u7684 Taskfile\u3002 \u4f8b\u5982\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5728\u6b64\u793a\u4f8b\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"cd ")," \u548c ",(0,l.kt)("inlineCode",{parentName:"p"},"task up"),"\uff0c\u53ea\u8981 ",(0,l.kt)("inlineCode",{parentName:"p"},"")," \u76ee\u5f55\u5305\u542b ",(0,l.kt)("inlineCode",{parentName:"p"},"docker-compose.yml"),"\uff0c\u5c31\u4f1a\u542f\u52a8 Docker Compose\u3002"),(0,l.kt)("h3",{id:"\u8fd0\u884c\u5168\u5c40-taskfile"},"\u8fd0\u884c\u5168\u5c40 Taskfile"),(0,l.kt)("p",null,"\u5982\u679c\u60a8\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"--global"),"\uff08\u522b\u540d ",(0,l.kt)("inlineCode",{parentName:"p"},"-g"),"\uff09\u6807\u5fd7\u8c03\u7528 Task\uff0c\u5b83\u5c06\u67e5\u627e\u60a8\u7684 home \u76ee\u5f55\u800c\u4e0d\u662f\u60a8\u7684\u5de5\u4f5c\u76ee\u5f55\u3002 \u7b80\u800c\u8a00\u4e4b\uff0cTask \u5c06\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yml")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yaml")," \u8def\u5f84\u4e0a\u5bfb\u627e Taskfile\u3002"),(0,l.kt)("p",null,"\u8fd9\u5bf9\u4e8e\u60a8\u53ef\u4ee5\u5728\u7cfb\u7edf\u7684\u4efb\u4f55\u5730\u65b9\u8fd0\u884c\u7684\u81ea\u52a8\u5316\u5f88\u6709\u7528\uff01"),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u5f53\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"-g")," \u8fd0\u884c\u5168\u5c40 Taskfile \u65f6\uff0ctask \u5c06\u9ed8\u8ba4\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},"$HOME")," \u4e0a\u8fd0\u884c\uff0c\u800c\u4e0d\u662f\u5728\u60a8\u7684\u5de5\u4f5c\u76ee\u5f55\u4e0a\uff01"),(0,l.kt)("p",{parentName:"admonition"},"\u5982\u524d\u4e00\u8282\u6240\u8ff0\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}")," \u7279\u6b8a\u53d8\u91cf\u5728\u8fd9\u91cc\u53ef\u4ee5\u975e\u5e38\u65b9\u4fbf\u5730\u5728\u60a8\u4ece\u4e2d\u8c03\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"task -g")," \u7684\u76ee\u5f55\u4e2d\u8fd0\u884c\u5185\u5bb9\u3002"),(0,l.kt)("pre",{parentName:"admonition"},(0,l.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,l.kt)("h2",{id:"\u73af\u5883\u53d8\u91cf"},"\u73af\u5883\u53d8\u91cf"),(0,l.kt)("h3",{id:"task"},"Task"),(0,l.kt)("p",null,"\u4f60\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"env")," \u7ed9\u6bcf\u4e2a task \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u73af\u5883\u53d8\u91cf:"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u6b64\u5916\uff0c\u60a8\u53ef\u4ee5\u8bbe\u7f6e\u53ef\u7528\u4e8e\u6240\u6709 task \u7684\u5168\u5c40\u73af\u5883\u53d8\u91cf\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},(0,l.kt)("inlineCode",{parentName:"p"},"env")," \u652f\u6301\u6269\u5c55\u548c\u68c0\u7d22 shell \u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u5c31\u50cf\u53d8\u91cf\u4e00\u6837\uff0c\u5982\u60a8\u5728 ",(0,l.kt)("a",{parentName:"p",href:"#%E5%8F%98%E9%87%8F"},"\u53d8\u91cf")," \u90e8\u5206\u4e2d\u770b\u5230\u7684\u90a3\u6837\u3002")),(0,l.kt)("h3",{id:"env-\u6587\u4ef6"},".env \u6587\u4ef6"),(0,l.kt)("p",null,"\u60a8\u8fd8\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"dotenv:")," \u8bbe\u7f6e\u8981\u6c42 tasks \u5305\u542b ",(0,l.kt)("inlineCode",{parentName:"p"},".env")," \u4e4b\u7c7b\u7684\u6587\u4ef6"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title=".env"',title:'".env"'},"KEYNAME=VALUE\n")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title="testing/.env"',title:'"testing/.env"'},"ENDPOINT=testing.com\n")),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4e5f\u53ef\u4ee5\u5728 task \u7ea7\u522b\u6307\u5b9a .env \u6587\u4ef6\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5728 task \u7ea7\u522b\u660e\u786e\u6307\u5b9a\u7684\u73af\u5883\u53d8\u91cf\u5c06\u8986\u76d6\u70b9\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u8bf7\u6ce8\u610f\uff0c\u60a8\u76ee\u524d\u65e0\u6cd5\u5728\u5305\u542b\u7684 Taskfile \u4e2d\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"dotenv")," \u952e\u3002")),(0,l.kt)("h2",{id:"\u5305\u542b\u5176\u4ed6-taskfile"},"\u5305\u542b\u5176\u4ed6 Taskfile"),(0,l.kt)("p",null,"\u5982\u679c\u8981\u5728\u4e0d\u540c\u9879\u76ee\uff08Taskfile\uff09\u4e4b\u95f4\u5171\u4eab\u4efb\u52a1\uff0c\u53ef\u4ee5\u4f7f\u7528\u5bfc\u5165\u673a\u5236\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"includes")," \u5173\u952e\u5b57\u5305\u542b\u5176\u4ed6\u4efb\u52a1\u6587\u4ef6\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u7ed9\u5b9a\u7684 Taskfile \u4e2d\u63cf\u8ff0\u7684\u4efb\u52a1\u5c06\u5728\u6307\u5b9a\u7684\u547d\u540d\u7a7a\u95f4\u4e2d\u63d0\u4f9b\u3002 \u56e0\u6b64\uff0c\u60a8\u53ef\u4ee5\u8c03\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"task docs:serve")," \u4ece ",(0,l.kt)("inlineCode",{parentName:"p"},"documentation/Taskfile.yml")," \u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"serve")," task\uff0c\u6216\u8005\u8c03\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"task docker:build")," \u4ece ",(0,l.kt)("inlineCode",{parentName:"p"},"DockerTasks.yml")," \u6587\u4ef6\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"build")," task\u3002"),(0,l.kt)("p",null,"\u76f8\u5bf9\u8def\u5f84\u662f\u76f8\u5bf9\u4e8e\u5305\u542b\u5305\u542b Taskfile \u7684\u76ee\u5f55\u89e3\u6790\u7684\u3002"),(0,l.kt)("h3",{id:"\u64cd\u4f5c\u7cfb\u7edf\u7279\u5b9a-taskfile"},"\u64cd\u4f5c\u7cfb\u7edf\u7279\u5b9a Taskfile"),(0,l.kt)("p",null,"\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},"version: '2'")," \u4e2d\uff0ctask \u4f1a\u81ea\u52a8\u5c1d\u8bd5\u5f15\u5165 ",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile_{{OS}}.yml")," \u6587\u4ef6 \uff08\u4f8b\u5982",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile_windows.yml"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile_linux.yml")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile_darwin.yml"),"\uff09\u3002 \u4f46\u662f\u56e0\u4e3a\u8fc7\u4e8e\u9690\u6666\uff0c\u5728\u7248\u672c 3 \u4e2d\u88ab\u79fb\u9664\u4e86\uff0c \u5728\u7248\u672c 3 \u53ef\u4ee5\u901a\u8fc7\u660e\u786e\u7684\u5f15\u7528\u6765\u5b9e\u73b0\u7c7b\u4f3c\u529f\u80fd:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n build: ./Taskfile_{{OS}}.yml\n")),(0,l.kt)("h3",{id:"\u5305\u542b-taskfile-\u7684\u76ee\u5f55"},"\u5305\u542b Taskfile \u7684\u76ee\u5f55"),(0,l.kt)("p",null,"\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5305\u542b\u7684 Taskfile \u7684 task \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\u8fd0\u884c\uff0c\u5373\u4f7f Taskfile \u5728\u53e6\u4e00\u4e2a\u76ee\u5f55\u4e2d\uff0c\u4f46\u60a8\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u66ff\u4ee3\u8bed\u6cd5\u5f3a\u5236\u5176 task \u5728\u53e6\u4e00\u4e2a\u76ee\u5f55\u4e2d\u8fd0\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n docs:\n taskfile: ./docs/Taskfile.yml\n dir: ./docs\n")),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u5305\u542b\u7684 Taskfile \u5fc5\u987b\u4f7f\u7528\u4e0e\u4e3b Taskfile \u4f7f\u7528\u7684\u76f8\u540c\u89c4\u5219\u7248\u672c\u3002")),(0,l.kt)("h3",{id:"\u53ef\u9009-includes"},"\u53ef\u9009 includes"),(0,l.kt)("p",null,"\u5982\u679c\u5305\u542b\u6587\u4ef6\u4e22\u5931\uff0c\u6807\u8bb0\u4e3a\u53ef\u9009\u7684\u5305\u542b\u5c06\u5141\u8bb8 task \u7ee7\u7eed\u6b63\u5e38\u6267\u884c\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h3",{id:"\u5185\u90e8-includes"},"\u5185\u90e8 includes"),(0,l.kt)("p",null,"\u6807\u8bb0\u4e3a internal \u7684\u5305\u542b\u4f1a\u5c06\u5305\u542b\u6587\u4ef6\u7684\u6240\u6709 task \u4e5f\u8bbe\u7f6e\u4e3a\u5185\u90e8 task\uff08\u8bf7\u53c2\u9605\u4e0b\u9762\u7684 ",(0,l.kt)("a",{parentName:"p",href:"#%E5%86%85%E9%83%A8-tasks"},"\u5185\u90e8-tasks")," \u90e8\u5206\uff09\u3002 \u8fd9\u5728\u5305\u542b\u4e0d\u6253\u7b97\u7531\u7528\u6237\u76f4\u63a5\u4f7f\u7528\u7684\u5b9e\u7528\u7a0b\u5e8f\u4efb\u52a1\u65f6\u5f88\u6709\u7528\u3002"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n tests:\n taskfile: ./taskfiles/Utils.yml\n internal: true\n")),(0,l.kt)("h3",{id:"\u5305\u542b-taskfile-\u7684\u53d8\u91cf"},"\u5305\u542b Taskfile \u7684\u53d8\u91cf"),(0,l.kt)("p",null,"\u60a8\u8fd8\u53ef\u4ee5\u5728\u5305\u542b Taskfile \u65f6\u6307\u5b9a\u53d8\u91cf\u3002 \u8fd9\u5bf9\u4e8e\u62e5\u6709\u53ef\u4ee5\u8c03\u6574\u751a\u81f3\u591a\u6b21\u5305\u542b\u7684\u53ef\u91cd\u7528 Taskfile \u53ef\u80fd\u5f88\u6709\u7528\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h3",{id:"\u547d\u540d\u7a7a\u95f4\u522b\u540d"},"\u547d\u540d\u7a7a\u95f4\u522b\u540d"),(0,l.kt)("p",null,"\u5305\u542b Taskfile \u65f6\uff0c\u60a8\u53ef\u4ee5\u4e3a\u547d\u540d\u7a7a\u95f4\u63d0\u4f9b\u4e00\u4e2a ",(0,l.kt)("inlineCode",{parentName:"p"},"aliases")," \u5217\u8868\u3002 \u8fd9\u4e0e ",(0,l.kt)("a",{parentName:"p",href:"#task-%E5%88%AB%E5%90%8D"},"task \u522b\u540d")," \u7684\u5de5\u4f5c\u65b9\u5f0f\u76f8\u540c\uff0c\u53ef\u4ee5\u4e00\u8d77\u4f7f\u7528\u6765\u521b\u5efa\u66f4\u77ed\u4e14\u66f4\u6613\u4e8e\u952e\u5165\u7684\u547d\u4ee4\u3002"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n generate:\n taskfile: ./taskfiles/Generate.yml\n aliases: [gen]\n")),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u5728\u5305\u542b\u7684 Taskfile \u4e2d\u58f0\u660e\u7684\u53d8\u91cf\u4f18\u5148\u4e8e\u5305\u542b Taskfile \u4e2d\u7684\u53d8\u91cf\uff01 \u5982\u679c\u60a8\u5e0c\u671b\u5305\u542b\u7684 Taskfile \u4e2d\u7684\u53d8\u91cf\u53ef\u88ab\u8986\u76d6\uff0c\u8bf7\u4f7f\u7528 ",(0,l.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/defaults.html"},"\u9ed8\u8ba4\u65b9\u6cd5"),"\uff1a",(0,l.kt)("inlineCode",{parentName:"p"},"MY_VAR: '{{.MY_VAR | default \"my-default-value\"}}'"),"\u3002")),(0,l.kt)("h2",{id:"\u5185\u90e8-tasks"},"\u5185\u90e8 tasks"),(0,l.kt)("p",null,"\u5185\u90e8 task \u662f\u7528\u6237\u4e0d\u80fd\u76f4\u63a5\u8c03\u7528\u7684 task\u3002 \u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"task --list|--list-all")," \u65f6\uff0c\u5b83\u4eec\u4e0d\u4f1a\u51fa\u73b0\u5728\u8f93\u51fa\u4e2d\u3002 \u5176\u4ed6 task \u53ef\u4ee5\u7167\u5e38\u8c03\u7528\u5185\u90e8 task\u3002 \u8fd9\u5bf9\u4e8e\u521b\u5efa\u5728\u547d\u4ee4\u884c\u4e0a\u6ca1\u6709\u7528\u5904\u7684\u53ef\u91cd\u7528\u3001\u7c7b\u4f3c\u51fd\u6570\u7684 task \u5f88\u6709\u7528\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"task-\u76ee\u5f55"},"Task \u76ee\u5f55"),(0,l.kt)("p",null,"\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ctasks \u5c06\u5728 Taskfile \u6240\u5728\u7684\u76ee\u5f55\u4e2d\u6267\u884c\u3002 \u4f46\u662f\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u8ba9 task \u5728\u53e6\u4e00\u4e2a\u76ee\u5f55\u4e2d\u8fd0\u884c\uff0c\u6307\u5b9a ",(0,l.kt)("inlineCode",{parentName:"p"},"dir"),"\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5982\u679c\u8be5\u76ee\u5f55\u4e0d\u5b58\u5728\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"task")," \u4f1a\u521b\u5efa\u5b83\u3002"),(0,l.kt)("h2",{id:"task-\u4f9d\u8d56"},"Task \u4f9d\u8d56"),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\u4f9d\u8d56\u9879\u5e76\u884c\u8fd0\u884c\uff0c\u56e0\u6b64\u4e00\u9879 task \u7684\u4f9d\u8d56\u9879\u4e0d\u5e94\u76f8\u4e92\u4f9d\u8d56\u3002 \u5982\u679c\u60a8\u60f3\u5f3a\u5236\u4efb\u52a1\u987a\u5e8f\u8fd0\u884c\uff0c\u8bf7\u67e5\u770b\u4e0b\u9762\u7684 ",(0,l.kt)("a",{parentName:"p",href:"#%E8%B0%83%E7%94%A8%E5%8F%A6%E4%B8%80%E4%B8%AA-task"},"\u8c03\u7528\u53e6\u4e00\u4e2a task")," \u90e8\u5206\u3002")),(0,l.kt)("p",null,"\u60a8\u53ef\u80fd\u6709\u4f9d\u8d56\u4e8e\u5176\u5b83\u7684 task\u3002 \u5c06\u5b83\u4eec\u6307\u5411 ",(0,l.kt)("inlineCode",{parentName:"p"},"deps")," \u5c06\u4f7f\u5b83\u4eec\u5728\u8fd0\u884c\u7236 task \u4e4b\u524d\u81ea\u52a8\u8fd0\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c\u5982\u679c\u60a8\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"task build"),"\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"assets")," \u5c06\u59cb\u7ec8\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},"build")," \u4e4b\u524d\u8fd0\u884c\u3002"),(0,l.kt)("p",null,"\u4e00\u4e2a task \u53ea\u80fd\u6709\u4f9d\u8d56\u5173\u7cfb\uff0c\u6ca1\u6709\u547d\u4ee4\u6765\u5c06 task \u7ec4\u5408\u5728\u4e00\u8d77\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5982\u679c\u6709\u591a\u4e2a\u4f9d\u8d56\u9879\uff0c\u5b83\u4eec\u603b\u662f\u5e76\u884c\u8fd0\u884c\u4ee5\u83b7\u5f97\u66f4\u597d\u7684\u6027\u80fd\u3002"),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"\u60a8\u8fd8\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"--parallel")," \u6807\u5fd7\uff08\u522b\u540d ",(0,l.kt)("inlineCode",{parentName:"p"},"-p"),"\uff09\u4f7f\u547d\u4ee4\u884c\u7ed9\u51fa\u7684 task \u5e76\u884c\u8fd0\u884c\u3002 \u4f8b\u5982: ",(0,l.kt)("inlineCode",{parentName:"p"},"task --parallel js css"),"\u3002")),(0,l.kt)("p",null,"\u5982\u679c\u4f60\u60f3\u5c06\u4fe1\u606f\u4f20\u9012\u7ed9\u4f9d\u8d56\u9879\uff0c\u4f60\u53ef\u4ee5\u50cf ",(0,l.kt)("a",{parentName:"p",href:"#%E8%B0%83%E7%94%A8%E5%8F%A6%E4%B8%80%E4%B8%AA-task"},"\u8c03\u7528\u53e6\u4e00\u4e2a task")," \u4e00\u6837\u4ee5\u76f8\u540c\u7684\u65b9\u5f0f\u8fdb\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u5e73\u53f0\u7279\u5b9a\u7684-tasks-\u548c-cmds"},"\u5e73\u53f0\u7279\u5b9a\u7684 tasks \u548c cmds"),(0,l.kt)("p",null,"\u5982\u679c\u60a8\u60f3\u5c06 task \u7684\u8fd0\u884c\u9650\u5236\u5728\u660e\u786e\u7684\u5e73\u53f0\u4e0a\uff0c\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"platforms:")," \u952e\u6765\u5b9e\u73b0\u3002 Task \u53ef\u4ee5\u9650\u5236\u5728\u7279\u5b9a\u7684\u64cd\u4f5c\u7cfb\u7edf\u3001\u67b6\u6784\u6216\u4e24\u8005\u7684\u7ec4\u5408\u4e2d\u3002 \u5982\u679c\u4e0d\u5339\u914d\uff0c\u4efb\u52a1\u6216\u547d\u4ee4\u5c06\u88ab\u8df3\u8fc7\uff0c\u5e76\u4e14\u4e0d\u4f1a\u629b\u51fa\u4efb\u4f55\u9519\u8bef\u3002"),(0,l.kt)("p",null,"\u5141\u8bb8\u4f5c\u4e3a OS \u6216 Arch \u7684\u503c\u662f\u6709\u6548\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},"GOOS")," \u548c ",(0,l.kt)("inlineCode",{parentName:"p"},"GOARCH")," \u503c\uff0c\u6b63\u5982 ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/golang/go/blob/master/src/go/build/syslist.go"},"\u6b64\u5904")," \u7684 Go \u8bed\u8a00\u6240\u5b9a\u4e49\u7684\u90a3\u6837\u3002"),(0,l.kt)("p",null,"\u4e0b\u9762\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},"build-windows")," task \u5c06\u4ec5\u5728 Windows \u6240\u6709\u67b6\u6784\u4e0a\u8fd0\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u8fd9\u53ef\u4ee5\u9650\u5236\u4e3a\u7279\u5b9a\u7684\u67b6\u6784\uff0c\u5982\u4e0b\u6240\u793a\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4e5f\u53ef\u4ee5\u5c06 task \u9650\u5236\u5728\u7279\u5b9a\u7684\u67b6\u6784\u4e2d\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u53ef\u4ee5\u6307\u5b9a\u591a\u4e2a\u5e73\u53f0\uff0c\u5982\u4e0b\u6240\u793a\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4e2a\u522b\u547d\u4ee4\u4e5f\u53ef\u4ee5\u9650\u5236\u5728\u7279\u5b9a\u5e73\u53f0\u4e0a\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u8c03\u7528\u53e6\u4e00\u4e2a-task"},"\u8c03\u7528\u53e6\u4e00\u4e2a task"),(0,l.kt)("p",null,"\u5f53\u4e00\u4e2a task \u6709\u5f88\u591a\u4f9d\u8d56\u65f6\uff0c\u5b83\u4eec\u662f\u5e76\u53d1\u6267\u884c\u7684\u3002 \u8fd9\u901a\u5e38\u4f1a\u5bfc\u81f4\u66f4\u5feb\u7684\u6784\u5efa\u7ba1\u9053\u3002 \u4f46\u662f\uff0c\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u60a8\u53ef\u80fd\u9700\u8981\u4e32\u884c\u8c03\u7528\u5176\u4ed6 task\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u8bf7\u4f7f\u7528\u4ee5\u4e0b\u8bed\u6cd5\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5728\u88ab\u8c03\u7528 task \u4e2d\u8986\u76d6\u53d8\u91cf\u5c31\u50cf\u901a\u77e5 ",(0,l.kt)("inlineCode",{parentName:"p"},"vars")," \u5c5e\u6027\u4e00\u6837\u7b80\u5355\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"deps")," \u4e5f\u652f\u6301\u4e0a\u8ff0\u8bed\u6cd5\u3002"),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"\u6ce8\u610f\uff1a\u5982\u679c\u60a8\u60f3\u4ece ",(0,l.kt)("a",{parentName:"p",href:"#%E5%8C%85%E5%90%AB%E5%85%B6%E4%BB%96-taskfile"},"\u5305\u542b\u7684 Taskfile")," \u4e2d\u8c03\u7528\u5728\u6839 Taskfile \u4e2d\u58f0\u660e\u7684 task\uff0c\u8bf7\u50cf\u8fd9\u6837\u6dfb\u52a0 ",(0,l.kt)("inlineCode",{parentName:"p"},":")," \u524d\u7f00\uff1a",(0,l.kt)("inlineCode",{parentName:"p"},"task: :task-name"),"\u3002")),(0,l.kt)("h2",{id:"\u51cf\u5c11\u4e0d\u5fc5\u8981\u7684\u5de5\u4f5c"},"\u51cf\u5c11\u4e0d\u5fc5\u8981\u7684\u5de5\u4f5c"),(0,l.kt)("h3",{id:"\u901a\u8fc7\u6307\u7eb9\u8bc6\u522b\u672c\u5730\u751f\u6210\u7684\u6587\u4ef6\u53ca\u5176\u6765\u6e90"},"\u901a\u8fc7\u6307\u7eb9\u8bc6\u522b\u672c\u5730\u751f\u6210\u7684\u6587\u4ef6\u53ca\u5176\u6765\u6e90"),(0,l.kt)("p",null,"\u5982\u679c\u4e00\u4e2a task \u751f\u6210\u4e86\u4e00\u4e9b\u4e1c\u897f\uff0c\u4f60\u53ef\u4ee5\u901a\u77e5 task \u6e90\u548c\u751f\u6210\u7684\u6587\u4ef6\uff0c\u8fd9\u6837 task \u5c31\u4f1a\u5728\u4e0d\u9700\u8981\u7684\u65f6\u5019\u963b\u6b62\u8fd0\u884c\u5b83\u4eec\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"sources")," \u548c ",(0,l.kt)("inlineCode",{parentName:"p"},"generates")," \u53ef\u4ee5\u914d\u7f6e\u5177\u4f53\u6587\u4ef6\u6216\u8005\u4f7f\u7528\u5339\u914d\u6a21\u5f0f\u3002 \u8bbe\u7f6e\u540e\uff0c Task \u4f1a\u6839\u636e\u6e90\u6587\u4ef6\u7684 checksum \u6765\u786e\u5b9a\u662f\u5426\u9700\u8981\u6267\u884c\u5f53\u524d\u4efb\u52a1\u3002 \u5982\u679c\u4e0d\u9700\u8981\u6267\u884c\uff0c \u5219\u4f1a\u8f93\u51fa\u50cf ",(0,l.kt)("inlineCode",{parentName:"p"},'Task "js" is up to date')," \u8fd9\u6837\u7684\u4fe1\u606f\u3002"),(0,l.kt)("p",null,"\u5982\u679c\u60a8\u5e0c\u671b\u901a\u8fc7\u6587\u4ef6\u7684\u4fee\u6539 timestamp \u800c\u4e0d\u662f\u5176 checksum\uff08\u5185\u5bb9\uff09\u6765\u8fdb\u884c\u6b64\u68c0\u67e5\uff0c\u53ea\u9700\u5c06 ",(0,l.kt)("inlineCode",{parentName:"p"},"method")," \u5c5e\u6027\u8bbe\u7f6e\u4e3a ",(0,l.kt)("inlineCode",{parentName:"p"},"timestamp")," \u5373\u53ef\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5728\u9700\u8981\u66f4\u5927\u7075\u6d3b\u6027\u7684\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u5173\u952e\u5b57\u3002 \u60a8\u751a\u81f3\u53ef\u4ee5\u5c06\u4e24\u8005\u7ed3\u5408\u8d77\u6765\u3002 \u6709\u5173\u793a\u4f8b\uff0c\u8bf7\u53c2\u9605 ",(0,l.kt)("a",{parentName:"p",href:"#%E4%BD%BF%E7%94%A8%E7%A8%8B%E5%BA%8F%E6%A3%80%E6%9F%A5%E6%9D%A5%E8%A1%A8%E7%A4%BA%E4%BB%BB%E5%8A%A1%E6%98%AF%E6%9C%80%E6%96%B0%E7%9A%84"},"\u72b6\u6001")," \u6587\u6863\u3002"),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u9ed8\u8ba4\u60c5\u51b5\uff0ctask \u5728\u672c\u5730\u9879\u76ee\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},".task")," \u76ee\u5f55\u4fdd\u5b58 checksums \u503c\u3002 \u4e00\u822c\u90fd\u4f1a\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},".gitignore"),"\uff08\u6216\u7c7b\u4f3c\u914d\u7f6e\uff09\u4e2d\u5ffd\u7565\u6389\u8fd9\u4e2a\u76ee\u5f55\uff0c\u8fd9\u6837\u5b83\u5c31\u4e0d\u4f1a\u88ab\u63d0\u4ea4\u3002 (\u5982\u679c\u60a8\u6709\u4e00\u4e2a\u5df2\u63d0\u4ea4\u7684\u4ee3\u7801\u751f\u6210\u4efb\u52a1\uff0c\u90a3\u4e48\u63d0\u4ea4\u8be5\u4efb\u52a1\u7684\u6821\u9a8c\u548c\u4e5f\u662f\u6709\u610f\u4e49\u7684)\u3002"),(0,l.kt)("p",{parentName:"admonition"},"\u5982\u679c\u4f60\u60f3\u8981\u5c06\u8fd9\u4e9b\u6587\u4ef6\u5b58\u50a8\u5728\u53e6\u4e00\u4e2a\u76ee\u5f55\u4e2d\uff0c\u4f60\u53ef\u4ee5\u5728\u4f60\u7684\u673a\u5668\u4e2d\u8bbe\u7f6e\u4e00\u4e2a ",(0,l.kt)("inlineCode",{parentName:"p"},"TASK_TEMP_DIR")," \u73af\u5883\u53d8\u91cf\u3002 \u53ef\u4ee5\u4f7f\u7528\u76f8\u5bf9\u8def\u5f84\uff0c\u6bd4\u5982 ",(0,l.kt)("inlineCode",{parentName:"p"},"tmp/task"),"\uff0c\u76f8\u5bf9\u9879\u76ee\u6839\u76ee\u5f55\uff0c\u4e5f\u53ef\u4ee5\u7528\u7edd\u5bf9\u8def\u5f84\u3001\u7528\u6237\u76ee\u5f55\u8def\u5f84\uff0c\u6bd4\u5982 ",(0,l.kt)("inlineCode",{parentName:"p"},"/tmp/.task")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"~/.task"),"\uff08\u6bcf\u4e2a\u9879\u76ee\u5355\u72ec\u521b\u5efa\u5b50\u76ee\u5f55\uff09\u3002"),(0,l.kt)("pre",{parentName:"admonition"},(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"export TASK_TEMP_DIR='~/.task'\n"))),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u6bcf\u4e2a task \u53ea\u4e3a\u5176 ",(0,l.kt)("inlineCode",{parentName:"p"},"sources")," \u5b58\u50a8\u4e00\u4e2a checksum\u3002 \u5982\u679c\u60a8\u60f3\u901a\u8fc7\u4efb\u4f55\u8f93\u5165\u53d8\u91cf\u6765\u533a\u5206 task\uff0c\u60a8\u53ef\u4ee5\u5c06\u8fd9\u4e9b\u53d8\u91cf\u6dfb\u52a0\u4e3a task \u6807\u7b7e\u7684\u4e00\u90e8\u5206\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u4e0d\u540c\u7684 task\u3002"),(0,l.kt)("p",{parentName:"admonition"},"\u5982\u679c\u60a8\u60f3\u4e3a\u6bcf\u4e2a\u4e0d\u540c\u7684\u8f93\u5165\u96c6\u8fd0\u884c\u4e00\u6b21 task\uff0c\u76f4\u5230 sources \u5b9e\u9645\u53d1\u751f\u53d8\u5316\uff0c\u8fd9\u5c06\u5f88\u6709\u7528\u3002 \u4f8b\u5982\uff0c\u5982\u679c sources \u4f9d\u8d56\u4e8e\u53d8\u91cf\u7684\u503c\uff0c\u6216\u8005\u60a8\u5e0c\u671b\u5728\u67d0\u4e9b\u53c2\u6570\u53d1\u751f\u53d8\u5316\u65f6\u91cd\u65b0\u8fd0\u884c task\uff0c\u5373\u4f7f sources \u6ca1\u6709\u53d1\u751f\u53d8\u5316\u4e5f\u662f\u5982\u6b64\u3002")),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"\u5c06 method \u8bbe\u7f6e\u4e3a ",(0,l.kt)("inlineCode",{parentName:"p"},"none")," \u4f1a\u8df3\u8fc7\u4efb\u4f55\u9a8c\u8bc1\u5e76\u59cb\u7ec8\u8fd0\u884c\u4efb\u52a1\u3002")),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u8981\u4f7f ",(0,l.kt)("inlineCode",{parentName:"p"},"checksum"),"\uff08\u9ed8\u8ba4\uff09\u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"timestamp")," \u65b9\u6cd5\u8d77\u4f5c\u7528\uff0c\u53ea\u9700\u8981\u901a\u77e5 source \u6587\u4ef6\u5373\u53ef\u3002 \u5f53\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"timestamp")," \u65b9\u6cd5\u65f6\uff0c\u6700\u540e\u4e00\u6b21\u8fd0\u884c task \u88ab\u8ba4\u4e3a\u662f\u4e00\u6b21\u751f\u6210\u3002")),(0,l.kt)("h3",{id:"\u4f7f\u7528\u7a0b\u5e8f\u68c0\u67e5\u6765\u8868\u793a\u4efb\u52a1\u662f\u6700\u65b0\u7684"},"\u4f7f\u7528\u7a0b\u5e8f\u68c0\u67e5\u6765\u8868\u793a\u4efb\u52a1\u662f\u6700\u65b0\u7684"),(0,l.kt)("p",null,"\u6216\u8005\uff0c\u60a8\u53ef\u4ee5\u901a\u77e5\u4e00\u7cfb\u5217\u6d4b\u8bd5\u4f5c\u4e3a ",(0,l.kt)("inlineCode",{parentName:"p"},"status"),"\u3002 \u5982\u679c\u6ca1\u6709\u9519\u8bef\u8fd4\u56de\uff08\u9000\u51fa\u72b6\u6001 0\uff09\uff0ctask \u88ab\u8ba4\u4e3a\u662f\u6700\u65b0\u7684\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u901a\u5e38\uff0c\u60a8\u4f1a\u5c06 ",(0,l.kt)("inlineCode",{parentName:"p"},"sources")," \u4e0e ",(0,l.kt)("inlineCode",{parentName:"p"},"generates")," \u7ed3\u5408\u4f7f\u7528 - \u4f46\u5bf9\u4e8e\u751f\u6210\u8fdc\u7a0b\u5de5\u4ef6\uff08Docker \u6620\u50cf\u3001\u90e8\u7f72\u3001CD \u7248\u672c\uff09\u7684 task\uff0cchecksum source \u548c timestamps \u9700\u8981\u8bbf\u95ee\u5de5\u4ef6\u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},".checksum")," \u6307\u7eb9\u6587\u4ef6\u3002"),(0,l.kt)("p",null,"\u4e24\u4e2a\u7279\u6b8a\u53d8\u91cf ",(0,l.kt)("inlineCode",{parentName:"p"},"{{.CHECKSUM}}")," \u548c ",(0,l.kt)("inlineCode",{parentName:"p"},"{{.TIMESTAMP}}")," \u53ef\u7528\u4e8e ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u547d\u4ee4\u4e2d\u7684\u63d2\u503c\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u5206\u914d\u7ed9 sources \u7684\u6307\u7eb9\u65b9\u6cd5\u3002 \u53ea\u6709 ",(0,l.kt)("inlineCode",{parentName:"p"},"source")," \u5757\u624d\u80fd\u751f\u6210\u6307\u7eb9\u3002"),(0,l.kt)("p",null,"\u8bf7\u6ce8\u610f\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"{{.TIMESTAMP}}")," \u53d8\u91cf\u662f\u4e00\u4e2a\u201c\u5b9e\u65f6\u201dGo ",(0,l.kt)("inlineCode",{parentName:"p"},"time.Time")," \u7ed3\u6784\uff0c\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"time.Time")," \u54cd\u5e94\u7684\u4efb\u4f55\u65b9\u6cd5\u8fdb\u884c\u683c\u5f0f\u5316\u3002"),(0,l.kt)("p",null,"\u6709\u5173\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 ",(0,l.kt)("a",{parentName:"p",href:"https://golang.org/pkg/time/"},"Go Time \u6587\u6863"),"\u3002"),(0,l.kt)("p",null,"\u5982\u679c\u4f60\u60f3\u5f3a\u5236\u4efb\u52a1\u8fd0\u884c\uff0c\u5373\u4f7f\u662f\u6700\u65b0\u7684\uff0c\u4f60\u4e5f\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"--force")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"-f"),"\u3002"),(0,l.kt)("p",null,"\u6b64\u5916\uff0c\u5982\u679c\u4efb\u4f55 task \u4e0d\u662f\u6700\u65b0\u7684\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"task --status [tasks]...")," \u5c06\u4ee5\u975e\u96f6\u9000\u51fa\u4ee3\u7801\u9000\u51fa\u3002"),(0,l.kt)("p",null,"\u5982\u679c source/generated \u7684\u5de5\u4ef6\u53d1\u751f\u53d8\u5316\uff0c\u6216\u8005\u7a0b\u5e8f\u68c0\u67e5\u5931\u8d25\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u53ef\u4ee5\u4e0e ",(0,l.kt)("a",{parentName:"p",href:"#%E9%80%9A%E8%BF%87%E6%8C%87%E7%BA%B9%E8%AF%86%E5%88%AB%E6%9C%AC%E5%9C%B0%E7%94%9F%E6%88%90%E7%9A%84%E6%96%87%E4%BB%B6%E5%8F%8A%E5%85%B6%E6%9D%A5%E6%BA%90"},"\u6307\u7eb9")," \u7ed3\u5408\u4ee5\u8fd0\u884c\u4efb\u52a1\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h3",{id:"\u4f7f\u7528\u7a0b\u5e8f\u68c0\u67e5\u53d6\u6d88\u4efb\u52a1\u53ca\u5176\u4f9d\u8d56\u9879\u7684\u6267\u884c"},"\u4f7f\u7528\u7a0b\u5e8f\u68c0\u67e5\u53d6\u6d88\u4efb\u52a1\u53ca\u5176\u4f9d\u8d56\u9879\u7684\u6267\u884c"),(0,l.kt)("p",null,"\u9664\u4e86 ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u68c0\u67e5\u4e4b\u5916\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"preconditions")," \u68c0\u67e5\u662f ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u68c0\u67e5\u7684\u903b\u8f91\u9006\u8fc7\u7a0b\u3002 \u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u60a8\u9700\u8981\u4e00\u7ec4\u7279\u5b9a\u7684\u6761\u4ef6\u4e3a ",(0,l.kt)("em",{parentName:"p"},"true"),"\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"preconditions"),"\u3002 ",(0,l.kt)("inlineCode",{parentName:"p"},"preconditions")," \u7c7b\u4f3c\u4e8e ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u884c\uff0c\u9664\u4e86\u5b83\u4eec\u652f\u6301 ",(0,l.kt)("inlineCode",{parentName:"p"},"sh")," \u6269\u5c55\uff0c\u5e76\u4e14\u5b83\u4eec\u5e94\u8be5\u5168\u90e8\u8fd4\u56de 0\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5148\u51b3\u6761\u4ef6\u53ef\u4ee5\u8bbe\u7f6e\u7279\u5b9a\u7684\u5931\u8d25\u6d88\u606f\uff0c\u8fd9\u4e9b\u6d88\u606f\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"msg")," \u5b57\u6bb5\u544a\u8bc9\u7528\u6237\u8981\u91c7\u53d6\u4ec0\u4e48\u6b65\u9aa4\u3002"),(0,l.kt)("p",null,"\u5982\u679c\u4e00\u4e2a task \u4f9d\u8d56\u4e8e\u4e00\u4e2a\u5177\u6709\u524d\u63d0\u6761\u4ef6\u7684\u5b50 task\uff0c\u5e76\u4e14\u4e0d\u6ee1\u8db3\u8be5\u524d\u63d0\u6761\u4ef6 - \u8c03\u7528 task \u5c06\u5931\u8d25\u3002 \u8bf7\u6ce8\u610f\uff0c\u9664\u975e\u7ed9\u51fa ",(0,l.kt)("inlineCode",{parentName:"p"},"--force")," \uff0c\u5426\u5219\u4ee5\u5931\u8d25\u7684\u524d\u63d0\u6761\u4ef6\u6267\u884c\u7684 task \u5c06\u4e0d\u4f1a\u8fd0\u884c\u3002"),(0,l.kt)("p",null,"\u4e0e ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u5224\u65ad task \u662f\u6700\u65b0\u72b6\u6001\u65f6\u4f1a\u8df3\u8fc7\u5e76\u7ee7\u7eed\u6267\u884c\u4e0d\u540c\uff0c ",(0,l.kt)("inlineCode",{parentName:"p"},"precondition")," \u5931\u8d25\u4f1a\u5bfc\u81f4 task \u5931\u8d25\uff0c\u4ee5\u53ca\u6240\u6709\u4f9d\u8d56\u5b83\u7684 task \u90fd\u4f1a\u5931\u8d25\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h3",{id:"\u5728\u4efb\u52a1\u8fd0\u884c\u65f6\u9650\u5236"},"\u5728\u4efb\u52a1\u8fd0\u884c\u65f6\u9650\u5236"),(0,l.kt)("p",null,"\u5982\u679c task \u7531\u591a\u4e2a ",(0,l.kt)("inlineCode",{parentName:"p"},"cmd")," \u6216\u591a\u4e2a ",(0,l.kt)("inlineCode",{parentName:"p"},"deps")," \u6267\u884c\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"run")," \u63a7\u5236\u4f55\u65f6\u6267\u884c\u3002 ",(0,l.kt)("inlineCode",{parentName:"p"},"run")," \u4e5f\u53ef\u4ee5\u8bbe\u7f6e\u5728 Taskfile \u7684\u6839\u76ee\u5f55\u4ee5\u66f4\u6539\u6240\u6709\u4efb\u52a1\u7684\u884c\u4e3a\uff0c\u9664\u975e\u88ab\u660e\u786e\u8986\u76d6\u3002"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"run")," \u652f\u6301\u7684\u503c\uff1a"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"always")," \uff08\u9ed8\u8ba4\uff09\u603b\u662f\u5c1d\u8bd5\u8c03\u7528 task\uff0c\u65e0\u8bba\u5148\u524d\u6267\u884c\u7684\u6b21\u6570\u5982\u4f55"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"once")," \u53ea\u8c03\u7528\u4e00\u6b21\u8fd9\u4e2a\u4efb\u52a1\uff0c\u4e0d\u7ba1\u5f15\u7528\u7684\u6570\u91cf"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"when_changed")," \u53ea\u4e3a\u4f20\u9012\u7ed9 task \u7684\u6bcf\u4e2a\u552f\u4e00\u53d8\u91cf\u96c6\u8c03\u7528\u4e00\u6b21 task")),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u53d8\u91cf"},"\u53d8\u91cf"),(0,l.kt)("p",null,"\u5728\u8fdb\u884c\u53d8\u91cf\u63d2\u503c\u65f6\uff0cTask \u5c06\u67e5\u627e\u4ee5\u4e0b\u5185\u5bb9\u3002 \u5b83\u4eec\u6309\u6743\u91cd\u987a\u5e8f\u5217\u5728\u4e0b\u9762\uff08\u5373\u6700\u91cd\u8981\u7684\u7b2c\u4e00\u4f4d\uff09\uff1a"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"task \u5185\u90e8\u5b9a\u4e49\u7684\u53d8\u91cf"),(0,l.kt)("li",{parentName:"ul"},"\u88ab\u5176\u5b83 task \u8c03\u7528\u65f6\u4f20\u5165\u7684\u53d8\u91cf(\u67e5\u770b ",(0,l.kt)("a",{parentName:"li",href:"#%E8%B0%83%E7%94%A8%E5%8F%A6%E4%B8%80%E4%B8%AA-task"},"\u8c03\u7528\u53e6\u4e00\u4e2a task"),")"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#%E5%8C%85%E5%90%AB%E5%85%B6%E4%BB%96-taskfile"},"\u5305\u542b\u5176\u4ed6 Taskfile")," \u4e2d\u7684\u53d8\u91cf (\u5f53\u5305\u542b\u5176\u4ed6 task \u65f6)"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#%E5%8C%85%E5%90%AB-taskfile-%E7%9A%84%E5%8F%98%E9%87%8F"},"\u5305\u542b Taskfile")," \u7684\u53d8\u91cf\uff08\u5305\u542b task \u65f6\uff09"),(0,l.kt)("li",{parentName:"ul"},"\u5168\u5c40\u53d8\u91cf (\u5728 Taskfile \u7684 ",(0,l.kt)("inlineCode",{parentName:"li"},"vars:")," \u4e2d\u58f0\u660e)"),(0,l.kt)("li",{parentName:"ul"},"\u73af\u5883\u53d8\u91cf")),(0,l.kt)("p",null,"\u4f7f\u7528\u73af\u5883\u53d8\u91cf\u4f20\u8f93\u53c2\u6570\u7684\u793a\u4f8b\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"$ TASK_VARIABLE=a-value task do-something\n")),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"\u5305\u542b\u4efb\u52a1\u540d\u79f0\u7684\u7279\u6b8a\u53d8\u91cf ",(0,l.kt)("inlineCode",{parentName:"p"},".TASK")," \u59cb\u7ec8\u53ef\u7528\u3002")),(0,l.kt)("p",null,"\u7531\u4e8e\u67d0\u4e9b shell \u4e0d\u652f\u6301\u4e0a\u8ff0\u8bed\u6cd5\u6765\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf (Windows)\uff0ctask \u5728\u4e0d\u5728\u547d\u4ee4\u5f00\u5934\u65f6\u4e5f\u63a5\u53d7\u7c7b\u4f3c\u7684\u6837\u5f0f\u3002"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'$ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!"\n')),(0,l.kt)("p",null,"\u672c\u5730\u58f0\u660e\u7684\u53d8\u91cf\u793a\u4f8b\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," \u4e2d\u7684\u5168\u5c40\u53d8\u91cf\u793a\u4f8b\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h3",{id:"\u52a8\u6001\u53d8\u91cf"},"\u52a8\u6001\u53d8\u91cf"),(0,l.kt)("p",null,"\u4ee5\u4e0b\u8bed\u6cd5 (",(0,l.kt)("inlineCode",{parentName:"p"},"sh:")," prop in a variable) \u88ab\u8ba4\u4e3a\u662f\u52a8\u6001\u53d8\u91cf\u3002 \u8be5\u503c\u5c06\u88ab\u89c6\u4e3a\u547d\u4ee4\u5e76\u4ea7\u751f\u8f93\u51fa\u7ed3\u679c\u7528\u4e8e\u8d4b\u503c\u3002 \u5982\u679c\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u5c3e\u968f\u6362\u884c\u7b26\uff0c\u6700\u540e\u4e00\u4e2a\u6362\u884c\u7b26\u5c06\u88ab\u4fee\u526a\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u8fd9\u9002\u7528\u4e8e\u6240\u6709\u7c7b\u578b\u7684\u53d8\u91cf\u3002"),(0,l.kt)("h2",{id:"\u5c06-cli-\u53c2\u6570\u8f6c\u53d1\u5230-cmds"},"\u5c06 CLI \u53c2\u6570\u8f6c\u53d1\u5230 cmds"),(0,l.kt)("p",null,"\u5982\u679c ",(0,l.kt)("inlineCode",{parentName:"p"},"--")," \u5728 CLI \u4e2d\u7ed9\u51fa\uff0c\u5219\u6240\u6709\u4ee5\u4e0b\u53c2\u6570\u90fd\u5c06\u6dfb\u52a0\u5230\u7279\u6b8a\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},".CLI_ARGS")," \u53d8\u91cf\u4e2d\u3002 \u8fd9\u5bf9\u4e8e\u5c06\u53c2\u6570\u8f6c\u53d1\u7ed9\u53e6\u4e00\u4e2a\u547d\u4ee4\u5f88\u6709\u7528\u3002"),(0,l.kt)("p",null,"\u4e0b\u9762\u7684\u793a\u4f8b\u5c06\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"yarn install"),"\u3002"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"$ task yarn -- install\n")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n yarn:\n cmds:\n - yarn {{.CLI_ARGS}}\n")),(0,l.kt)("h2",{id:"\u4f7f\u7528-defer-\u505a-task-\u6e05\u7406"},"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"h2"},"defer")," \u505a task \u6e05\u7406"),(0,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"defer")," \u5173\u952e\u5b57\uff0c\u53ef\u4ee5\u5b89\u6392\u5728 task \u5b8c\u6210\u540e\u8fd0\u884c\u6e05\u7406\u3002 \u4e0e\u4ec5\u5c06\u5176\u4f5c\u4e3a\u6700\u540e\u4e00\u4e2a\u547d\u4ee4\u7684\u4e0d\u540c\u4e4b\u5904\u5728\u4e8e\uff0c\u5373\u4f7f task \u5931\u8d25\uff0c\u8be5\u547d\u4ee4\u4e5f\u4f1a\u8fd0\u884c\u3002"),(0,l.kt)("p",null,"\u5728\u4e0b\u9762\u7684\u793a\u4f8b\u4e2d\uff0c\u5373\u4f7f\u7b2c\u4e09\u4e2a\u547d\u4ee4\u5931\u8d25\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"rm -rf tmpdir/")," \u4e5f\u4f1a\u8fd0\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4f7f\u7528\u5176\u5b83 task \u4f5c\u4e3a\u6e05\u7406\u4efb\u52a1\u7684\u547d\u4ee4\u65f6\uff0c\u53ef\u4ee5\u8fd9\u6837\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u7531\u4e8e ",(0,l.kt)("a",{parentName:"p",href:"https://go.dev/tour/flowcontrol/13"},"Go \u81ea\u8eab\u7684 ",(0,l.kt)("inlineCode",{parentName:"a"},"defer")," \u5de5\u4f5c\u65b9\u5f0f")," \u7684\u6027\u8d28\uff0c\u5982\u679c\u60a8\u5b89\u6392\u591a\u4e2a defer\u547d\u4ee4\uff0c\u5219 defer \u547d\u4ee4\u5c06\u4ee5\u76f8\u53cd\u7684\u987a\u5e8f\u6267\u884c\u3002")),(0,l.kt)("h2",{id:"go-\u7684\u6a21\u677f\u5f15\u64ce"},"Go \u7684\u6a21\u677f\u5f15\u64ce"),(0,l.kt)("p",null,"Task \u5728\u6267\u884c\u547d\u4ee4\u4e4b\u524d\u5c06\u547d\u4ee4\u89e3\u6790\u4e3a ",(0,l.kt)("a",{parentName:"p",href:"https://golang.org/pkg/text/template/"},"Go \u7684\u6a21\u677f\u5f15\u64ce"),"\u3002 \u53ef\u4ee5\u901a\u8fc7\u70b9\u8bed\u6cd5 (",(0,l.kt)("inlineCode",{parentName:"p"},".VARNAME"),") \u8bbf\u95ee\u53d8\u91cf\u3002"),(0,l.kt)("p",null,"Go \u7684 ",(0,l.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/"},"slim-sprig \u5e93")," \u7684\u6240\u6709\u529f\u80fd\u90fd\u53ef\u7528\u3002 \u4ee5\u4e0b\u793a\u4f8b\u6309\u7167\u7ed9\u5b9a\u683c\u5f0f\u83b7\u53d6\u5f53\u524d\u65e5\u671f\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"Task \u8fd8\u589e\u52a0\u4e86\u4ee5\u4e0b\u529f\u80fd\uff1a"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"OS"),"\uff1a\u8fd4\u56de\u64cd\u4f5c\u7cfb\u7edf\u3002 \u53ef\u80fd\u7684\u503c\u4e3a\u201cwindows\u201d\u3001\u201clinux\u201d\u3001\u201cdarwin\u201d(macOS) \u548c\u201cfreebsd\u201d\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"ARCH"),"\uff1a\u8fd4\u56de Task \u7684\u7f16\u8bd1\u67b6\u6784\u4e3a\uff1a\u201c386\u201d\u3001\u201camd64\u201d\u3001\u201carm\u201d\u6216\u201cs390x\u201d\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"splitLines"),"\uff1a\u62c6\u5206 Unix (\\n) \u548c Windows (\\r\\n) \u6837\u5f0f\u7684\u6362\u884c\u7b26\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"catLines"),"\uff1a\u7528\u7a7a\u683c\u66ff\u6362 Unix (\\n) \u548c Windows (\\r\\n) \u6837\u5f0f\u7684\u6362\u884c\u7b26\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"toSlash"),"\uff1a\u5728 Unix \u4e0a\u4e0d\u6267\u884c\u4efb\u4f55\u64cd\u4f5c\uff0c\u4f46\u5728 Windows \u4e0a\u5c06\u5b57\u7b26\u4e32\u4ece ",(0,l.kt)("inlineCode",{parentName:"li"},"\\")," \u8def\u5f84\u683c\u5f0f\u8f6c\u6362\u4e3a ",(0,l.kt)("inlineCode",{parentName:"li"},"/"),"\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"fromSlash"),"\uff1a\u4e0e ",(0,l.kt)("inlineCode",{parentName:"li"},"toSlash")," \u76f8\u53cd\u3002 \u5728 Unix \u4e0a\u4e0d\u6267\u884c\u4efb\u4f55\u64cd\u4f5c\uff0c\u4f46\u5728 Windows \u4e0a\u5c06\u5b57\u7b26\u4e32\u4ece ",(0,l.kt)("inlineCode",{parentName:"li"},"/")," \u8def\u5f84\u683c\u5f0f\u8f6c\u6362\u4e3a ",(0,l.kt)("inlineCode",{parentName:"li"},"\\"),"\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"exeExt"),"\uff1a\u8fd4\u56de\u5f53\u524d\u64cd\u4f5c\u7cfb\u7edf\u7684\u6b63\u786e\u53ef\u6267\u884c\u6587\u4ef6\u6269\u5c55\u540d\uff08Windows \u4e3a",(0,l.kt)("inlineCode",{parentName:"li"},"\u201c.exe\u201d"),"\uff0c\u5176\u4ed6\u64cd\u4f5c\u7cfb\u7edf\u4e3a",(0,l.kt)("inlineCode",{parentName:"li"},"\u201c\u201d"),"\uff09\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"shellQuote"),"\uff1a\u5f15\u7528\u4e00\u4e2a\u5b57\u7b26\u4e32\u4ee5\u4f7f\u5176\u5728 shell \u811a\u672c\u4e2d\u5b89\u5168\u4f7f\u7528\u3002 Task \u4e3a\u6b64\u4f7f\u7528\u4e86 ",(0,l.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote"},"\u8fd9\u4e2a Go \u51fd\u6570"),"\u3002 \u5047\u5b9a\u4f7f\u7528 Bash \u8bed\u6cd5\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"splitArgs"),"\uff1a\u5c06\u5b57\u7b26\u4e32\u4f5c\u4e3a\u547d\u4ee4\u7684\u53c2\u6570\u8fdb\u884c\u62c6\u5206\u3002 Task \u4f7f\u7528 ",(0,l.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/shell#Fields"},"\u8fd9\u4e2a Go \u51fd\u6570"))),(0,l.kt)("p",null,"\u793a\u4f8b\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u5e2e\u52a9"},"\u5e2e\u52a9"),(0,l.kt)("p",null,"\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"task --list"),"\uff08\u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"task -l"),"\uff09\u5217\u51fa\u6240\u6709\u5e26\u6709\u63cf\u8ff0\u7684\u4efb\u52a1\u3002 \u4ee5\u4e0b Taskfile\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5c06\u6253\u5370\u4ee5\u4e0b\u8f93\u51fa\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"* build: Build the go binary.\n* test: Run all the go tests.\n")),(0,l.kt)("p",null,"\u5982\u679c\u60a8\u60f3\u67e5\u770b\u6240\u6709\u4efb\u52a1\uff0c\u8fd8\u6709\u4e00\u4e2a ",(0,l.kt)("inlineCode",{parentName:"p"},"--list-all"),"\uff08\u522b\u540d ",(0,l.kt)("inlineCode",{parentName:"p"},"-a"),"\uff09\u6807\u5fd7\u3002"),(0,l.kt)("h2",{id:"\u663e\u793a\u4efb\u52a1\u6458\u8981"},"\u663e\u793a\u4efb\u52a1\u6458\u8981"),(0,l.kt)("p",null,"\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"task --summary task-name")," \u5c06\u663e\u793a\u4efb\u52a1\u7684\u6458\u8981\u3002 \u4ee5\u4e0b Taskfile\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"task --summary release")," \u5c06\u6253\u5370\u4ee5\u4e0b\u8f93\u51fa\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5982\u679c\u7f3a\u5c11\u6458\u8981\uff0c\u5c06\u6253\u5370\u63cf\u8ff0\u3002 \u5982\u679c\u4efb\u52a1\u6ca1\u6709\u6458\u8981\u6216\u63cf\u8ff0\uff0c\u5219\u4f1a\u6253\u5370\u4e00\u6761\u8b66\u544a\u3002"),(0,l.kt)("p",null,"\u8bf7\u6ce8\u610f\uff1a",(0,l.kt)("em",{parentName:"p"},"\u663e\u793a\u6458\u8981\u4e0d\u4f1a\u6267\u884c\u547d\u4ee4"),"\u3002"),(0,l.kt)("h2",{id:"task-\u522b\u540d"},"Task \u522b\u540d"),(0,l.kt)("p",null,"Aliases \u662f task \u7684\u66ff\u4ee3\u540d\u79f0\u3002 \u5b83\u4eec\u53ef\u4ee5\u4f7f\u8fd0\u884c\u5177\u6709\u957f\u540d\u79f0\u6216\u96be\u4ee5\u952e\u5165\u540d\u79f0\u7684 task \u53d8\u5f97\u66f4\u52a0\u5bb9\u6613\u548c\u5feb\u901f\u3002 \u60a8\u53ef\u4ee5\u5728\u547d\u4ee4\u884c\u4e0a\u4f7f\u7528\u5b83\u4eec\uff0c\u5728\u60a8\u7684 Taskfile \u4e2d ",(0,l.kt)("a",{parentName:"p",href:"#%E8%B0%83%E7%94%A8%E5%8F%A6%E4%B8%80%E4%B8%AA-task"},"\u8c03\u7528\u5b50\u4efb\u52a1")," \u65f6\u4ee5\u53ca\u5728 ",(0,l.kt)("a",{parentName:"p",href:"#%E5%8C%85%E5%90%AB%E5%85%B6%E4%BB%96-taskfile"},"\u5305\u542b\u6765\u81ea\u53e6\u4e00\u4e2a Taskfile")," \u7684\u522b\u540d task \u65f6\u3002 \u5b83\u4eec\u4e5f\u53ef\u4ee5\u4e0e ",(0,l.kt)("a",{parentName:"p",href:"#%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E5%88%AB%E5%90%8D"},"\u547d\u540d\u7a7a\u95f4\u522b\u540d")," \u4e00\u8d77\u4f7f\u7528\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u8986\u76d6-task-\u540d\u79f0"},"\u8986\u76d6 Task \u540d\u79f0"),(0,l.kt)("p",null,"\u6709\u65f6\u4f60\u53ef\u80fd\u60f3\u8986\u76d6\u6253\u5370\u5728\u6458\u8981\u4e0a\u7684 task \u540d\u79f0\uff0c\u6700\u65b0\u6d88\u606f\u5230 STDOUT \u7b49\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u53ef\u4ee5\u53ea\u8bbe\u7f6e ",(0,l.kt)("inlineCode",{parentName:"p"},"label:"),"\uff0c\u4e5f\u53ef\u4ee5\u7528\u53d8\u91cf\u8fdb\u884c\u63d2\u503c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u9759\u9ed8\u6a21\u5f0f"},"\u9759\u9ed8\u6a21\u5f0f"),(0,l.kt)("p",null,"\u9759\u9ed8\u6a21\u5f0f\u5728 Task \u8fd0\u884c\u547d\u4ee4\u4e4b\u524d\u7981\u7528\u547d\u4ee4\u56de\u663e\u3002 \u5bf9\u4e8e\u4ee5\u4e0b Taskfile\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n")),(0,l.kt)("p",null,"\u901a\u5e38\u8fd9\u5c06\u6253\u5370\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},'echo "Print something"\nPrint something\n')),(0,l.kt)("p",null,"\u5f00\u542f\u9759\u9ed8\u6a21\u5f0f\u540e\uff0c\u5c06\u6253\u5370\u4ee5\u4e0b\u5185\u5bb9\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"Print something\n")),(0,l.kt)("p",null,"\u5f00\u542f\u9759\u9ed8\u6a21\u5f0f\u6709\u56db\u79cd\u65b9\u5f0f\uff1a"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\u5728 cmds \u7ea7\u522b\uff1a")),(0,l.kt)("pre",null,(0,l.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,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\u5728 task \u7ea7\u522b\uff1a")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n silent: true\n")),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\u5728 Taskfile \u5168\u5c40\u7ea7\u522b\uff1a")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nsilent: true\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n")),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\u6216\u8005\u5168\u5c40\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"li"},"--silent")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"li"},"-s")," \u6807\u5fd7")),(0,l.kt)("p",null,"\u5982\u679c\u60a8\u60f3\u6539\u4e3a\u7981\u6b62 STDOUT\uff0c\u53ea\u9700\u5c06\u547d\u4ee4\u91cd\u5b9a\u5411\u5230 ",(0,l.kt)("inlineCode",{parentName:"p"},"/dev/null"),"\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u8bd5\u8fd0\u884c\u6a21\u5f0f"},"\u8bd5\u8fd0\u884c\u6a21\u5f0f"),(0,l.kt)("p",null,"\u8bd5\u8fd0\u884c\u6a21\u5f0f (",(0,l.kt)("inlineCode",{parentName:"p"},"--dry"),") \u7f16\u8bd1\u5e76\u9010\u6b65\u5b8c\u6210\u6bcf\u4e2a task\uff0c\u6253\u5370\u5c06\u8fd0\u884c\u4f46\u4e0d\u6267\u884c\u5b83\u4eec\u7684\u547d\u4ee4\u3002 \u8fd9\u5bf9\u4e8e\u8c03\u8bd5\u60a8\u7684 Taskfile \u5f88\u6709\u7528\u3002"),(0,l.kt)("h2",{id:"\u5ffd\u7565\u9519\u8bef"},"\u5ffd\u7565\u9519\u8bef"),(0,l.kt)("p",null,"\u60a8\u53ef\u4ee5\u9009\u62e9\u5728\u547d\u4ee4\u6267\u884c\u671f\u95f4\u5ffd\u7565\u9519\u8bef\u3002 \u7ed9\u5b9a\u4ee5\u4e0b Taskfile\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - exit 1\n - echo \"Hello World\"\n")),(0,l.kt)("p",null,"Task \u5c06\u5728\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"exit 1")," \u540e\u4e2d\u6b62\u6267\u884c\uff0c\u56e0\u4e3a\u72b6\u6001\u4ee3\u7801 ",(0,l.kt)("inlineCode",{parentName:"p"},"1")," \u4ee3\u8868 ",(0,l.kt)("inlineCode",{parentName:"p"},"EXIT_FAILURE"),"\u3002 \u4f46\u662f\uff0c\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"ignore_error")," \u7ee7\u7eed\u6267\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4e5f\u53ef\u4ee5\u4e3a task \u8bbe\u7f6e ",(0,l.kt)("inlineCode",{parentName:"p"},"ignore_error"),"\uff0c\u8fd9\u610f\u5473\u7740\u6240\u6709\u547d\u4ee4\u7684\u9519\u8bef\u90fd\u5c06\u88ab\u5ffd\u7565\u3002 \u4e0d\u8fc7\uff0c\u8bf7\u8bb0\u4f4f\uff0c\u6b64\u9009\u9879\u4e0d\u4f1a\u4f20\u64ad\u5230\u7531 deps \u6216 cmds \u8c03\u7528\u7684\u5176\u4ed6 task\uff01"),(0,l.kt)("h2",{id:"\u8f93\u51fa\u8bed\u6cd5"},"\u8f93\u51fa\u8bed\u6cd5"),(0,l.kt)("p",null,"\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cTask \u53ea\u662f\u5c06\u6b63\u5728\u8fd0\u884c\u7684\u547d\u4ee4\u7684 STDOUT \u548c STDERR \u5b9e\u65f6\u91cd\u5b9a\u5411\u5230 shell\u3002 \u8fd9\u6709\u5229\u4e8e\u901a\u8fc7\u547d\u4ee4\u6253\u5370\u65e5\u5fd7\u8bb0\u5f55\u7684\u5b9e\u65f6\u53cd\u9988\uff0c\u4f46\u5982\u679c\u540c\u65f6\u8fd0\u884c\u591a\u4e2a\u547d\u4ee4\u5e76\u6253\u5370\u5927\u91cf\u5185\u5bb9\uff0c\u8f93\u51fa\u53ef\u80fd\u4f1a\u53d8\u5f97\u6df7\u4e71\u3002"),(0,l.kt)("p",null,"\u4e3a\u4e86\u4f7f\u5176\u66f4\u5177\u53ef\u5b9a\u5236\u6027\uff0c\u76ee\u524d\u60a8\u53ef\u4ee5\u9009\u62e9\u4e09\u79cd\u4e0d\u540c\u7684\u8f93\u51fa\u9009\u9879\uff1a"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"interleaved")," (\u9ed8\u8ba4)"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"group")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"prefixed"))),(0,l.kt)("p",null,"\u8981\u9009\u62e9\u53e6\u4e00\u4e2a\uff0c\u53ea\u9700\u5728 Taskfile \u6839\u76ee\u5f55\u4e2d\u8bbe\u7f6e\u5373\u53ef\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\noutput: 'group'\n\ntasks:\n # ...\n")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"group")," \u8f93\u51fa\u5c06\u5728\u547d\u4ee4\u5b8c\u6210\u540e\u6253\u5370\u4e00\u6b21\u547d\u4ee4\u7684\u5168\u90e8\u8f93\u51fa\uff0c\u56e0\u6b64\u60a8\u4e0d\u4f1a\u5bf9\u9700\u8981\u5f88\u957f\u65f6\u95f4\u8fd0\u884c\u7684\u547d\u4ee4\u6709\u5b9e\u65f6\u53cd\u9988\u3002"),(0,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"group")," \u8f93\u51fa\u65f6\uff0c\u60a8\u53ef\u4ee5\u9009\u62e9\u63d0\u4f9b\u6a21\u677f\u5316\u6d88\u606f\u4ee5\u5728\u7ec4\u7684\u5f00\u59cb\u548c\u7ed3\u675f\u5904\u6253\u5370\u3002 \u8fd9\u5bf9\u4e8e\u6307\u793a CI \u7cfb\u7edf\u5bf9\u7ed9\u5b9a\u4efb\u52a1\u7684\u6240\u6709\u8f93\u51fa\u8fdb\u884c\u5206\u7ec4\u975e\u5e38\u6709\u7528\uff0c\u4f8b\u5982\u4f7f\u7528 ",(0,l.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#grouping-log-lines"},"GitHub Actions \u7684 ",(0,l.kt)("inlineCode",{parentName:"a"},"::group::")," \u547d\u4ee4")," \u6216 ",(0,l.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"),"\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"$ task default\n::group::default\nHello, World!\n::endgroup::\n")),(0,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"group")," \u8f93\u51fa\u65f6\uff0c\u5982\u679c\u6ca1\u6709\u5931\u8d25\uff08\u96f6\u9000\u51fa\u4ee3\u7801\uff09\uff0c\u60a8\u53ef\u4ee5\u5728\u6807\u51c6\u8f93\u51fa\u548c\u6807\u51c6\u9519\u8bef\u4e0a\u6267\u884c\u547d\u4ee4\u7684\u8f93\u51fa\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("pre",null,(0,l.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,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"prefix")," \u8f93\u51fa\u5c06\u4e3a\u547d\u4ee4\u6253\u5370\u7684\u6bcf\u4e00\u884c\u6dfb\u52a0\u524d\u7f00 ",(0,l.kt)("inlineCode",{parentName:"p"},"[task-name]")," \u4f5c\u4e3a\u524d\u7f00\uff0c\u4f46\u60a8\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"prefix:")," \u5c5e\u6027\u81ea\u5b9a\u4e49\u547d\u4ee4\u7684\u524d\u7f00\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"$ task default\n[print-foo] foo\n[print-bar] bar\n[print-baz] baz\n")),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},(0,l.kt)("inlineCode",{parentName:"p"},"output")," \u9009\u9879\u4e5f\u53ef\u4ee5\u7531 ",(0,l.kt)("inlineCode",{parentName:"p"},"--output")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"-o")," \u6807\u5fd7\u6307\u5b9a\u3002")),(0,l.kt)("h2",{id:"\u4ea4\u4e92\u5f0f-cli-\u5e94\u7528"},"\u4ea4\u4e92\u5f0f CLI \u5e94\u7528"),(0,l.kt)("p",null,"Task \u6267\u884c\u5305\u542b\u4ea4\u4e92\u5f0f\u7684\u547d\u4ee4\u65f6\u6709\u65f6\u4f1a\u51fa\u73b0\u5947\u602a\u7684\u7ed3\u679c\uff0c \u5c24\u5176\u5f53 ",(0,l.kt)("a",{parentName:"p",href:"#%E8%BE%93%E5%87%BA%E8%AF%AD%E6%B3%95"},"\u8f93\u51fa\u6a21\u5f0f")," \u8bbe\u7f6e\u7684\u4e0d\u662f ",(0,l.kt)("inlineCode",{parentName:"p"},"interleaved")," \uff08\u9ed8\u8ba4\uff09\uff0c \u6216\u8005\u5f53\u4ea4\u4e92\u5f0f\u5e94\u7528\u4e0e\u5176\u5b83 task \u5e76\u53d1\u6267\u884c\u65f6\u3002"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"interactive: true")," \u544a\u8bc9 Task \u8fd9\u662f\u4e00\u4e2a\u4ea4\u4e92\u5f0f\u5e94\u7528\u7a0b\u5e8f\uff0cTask \u5c06\u5c1d\u8bd5\u9488\u5bf9\u5b83\u8fdb\u884c\u4f18\u5316\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5982\u679c\u60a8\u5728\u901a\u8fc7 Task \u8fd0\u884c\u4ea4\u4e92\u5f0f\u5e94\u7528\u7a0b\u5e8f\u65f6\u4ecd\u7136\u9047\u5230\u95ee\u9898\uff0c\u8bf7\u6253\u5f00\u4e00\u4e2a\u5173\u4e8e\u5b83\u7684 Issue\u3002"),(0,l.kt)("h2",{id:"\u77ed-task-\u8bed\u6cd5"},"\u77ed Task \u8bed\u6cd5"),(0,l.kt)("p",null,"\u4ece Task v3 \u5f00\u59cb\uff0c\u5982\u679c task \u5177\u6709\u9ed8\u8ba4\u8bbe\u7f6e\uff08\u4f8b\u5982\uff1a\u6ca1\u6709\u81ea\u5b9a\u4e49 ",(0,l.kt)("inlineCode",{parentName:"p"},"env:"),"\u3001",(0,l.kt)("inlineCode",{parentName:"p"},"vars:"),"\u3001",(0,l.kt)("inlineCode",{parentName:"p"},"desc:"),"\u3001",(0,l.kt)("inlineCode",{parentName:"p"},"silent:")," \u7b49\uff09\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u4f7f\u7528\u66f4\u77ed\u7684\u8bed\u6cd5\u7f16\u5199task\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"set-\u548c-shopt"},(0,l.kt)("inlineCode",{parentName:"h2"},"set")," \u548c ",(0,l.kt)("inlineCode",{parentName:"h2"},"shopt")),(0,l.kt)("p",null,"\u53ef\u4ee5\u4e3a ",(0,l.kt)("a",{parentName:"p",href:"https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html"},(0,l.kt)("inlineCode",{parentName:"a"},"set"))," \u548c ",(0,l.kt)("a",{parentName:"p",href:"https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html"},(0,l.kt)("inlineCode",{parentName:"a"},"shopt"))," \u5185\u7f6e\u51fd\u6570\u6307\u5b9a\u9009\u9879\u3002 \u8fd9\u53ef\u4ee5\u5728\u5168\u5c40\u3001task \u6216\u547d\u4ee4\u7ea7\u522b\u6dfb\u52a0\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u8bf7\u8bb0\u4f4f\uff0c\u5e76\u975e\u6240\u6709\u9009\u9879\u5728 Task \u4f7f\u7528\u7684 ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/mvdan/sh"},"shell \u89e3\u91ca\u5668\u5e93")," \u4e2d\u90fd\u53ef\u7528\u3002")),(0,l.kt)("h2",{id:"\u89c2\u5bdf-task"},"\u89c2\u5bdf task"),(0,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"--watch")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"-w")," \u53c2\u6570\u53ef\u4ee5\u89c2\u5bdf\u6587\u4ef6\u53d8\u5316\uff0c\u7136\u540e\u91cd\u65b0\u6267\u884c task\u3002 \u8fd9\u9700\u8981\u914d\u7f6e ",(0,l.kt)("inlineCode",{parentName:"p"},"sources")," \u5c5e\u6027\uff0ctask \u624d\u77e5\u9053\u89c2\u5bdf\u54ea\u4e9b\u6587\u4ef6\u3002"),(0,l.kt)("p",null,"\u9ed8\u8ba4\u76d1\u63a7\u7684\u65f6\u95f4\u95f4\u9694\u662f 5 \u79d2\uff0c\u4f46\u53ef\u4ee5\u901a\u8fc7 Taskfile \u4e2d\u6839\u5c5e\u6027 ",(0,l.kt)("inlineCode",{parentName:"p"},"interval: '500ms'")," \u8bbe\u7f6e\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4\u884c \u53c2\u6570 ",(0,l.kt)("inlineCode",{parentName:"p"},"--interval=500ms")," \u8bbe\u7f6e\u3002"))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/zh-Hans/assets/js/01713e21.c7d3f8fb.js b/zh-Hans/assets/js/01713e21.c7d3f8fb.js new file mode 100644 index 00000000..8fcdc165 --- /dev/null +++ b/zh-Hans/assets/js/01713e21.c7d3f8fb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[701],{3905:function(e,n,t){t.d(n,{Zo:function(){return o},kt:function(){return c}});var a=t(7294);function l(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(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||(l[t]=e[t]);return l}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(l[t]=e[t])}return l}var p=a.createContext({}),k=function(e){var n=a.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},o=function(e){var n=k(e.components);return a.createElement(p.Provider,{value:n},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,l=e.mdxType,s=e.originalType,p=e.parentName,o=r(e,["components","mdxType","originalType","parentName"]),m=k(t),u=l,c=m["".concat(p,".").concat(u)]||m[u]||d[u]||s;return t?a.createElement(c,i(i({ref:n},o),{},{components:t})):a.createElement(c,i({ref:n},o))}));function c(e,n){var t=arguments,l=n&&n.mdxType;if("string"==typeof e||l){var s=t.length,i=new Array(s);i[0]=u;var r={};for(var p in n)hasOwnProperty.call(n,p)&&(r[p]=n[p]);r.originalType=e,r[m]="string"==typeof e?e:l,i[1]=r;for(var k=2;kdefer \u505a task \u6e05\u7406",id:"\u4f7f\u7528-defer-\u505a-task-\u6e05\u7406",level:2},{value:"Go \u7684\u6a21\u677f\u5f15\u64ce",id:"go-\u7684\u6a21\u677f\u5f15\u64ce",level:2},{value:"\u5e2e\u52a9",id:"\u5e2e\u52a9",level:2},{value:"\u663e\u793a\u4efb\u52a1\u6458\u8981",id:"\u663e\u793a\u4efb\u52a1\u6458\u8981",level:2},{value:"Task \u522b\u540d",id:"task-\u522b\u540d",level:2},{value:"\u8986\u76d6 Task \u540d\u79f0",id:"\u8986\u76d6-task-\u540d\u79f0",level:2},{value:"\u9759\u9ed8\u6a21\u5f0f",id:"\u9759\u9ed8\u6a21\u5f0f",level:2},{value:"\u8bd5\u8fd0\u884c\u6a21\u5f0f",id:"\u8bd5\u8fd0\u884c\u6a21\u5f0f",level:2},{value:"\u5ffd\u7565\u9519\u8bef",id:"\u5ffd\u7565\u9519\u8bef",level:2},{value:"\u8f93\u51fa\u8bed\u6cd5",id:"\u8f93\u51fa\u8bed\u6cd5",level:2},{value:"\u4ea4\u4e92\u5f0f CLI \u5e94\u7528",id:"\u4ea4\u4e92\u5f0f-cli-\u5e94\u7528",level:2},{value:"\u77ed Task \u8bed\u6cd5",id:"\u77ed-task-\u8bed\u6cd5",level:2},{value:"set \u548c shopt",id:"set-\u548c-shopt",level:2},{value:"\u89c2\u5bdf task",id:"\u89c2\u5bdf-task",level:2}],o={toc:k};function m(e){let{components:n,...t}=e;return(0,l.kt)("wrapper",(0,a.Z)({},o,t,{components:n,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"\u4f7f\u7528\u6307\u5357"},"\u4f7f\u7528\u6307\u5357"),(0,l.kt)("h2",{id:"\u5feb\u901f\u5165\u95e8"},"\u5feb\u901f\u5165\u95e8"),(0,l.kt)("p",null,"\u5728\u9879\u76ee\u7684\u6839\u76ee\u5f55\u4e2d\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a ",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," \u7684\u6587\u4ef6\u3002 ",(0,l.kt)("inlineCode",{parentName:"p"},"cmds")," \u5c5e\u6027\u5e94\u5305\u542b task \u7684\u547d\u4ee4\u3002 \u4e0b\u9762\u7684\u793a\u4f8b\u5141\u8bb8\u7f16\u8bd1 Go \u5e94\u7528\u7a0b\u5e8f\u5e76\u4f7f\u7528 ",(0,l.kt)("a",{parentName:"p",href:"https://esbuild.github.io/"},"esbuild")," \u5c06\u591a\u4e2a CSS \u6587\u4ef6\u5408\u5e76\u5e76\u7f29\u5c0f\u4e3a\u4e00\u4e2a\u6587\u4ef6\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u8fd0\u884c task \u5c31\u8fd9\u6837\u7b80\u5355\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"task assets build\n")),(0,l.kt)("p",null,"Task \u4f7f\u7528 ",(0,l.kt)("a",{parentName:"p",href:"https://mvdan.cc/sh/"},"mvdan.cc/sh"),"\uff0c\u4e00\u4e2a\u539f\u751f\u7684 Go sh \u89e3\u91ca\u5668\u3002 \u56e0\u6b64\uff0c\u60a8\u53ef\u4ee5\u7f16\u5199 sh/bash \u547d\u4ee4\uff0c\u5b83\u751a\u81f3\u53ef\u4ee5\u5728 Windows \u4e0a\u8fd0\u884c\uff0c\u800c ",(0,l.kt)("inlineCode",{parentName:"p"},"sh")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"bash")," \u901a\u5e38\u4e0d\u53ef\u7528\u3002 \u8bf7\u8bb0\u4f4f\uff0c\u4efb\u4f55\u88ab\u8c03\u7528\u7684\u53ef\u6267\u884c\u6587\u4ef6\u90fd\u5fc5\u987b\u5728\u64cd\u4f5c\u7cfb\u7edf\u6216 PATH \u4e2d\u53ef\u7528\u3002"),(0,l.kt)("p",null,'\u5982\u679c\u4e0d\u4f20 task \u7684\u540d\u5b57\uff0c\u9ed8\u8ba4\u4f1a\u8c03\u7528 "default"\u3002'),(0,l.kt)("h2",{id:"\u652f\u6301\u7684\u6587\u4ef6\u540d\u79f0"},"\u652f\u6301\u7684\u6587\u4ef6\u540d\u79f0"),(0,l.kt)("p",null,"Task \u4f1a\u6309\u4ee5\u4e0b\u987a\u5e8f\u67e5\u627e\u914d\u7f6e\u6587\u4ef6:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Taskfile.yml"),(0,l.kt)("li",{parentName:"ul"},"Taskfile.yaml"),(0,l.kt)("li",{parentName:"ul"},"Taskfile.dist.yml"),(0,l.kt)("li",{parentName:"ul"},"Taskfile.dist.yaml")),(0,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},".dist")," \u53d8\u4f53\u7684\u76ee\u7684\u662f\u5141\u8bb8\u9879\u76ee\u6709\u4e00\u4e2a\u63d0\u4ea4\u7248\u672c (",(0,l.kt)("inlineCode",{parentName:"p"},".dist"),")\uff0c\u540c\u65f6\u4ecd\u7136\u5141\u8bb8\u4e2a\u4eba\u7528\u6237\u901a\u8fc7\u6dfb\u52a0\u989d\u5916\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile.yml"),"\uff08\u5c06\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},".gitignore")," \u4e0a\uff09\u6765\u8986\u76d6 Taskfile\u3002"),(0,l.kt)("h3",{id:"\u4ece\u5b50\u76ee\u5f55\u8fd0\u884c-taskfile"},"\u4ece\u5b50\u76ee\u5f55\u8fd0\u884c Taskfile"),(0,l.kt)("p",null,"\u5982\u679c\u5728\u5f53\u524d\u5de5\u4f5c\u76ee\u5f55\u4e2d\u627e\u4e0d\u5230 Taskfile\uff0c\u5b83\u5c06\u6cbf\u7740\u6587\u4ef6\u6811\u5411\u4e0a\u67e5\u627e\uff0c\u76f4\u5230\u627e\u5230\u4e00\u4e2a\uff08\u7c7b\u4f3c\u4e8e ",(0,l.kt)("inlineCode",{parentName:"p"},"git")," \u7684\u5de5\u4f5c\u65b9\u5f0f\uff09\u3002 \u5f53\u4ece\u8fd9\u6837\u7684\u5b50\u76ee\u5f55\u8fd0\u884c Task \u65f6\uff0c\u5b83\u7684\u884c\u4e3a\u5c31\u50cf\u4ece\u5305\u542b Taskfile \u7684\u76ee\u5f55\u8fd0\u884c\u5b83\u4e00\u6837\u3002"),(0,l.kt)("p",null,"\u60a8\u53ef\u4ee5\u5c06\u6b64\u529f\u80fd\u4e0e\u7279\u6b8a\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}")," \u53d8\u91cf\u4e00\u8d77\u4f7f\u7528\u6765\u521b\u5efa\u4e00\u4e9b\u975e\u5e38\u6709\u7528\u7684\u53ef\u91cd\u7528 task\u3002 \u4f8b\u5982\uff0c\u5982\u679c\u4f60\u6709\u4e00\u4e2a\u5305\u542b\u6bcf\u4e2a\u5fae\u670d\u52a1\u76ee\u5f55\u7684 monorepo\uff0c\u4f60\u53ef\u4ee5 ",(0,l.kt)("inlineCode",{parentName:"p"},"cd")," \u8fdb\u5165\u4e00\u4e2a\u5fae\u670d\u52a1\u76ee\u5f55\u5e76\u8fd0\u884c\u4e00\u4e2a task \u547d\u4ee4\u6765\u542f\u52a8\u5b83\uff0c\u800c\u4e0d\u5fc5\u521b\u5efa\u591a\u4e2a task \u6216\u5177\u6709\u76f8\u540c\u5185\u5bb9\u7684 Taskfile\u3002 \u4f8b\u5982\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5728\u6b64\u793a\u4f8b\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"cd ")," \u548c ",(0,l.kt)("inlineCode",{parentName:"p"},"task up"),"\uff0c\u53ea\u8981 ",(0,l.kt)("inlineCode",{parentName:"p"},"")," \u76ee\u5f55\u5305\u542b ",(0,l.kt)("inlineCode",{parentName:"p"},"docker-compose.yml"),"\uff0c\u5c31\u4f1a\u542f\u52a8 Docker Compose\u3002"),(0,l.kt)("h3",{id:"\u8fd0\u884c\u5168\u5c40-taskfile"},"\u8fd0\u884c\u5168\u5c40 Taskfile"),(0,l.kt)("p",null,"\u5982\u679c\u60a8\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"--global"),"\uff08\u522b\u540d ",(0,l.kt)("inlineCode",{parentName:"p"},"-g"),"\uff09\u6807\u5fd7\u8c03\u7528 Task\uff0c\u5b83\u5c06\u67e5\u627e\u60a8\u7684 home \u76ee\u5f55\u800c\u4e0d\u662f\u60a8\u7684\u5de5\u4f5c\u76ee\u5f55\u3002 \u7b80\u800c\u8a00\u4e4b\uff0cTask \u5c06\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yml")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"$HOME/Taskfile.yaml")," \u8def\u5f84\u4e0a\u5bfb\u627e Taskfile\u3002"),(0,l.kt)("p",null,"\u8fd9\u5bf9\u4e8e\u60a8\u53ef\u4ee5\u5728\u7cfb\u7edf\u7684\u4efb\u4f55\u5730\u65b9\u8fd0\u884c\u7684\u81ea\u52a8\u5316\u5f88\u6709\u7528\uff01"),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u5f53\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"-g")," \u8fd0\u884c\u5168\u5c40 Taskfile \u65f6\uff0ctask \u5c06\u9ed8\u8ba4\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},"$HOME")," \u4e0a\u8fd0\u884c\uff0c\u800c\u4e0d\u662f\u5728\u60a8\u7684\u5de5\u4f5c\u76ee\u5f55\u4e0a\uff01"),(0,l.kt)("p",{parentName:"admonition"},"\u5982\u524d\u4e00\u8282\u6240\u8ff0\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"{{.USER_WORKING_DIR}}")," \u7279\u6b8a\u53d8\u91cf\u5728\u8fd9\u91cc\u53ef\u4ee5\u975e\u5e38\u65b9\u4fbf\u5730\u5728\u60a8\u4ece\u4e2d\u8c03\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"task -g")," \u7684\u76ee\u5f55\u4e2d\u8fd0\u884c\u5185\u5bb9\u3002"),(0,l.kt)("pre",{parentName:"admonition"},(0,l.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,l.kt)("h2",{id:"\u73af\u5883\u53d8\u91cf"},"\u73af\u5883\u53d8\u91cf"),(0,l.kt)("h3",{id:"task"},"Task"),(0,l.kt)("p",null,"\u4f60\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"env")," \u7ed9\u6bcf\u4e2a task \u8bbe\u7f6e\u81ea\u5b9a\u4e49\u73af\u5883\u53d8\u91cf:"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u6b64\u5916\uff0c\u60a8\u53ef\u4ee5\u8bbe\u7f6e\u53ef\u7528\u4e8e\u6240\u6709 task \u7684\u5168\u5c40\u73af\u5883\u53d8\u91cf\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},(0,l.kt)("inlineCode",{parentName:"p"},"env")," \u652f\u6301\u6269\u5c55\u548c\u68c0\u7d22 shell \u547d\u4ee4\u7684\u8f93\u51fa\uff0c\u5c31\u50cf\u53d8\u91cf\u4e00\u6837\uff0c\u5982\u60a8\u5728 ",(0,l.kt)("a",{parentName:"p",href:"#%E5%8F%98%E9%87%8F"},"\u53d8\u91cf")," \u90e8\u5206\u4e2d\u770b\u5230\u7684\u90a3\u6837\u3002")),(0,l.kt)("h3",{id:"env-\u6587\u4ef6"},".env \u6587\u4ef6"),(0,l.kt)("p",null,"\u60a8\u8fd8\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"dotenv:")," \u8bbe\u7f6e\u8981\u6c42 tasks \u5305\u542b ",(0,l.kt)("inlineCode",{parentName:"p"},".env")," \u4e4b\u7c7b\u7684\u6587\u4ef6"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title=".env"',title:'".env"'},"KEYNAME=VALUE\n")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title="testing/.env"',title:'"testing/.env"'},"ENDPOINT=testing.com\n")),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4e5f\u53ef\u4ee5\u5728 task \u7ea7\u522b\u6307\u5b9a .env \u6587\u4ef6\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5728 task \u7ea7\u522b\u660e\u786e\u6307\u5b9a\u7684\u73af\u5883\u53d8\u91cf\u5c06\u8986\u76d6\u70b9\u6587\u4ef6\u4e2d\u5b9a\u4e49\u7684\u53d8\u91cf\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u8bf7\u6ce8\u610f\uff0c\u60a8\u76ee\u524d\u65e0\u6cd5\u5728\u5305\u542b\u7684 Taskfile \u4e2d\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"dotenv")," \u952e\u3002")),(0,l.kt)("h2",{id:"\u5305\u542b\u5176\u4ed6-taskfile"},"\u5305\u542b\u5176\u4ed6 Taskfile"),(0,l.kt)("p",null,"\u5982\u679c\u8981\u5728\u4e0d\u540c\u9879\u76ee\uff08Taskfile\uff09\u4e4b\u95f4\u5171\u4eab\u4efb\u52a1\uff0c\u53ef\u4ee5\u4f7f\u7528\u5bfc\u5165\u673a\u5236\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"includes")," \u5173\u952e\u5b57\u5305\u542b\u5176\u4ed6\u4efb\u52a1\u6587\u4ef6\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u7ed9\u5b9a\u7684 Taskfile \u4e2d\u63cf\u8ff0\u7684\u4efb\u52a1\u5c06\u5728\u6307\u5b9a\u7684\u547d\u540d\u7a7a\u95f4\u4e2d\u63d0\u4f9b\u3002 \u56e0\u6b64\uff0c\u60a8\u53ef\u4ee5\u8c03\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"task docs:serve")," \u4ece ",(0,l.kt)("inlineCode",{parentName:"p"},"documentation/Taskfile.yml")," \u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"serve")," task\uff0c\u6216\u8005\u8c03\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"task docker:build")," \u4ece ",(0,l.kt)("inlineCode",{parentName:"p"},"DockerTasks.yml")," \u6587\u4ef6\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"build")," task\u3002"),(0,l.kt)("p",null,"\u76f8\u5bf9\u8def\u5f84\u662f\u76f8\u5bf9\u4e8e\u5305\u542b\u5305\u542b Taskfile \u7684\u76ee\u5f55\u89e3\u6790\u7684\u3002"),(0,l.kt)("h3",{id:"\u64cd\u4f5c\u7cfb\u7edf\u7279\u5b9a-taskfile"},"\u64cd\u4f5c\u7cfb\u7edf\u7279\u5b9a Taskfile"),(0,l.kt)("p",null,"\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},"version: '2'")," \u4e2d\uff0ctask \u4f1a\u81ea\u52a8\u5c1d\u8bd5\u5f15\u5165 ",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile_{{OS}}.yml")," \u6587\u4ef6 \uff08\u4f8b\u5982",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile_windows.yml"),", ",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile_linux.yml")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile_darwin.yml"),"\uff09\u3002 \u4f46\u662f\u56e0\u4e3a\u8fc7\u4e8e\u9690\u6666\uff0c\u5728\u7248\u672c 3 \u4e2d\u88ab\u79fb\u9664\u4e86\uff0c \u5728\u7248\u672c 3 \u53ef\u4ee5\u901a\u8fc7\u660e\u786e\u7684\u5f15\u7528\u6765\u5b9e\u73b0\u7c7b\u4f3c\u529f\u80fd:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n build: ./Taskfile_{{OS}}.yml\n")),(0,l.kt)("h3",{id:"\u5305\u542b-taskfile-\u7684\u76ee\u5f55"},"\u5305\u542b Taskfile \u7684\u76ee\u5f55"),(0,l.kt)("p",null,"\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0c\u5305\u542b\u7684 Taskfile \u7684 task \u5728\u5f53\u524d\u76ee\u5f55\u4e2d\u8fd0\u884c\uff0c\u5373\u4f7f Taskfile \u5728\u53e6\u4e00\u4e2a\u76ee\u5f55\u4e2d\uff0c\u4f46\u60a8\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u66ff\u4ee3\u8bed\u6cd5\u5f3a\u5236\u5176 task \u5728\u53e6\u4e00\u4e2a\u76ee\u5f55\u4e2d\u8fd0\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n docs:\n taskfile: ./docs/Taskfile.yml\n dir: ./docs\n")),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u5305\u542b\u7684 Taskfile \u5fc5\u987b\u4f7f\u7528\u4e0e\u4e3b Taskfile \u4f7f\u7528\u7684\u76f8\u540c\u89c4\u5219\u7248\u672c\u3002")),(0,l.kt)("h3",{id:"\u53ef\u9009-includes"},"\u53ef\u9009 includes"),(0,l.kt)("p",null,"\u5982\u679c\u5305\u542b\u6587\u4ef6\u4e22\u5931\uff0c\u6807\u8bb0\u4e3a\u53ef\u9009\u7684\u5305\u542b\u5c06\u5141\u8bb8 task \u7ee7\u7eed\u6b63\u5e38\u6267\u884c\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h3",{id:"\u5185\u90e8-includes"},"\u5185\u90e8 includes"),(0,l.kt)("p",null,"\u6807\u8bb0\u4e3a internal \u7684\u5305\u542b\u4f1a\u5c06\u5305\u542b\u6587\u4ef6\u7684\u6240\u6709 task \u4e5f\u8bbe\u7f6e\u4e3a\u5185\u90e8 task\uff08\u8bf7\u53c2\u9605\u4e0b\u9762\u7684 ",(0,l.kt)("a",{parentName:"p",href:"#%E5%86%85%E9%83%A8-tasks"},"\u5185\u90e8-tasks")," \u90e8\u5206\uff09\u3002 \u8fd9\u5728\u5305\u542b\u4e0d\u6253\u7b97\u7531\u7528\u6237\u76f4\u63a5\u4f7f\u7528\u7684\u5b9e\u7528\u7a0b\u5e8f\u4efb\u52a1\u65f6\u5f88\u6709\u7528\u3002"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n tests:\n taskfile: ./taskfiles/Utils.yml\n internal: true\n")),(0,l.kt)("h3",{id:"\u5305\u542b-taskfile-\u7684\u53d8\u91cf"},"\u5305\u542b Taskfile \u7684\u53d8\u91cf"),(0,l.kt)("p",null,"\u60a8\u8fd8\u53ef\u4ee5\u5728\u5305\u542b Taskfile \u65f6\u6307\u5b9a\u53d8\u91cf\u3002 \u8fd9\u5bf9\u4e8e\u62e5\u6709\u53ef\u4ee5\u8c03\u6574\u751a\u81f3\u591a\u6b21\u5305\u542b\u7684\u53ef\u91cd\u7528 Taskfile \u53ef\u80fd\u5f88\u6709\u7528\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h3",{id:"\u547d\u540d\u7a7a\u95f4\u522b\u540d"},"\u547d\u540d\u7a7a\u95f4\u522b\u540d"),(0,l.kt)("p",null,"\u5305\u542b Taskfile \u65f6\uff0c\u60a8\u53ef\u4ee5\u4e3a\u547d\u540d\u7a7a\u95f4\u63d0\u4f9b\u4e00\u4e2a ",(0,l.kt)("inlineCode",{parentName:"p"},"aliases")," \u5217\u8868\u3002 \u8fd9\u4e0e ",(0,l.kt)("a",{parentName:"p",href:"#task-%E5%88%AB%E5%90%8D"},"task \u522b\u540d")," \u7684\u5de5\u4f5c\u65b9\u5f0f\u76f8\u540c\uff0c\u53ef\u4ee5\u4e00\u8d77\u4f7f\u7528\u6765\u521b\u5efa\u66f4\u77ed\u4e14\u66f4\u6613\u4e8e\u952e\u5165\u7684\u547d\u4ee4\u3002"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nincludes:\n generate:\n taskfile: ./taskfiles/Generate.yml\n aliases: [gen]\n")),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u5728\u5305\u542b\u7684 Taskfile \u4e2d\u58f0\u660e\u7684\u53d8\u91cf\u4f18\u5148\u4e8e\u5305\u542b Taskfile \u4e2d\u7684\u53d8\u91cf\uff01 \u5982\u679c\u60a8\u5e0c\u671b\u5305\u542b\u7684 Taskfile \u4e2d\u7684\u53d8\u91cf\u53ef\u88ab\u8986\u76d6\uff0c\u8bf7\u4f7f\u7528 ",(0,l.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/defaults.html"},"\u9ed8\u8ba4\u65b9\u6cd5"),"\uff1a",(0,l.kt)("inlineCode",{parentName:"p"},"MY_VAR: '{{.MY_VAR | default \"my-default-value\"}}'"),"\u3002")),(0,l.kt)("h2",{id:"\u5185\u90e8-tasks"},"\u5185\u90e8 tasks"),(0,l.kt)("p",null,"\u5185\u90e8 task \u662f\u7528\u6237\u4e0d\u80fd\u76f4\u63a5\u8c03\u7528\u7684 task\u3002 \u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"task --list|--list-all")," \u65f6\uff0c\u5b83\u4eec\u4e0d\u4f1a\u51fa\u73b0\u5728\u8f93\u51fa\u4e2d\u3002 \u5176\u4ed6 task \u53ef\u4ee5\u7167\u5e38\u8c03\u7528\u5185\u90e8 task\u3002 \u8fd9\u5bf9\u4e8e\u521b\u5efa\u5728\u547d\u4ee4\u884c\u4e0a\u6ca1\u6709\u7528\u5904\u7684\u53ef\u91cd\u7528\u3001\u7c7b\u4f3c\u51fd\u6570\u7684 task \u5f88\u6709\u7528\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"task-\u76ee\u5f55"},"Task \u76ee\u5f55"),(0,l.kt)("p",null,"\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0ctasks \u5c06\u5728 Taskfile \u6240\u5728\u7684\u76ee\u5f55\u4e2d\u6267\u884c\u3002 \u4f46\u662f\u60a8\u53ef\u4ee5\u8f7b\u677e\u5730\u8ba9 task \u5728\u53e6\u4e00\u4e2a\u76ee\u5f55\u4e2d\u8fd0\u884c\uff0c\u6307\u5b9a ",(0,l.kt)("inlineCode",{parentName:"p"},"dir"),"\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5982\u679c\u8be5\u76ee\u5f55\u4e0d\u5b58\u5728\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"task")," \u4f1a\u521b\u5efa\u5b83\u3002"),(0,l.kt)("h2",{id:"task-\u4f9d\u8d56"},"Task \u4f9d\u8d56"),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\u4f9d\u8d56\u9879\u5e76\u884c\u8fd0\u884c\uff0c\u56e0\u6b64\u4e00\u9879 task \u7684\u4f9d\u8d56\u9879\u4e0d\u5e94\u76f8\u4e92\u4f9d\u8d56\u3002 \u5982\u679c\u60a8\u60f3\u5f3a\u5236\u4efb\u52a1\u987a\u5e8f\u8fd0\u884c\uff0c\u8bf7\u67e5\u770b\u4e0b\u9762\u7684 ",(0,l.kt)("a",{parentName:"p",href:"#%E8%B0%83%E7%94%A8%E5%8F%A6%E4%B8%80%E4%B8%AA-task"},"\u8c03\u7528\u53e6\u4e00\u4e2a task")," \u90e8\u5206\u3002")),(0,l.kt)("p",null,"\u60a8\u53ef\u80fd\u6709\u4f9d\u8d56\u4e8e\u5176\u5b83\u7684 task\u3002 \u5c06\u5b83\u4eec\u6307\u5411 ",(0,l.kt)("inlineCode",{parentName:"p"},"deps")," \u5c06\u4f7f\u5b83\u4eec\u5728\u8fd0\u884c\u7236 task \u4e4b\u524d\u81ea\u52a8\u8fd0\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5728\u4e0a\u9762\u7684\u793a\u4f8b\u4e2d\uff0c\u5982\u679c\u60a8\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"task build"),"\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"assets")," \u5c06\u59cb\u7ec8\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},"build")," \u4e4b\u524d\u8fd0\u884c\u3002"),(0,l.kt)("p",null,"\u4e00\u4e2a task \u53ea\u80fd\u6709\u4f9d\u8d56\u5173\u7cfb\uff0c\u6ca1\u6709\u547d\u4ee4\u6765\u5c06 task \u7ec4\u5408\u5728\u4e00\u8d77\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5982\u679c\u6709\u591a\u4e2a\u4f9d\u8d56\u9879\uff0c\u5b83\u4eec\u603b\u662f\u5e76\u884c\u8fd0\u884c\u4ee5\u83b7\u5f97\u66f4\u597d\u7684\u6027\u80fd\u3002"),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"\u60a8\u8fd8\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"--parallel")," \u6807\u5fd7\uff08\u522b\u540d ",(0,l.kt)("inlineCode",{parentName:"p"},"-p"),"\uff09\u4f7f\u547d\u4ee4\u884c\u7ed9\u51fa\u7684 task \u5e76\u884c\u8fd0\u884c\u3002 \u4f8b\u5982: ",(0,l.kt)("inlineCode",{parentName:"p"},"task --parallel js css"),"\u3002")),(0,l.kt)("p",null,"\u5982\u679c\u4f60\u60f3\u5c06\u4fe1\u606f\u4f20\u9012\u7ed9\u4f9d\u8d56\u9879\uff0c\u4f60\u53ef\u4ee5\u50cf ",(0,l.kt)("a",{parentName:"p",href:"#%E8%B0%83%E7%94%A8%E5%8F%A6%E4%B8%80%E4%B8%AA-task"},"\u8c03\u7528\u53e6\u4e00\u4e2a task")," \u4e00\u6837\u4ee5\u76f8\u540c\u7684\u65b9\u5f0f\u8fdb\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.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 silent: true\n cmds:\n - echo \"after\"\n\n echo_sth:\n cmds:\n - echo {{.TEXT}}\n")),(0,l.kt)("h2",{id:"\u5e73\u53f0\u7279\u5b9a\u7684-tasks-\u548c-cmds"},"\u5e73\u53f0\u7279\u5b9a\u7684 tasks \u548c cmds"),(0,l.kt)("p",null,"\u5982\u679c\u60a8\u60f3\u5c06 task \u7684\u8fd0\u884c\u9650\u5236\u5728\u660e\u786e\u7684\u5e73\u53f0\u4e0a\uff0c\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"platforms:")," \u952e\u6765\u5b9e\u73b0\u3002 Task \u53ef\u4ee5\u9650\u5236\u5728\u7279\u5b9a\u7684\u64cd\u4f5c\u7cfb\u7edf\u3001\u67b6\u6784\u6216\u4e24\u8005\u7684\u7ec4\u5408\u4e2d\u3002 \u5982\u679c\u4e0d\u5339\u914d\uff0c\u4efb\u52a1\u6216\u547d\u4ee4\u5c06\u88ab\u8df3\u8fc7\uff0c\u5e76\u4e14\u4e0d\u4f1a\u629b\u51fa\u4efb\u4f55\u9519\u8bef\u3002"),(0,l.kt)("p",null,"\u5141\u8bb8\u4f5c\u4e3a OS \u6216 Arch \u7684\u503c\u662f\u6709\u6548\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},"GOOS")," \u548c ",(0,l.kt)("inlineCode",{parentName:"p"},"GOARCH")," \u503c\uff0c\u6b63\u5982 ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/golang/go/blob/master/src/go/build/syslist.go"},"\u6b64\u5904")," \u7684 Go \u8bed\u8a00\u6240\u5b9a\u4e49\u7684\u90a3\u6837\u3002"),(0,l.kt)("p",null,"\u4e0b\u9762\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},"build-windows")," task \u5c06\u4ec5\u5728 Windows \u6240\u6709\u67b6\u6784\u4e0a\u8fd0\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u8fd9\u53ef\u4ee5\u9650\u5236\u4e3a\u7279\u5b9a\u7684\u67b6\u6784\uff0c\u5982\u4e0b\u6240\u793a\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4e5f\u53ef\u4ee5\u5c06 task \u9650\u5236\u5728\u7279\u5b9a\u7684\u67b6\u6784\u4e2d\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u53ef\u4ee5\u6307\u5b9a\u591a\u4e2a\u5e73\u53f0\uff0c\u5982\u4e0b\u6240\u793a\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4e2a\u522b\u547d\u4ee4\u4e5f\u53ef\u4ee5\u9650\u5236\u5728\u7279\u5b9a\u5e73\u53f0\u4e0a\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u8c03\u7528\u53e6\u4e00\u4e2a-task"},"\u8c03\u7528\u53e6\u4e00\u4e2a task"),(0,l.kt)("p",null,"\u5f53\u4e00\u4e2a task \u6709\u5f88\u591a\u4f9d\u8d56\u65f6\uff0c\u5b83\u4eec\u662f\u5e76\u53d1\u6267\u884c\u7684\u3002 \u8fd9\u901a\u5e38\u4f1a\u5bfc\u81f4\u66f4\u5feb\u7684\u6784\u5efa\u7ba1\u9053\u3002 \u4f46\u662f\uff0c\u5728\u67d0\u4e9b\u60c5\u51b5\u4e0b\uff0c\u60a8\u53ef\u80fd\u9700\u8981\u4e32\u884c\u8c03\u7528\u5176\u4ed6 task\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u8bf7\u4f7f\u7528\u4ee5\u4e0b\u8bed\u6cd5\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"vars")," \u548c ",(0,l.kt)("inlineCode",{parentName:"p"},"silent")," \u5c5e\u6027\uff0c\u60a8\u53ef\u4ee5\u9009\u62e9\u5728\u9010\u4e2a\u8c03\u7528\u7684\u57fa\u7840\u4e0a\u4f20\u9012\u53d8\u91cf\u548c\u5207\u6362 ",(0,l.kt)("a",{parentName:"p",href:"#%E9%9D%99%E9%BB%98%E6%A8%A1%E5%BC%8F"},"\u9759\u9ed8\u6a21\u5f0f"),"\uff1a"),(0,l.kt)("pre",null,(0,l.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 silent: true\n")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"deps")," \u4e5f\u652f\u6301\u4e0a\u8ff0\u8bed\u6cd5\u3002"),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"\u6ce8\u610f\uff1a\u5982\u679c\u60a8\u60f3\u4ece ",(0,l.kt)("a",{parentName:"p",href:"#%E5%8C%85%E5%90%AB%E5%85%B6%E4%BB%96-taskfile"},"\u5305\u542b\u7684 Taskfile")," \u4e2d\u8c03\u7528\u5728\u6839 Taskfile \u4e2d\u58f0\u660e\u7684 task\uff0c\u8bf7\u50cf\u8fd9\u6837\u6dfb\u52a0 ",(0,l.kt)("inlineCode",{parentName:"p"},":")," \u524d\u7f00\uff1a",(0,l.kt)("inlineCode",{parentName:"p"},"task: :task-name"),"\u3002")),(0,l.kt)("h2",{id:"\u51cf\u5c11\u4e0d\u5fc5\u8981\u7684\u5de5\u4f5c"},"\u51cf\u5c11\u4e0d\u5fc5\u8981\u7684\u5de5\u4f5c"),(0,l.kt)("h3",{id:"\u901a\u8fc7\u6307\u7eb9\u8bc6\u522b\u672c\u5730\u751f\u6210\u7684\u6587\u4ef6\u53ca\u5176\u6765\u6e90"},"\u901a\u8fc7\u6307\u7eb9\u8bc6\u522b\u672c\u5730\u751f\u6210\u7684\u6587\u4ef6\u53ca\u5176\u6765\u6e90"),(0,l.kt)("p",null,"\u5982\u679c\u4e00\u4e2a task \u751f\u6210\u4e86\u4e00\u4e9b\u4e1c\u897f\uff0c\u4f60\u53ef\u4ee5\u901a\u77e5 task \u6e90\u548c\u751f\u6210\u7684\u6587\u4ef6\uff0c\u8fd9\u6837 task \u5c31\u4f1a\u5728\u4e0d\u9700\u8981\u7684\u65f6\u5019\u963b\u6b62\u8fd0\u884c\u5b83\u4eec\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"sources")," \u548c ",(0,l.kt)("inlineCode",{parentName:"p"},"generates")," \u53ef\u4ee5\u914d\u7f6e\u5177\u4f53\u6587\u4ef6\u6216\u8005\u4f7f\u7528\u5339\u914d\u6a21\u5f0f\u3002 \u8bbe\u7f6e\u540e\uff0c Task \u4f1a\u6839\u636e\u6e90\u6587\u4ef6\u7684 checksum \u6765\u786e\u5b9a\u662f\u5426\u9700\u8981\u6267\u884c\u5f53\u524d\u4efb\u52a1\u3002 \u5982\u679c\u4e0d\u9700\u8981\u6267\u884c\uff0c \u5219\u4f1a\u8f93\u51fa\u50cf ",(0,l.kt)("inlineCode",{parentName:"p"},'Task "js" is up to date')," \u8fd9\u6837\u7684\u4fe1\u606f\u3002"),(0,l.kt)("p",null,"\u5982\u679c\u60a8\u5e0c\u671b\u901a\u8fc7\u6587\u4ef6\u7684\u4fee\u6539 timestamp \u800c\u4e0d\u662f\u5176 checksum\uff08\u5185\u5bb9\uff09\u6765\u8fdb\u884c\u6b64\u68c0\u67e5\uff0c\u53ea\u9700\u5c06 ",(0,l.kt)("inlineCode",{parentName:"p"},"method")," \u5c5e\u6027\u8bbe\u7f6e\u4e3a ",(0,l.kt)("inlineCode",{parentName:"p"},"timestamp")," \u5373\u53ef\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5728\u9700\u8981\u66f4\u5927\u7075\u6d3b\u6027\u7684\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u5173\u952e\u5b57\u3002 \u60a8\u751a\u81f3\u53ef\u4ee5\u5c06\u4e24\u8005\u7ed3\u5408\u8d77\u6765\u3002 \u6709\u5173\u793a\u4f8b\uff0c\u8bf7\u53c2\u9605 ",(0,l.kt)("a",{parentName:"p",href:"#%E4%BD%BF%E7%94%A8%E7%A8%8B%E5%BA%8F%E6%A3%80%E6%9F%A5%E6%9D%A5%E8%A1%A8%E7%A4%BA%E4%BB%BB%E5%8A%A1%E6%98%AF%E6%9C%80%E6%96%B0%E7%9A%84"},"\u72b6\u6001")," \u6587\u6863\u3002"),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u9ed8\u8ba4\u60c5\u51b5\uff0ctask \u5728\u672c\u5730\u9879\u76ee\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},".task")," \u76ee\u5f55\u4fdd\u5b58 checksums \u503c\u3002 \u4e00\u822c\u90fd\u4f1a\u5728 ",(0,l.kt)("inlineCode",{parentName:"p"},".gitignore"),"\uff08\u6216\u7c7b\u4f3c\u914d\u7f6e\uff09\u4e2d\u5ffd\u7565\u6389\u8fd9\u4e2a\u76ee\u5f55\uff0c\u8fd9\u6837\u5b83\u5c31\u4e0d\u4f1a\u88ab\u63d0\u4ea4\u3002 (\u5982\u679c\u60a8\u6709\u4e00\u4e2a\u5df2\u63d0\u4ea4\u7684\u4ee3\u7801\u751f\u6210\u4efb\u52a1\uff0c\u90a3\u4e48\u63d0\u4ea4\u8be5\u4efb\u52a1\u7684\u6821\u9a8c\u548c\u4e5f\u662f\u6709\u610f\u4e49\u7684)\u3002"),(0,l.kt)("p",{parentName:"admonition"},"\u5982\u679c\u4f60\u60f3\u8981\u5c06\u8fd9\u4e9b\u6587\u4ef6\u5b58\u50a8\u5728\u53e6\u4e00\u4e2a\u76ee\u5f55\u4e2d\uff0c\u4f60\u53ef\u4ee5\u5728\u4f60\u7684\u673a\u5668\u4e2d\u8bbe\u7f6e\u4e00\u4e2a ",(0,l.kt)("inlineCode",{parentName:"p"},"TASK_TEMP_DIR")," \u73af\u5883\u53d8\u91cf\u3002 \u53ef\u4ee5\u4f7f\u7528\u76f8\u5bf9\u8def\u5f84\uff0c\u6bd4\u5982 ",(0,l.kt)("inlineCode",{parentName:"p"},"tmp/task"),"\uff0c\u76f8\u5bf9\u9879\u76ee\u6839\u76ee\u5f55\uff0c\u4e5f\u53ef\u4ee5\u7528\u7edd\u5bf9\u8def\u5f84\u3001\u7528\u6237\u76ee\u5f55\u8def\u5f84\uff0c\u6bd4\u5982 ",(0,l.kt)("inlineCode",{parentName:"p"},"/tmp/.task")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"~/.task"),"\uff08\u6bcf\u4e2a\u9879\u76ee\u5355\u72ec\u521b\u5efa\u5b50\u76ee\u5f55\uff09\u3002"),(0,l.kt)("pre",{parentName:"admonition"},(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"export TASK_TEMP_DIR='~/.task'\n"))),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u6bcf\u4e2a task \u53ea\u4e3a\u5176 ",(0,l.kt)("inlineCode",{parentName:"p"},"sources")," \u5b58\u50a8\u4e00\u4e2a checksum\u3002 \u5982\u679c\u60a8\u60f3\u901a\u8fc7\u4efb\u4f55\u8f93\u5165\u53d8\u91cf\u6765\u533a\u5206 task\uff0c\u60a8\u53ef\u4ee5\u5c06\u8fd9\u4e9b\u53d8\u91cf\u6dfb\u52a0\u4e3a task \u6807\u7b7e\u7684\u4e00\u90e8\u5206\uff0c\u5b83\u5c06\u88ab\u89c6\u4e3a\u4e0d\u540c\u7684 task\u3002"),(0,l.kt)("p",{parentName:"admonition"},"\u5982\u679c\u60a8\u60f3\u4e3a\u6bcf\u4e2a\u4e0d\u540c\u7684\u8f93\u5165\u96c6\u8fd0\u884c\u4e00\u6b21 task\uff0c\u76f4\u5230 sources \u5b9e\u9645\u53d1\u751f\u53d8\u5316\uff0c\u8fd9\u5c06\u5f88\u6709\u7528\u3002 \u4f8b\u5982\uff0c\u5982\u679c sources \u4f9d\u8d56\u4e8e\u53d8\u91cf\u7684\u503c\uff0c\u6216\u8005\u60a8\u5e0c\u671b\u5728\u67d0\u4e9b\u53c2\u6570\u53d1\u751f\u53d8\u5316\u65f6\u91cd\u65b0\u8fd0\u884c task\uff0c\u5373\u4f7f sources \u6ca1\u6709\u53d1\u751f\u53d8\u5316\u4e5f\u662f\u5982\u6b64\u3002")),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"\u5c06 method \u8bbe\u7f6e\u4e3a ",(0,l.kt)("inlineCode",{parentName:"p"},"none")," \u4f1a\u8df3\u8fc7\u4efb\u4f55\u9a8c\u8bc1\u5e76\u59cb\u7ec8\u8fd0\u884c\u4efb\u52a1\u3002")),(0,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u8981\u4f7f ",(0,l.kt)("inlineCode",{parentName:"p"},"checksum"),"\uff08\u9ed8\u8ba4\uff09\u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"timestamp")," \u65b9\u6cd5\u8d77\u4f5c\u7528\uff0c\u53ea\u9700\u8981\u901a\u77e5 source \u6587\u4ef6\u5373\u53ef\u3002 \u5f53\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"timestamp")," \u65b9\u6cd5\u65f6\uff0c\u6700\u540e\u4e00\u6b21\u8fd0\u884c task \u88ab\u8ba4\u4e3a\u662f\u4e00\u6b21\u751f\u6210\u3002")),(0,l.kt)("h3",{id:"\u4f7f\u7528\u7a0b\u5e8f\u68c0\u67e5\u6765\u8868\u793a\u4efb\u52a1\u662f\u6700\u65b0\u7684"},"\u4f7f\u7528\u7a0b\u5e8f\u68c0\u67e5\u6765\u8868\u793a\u4efb\u52a1\u662f\u6700\u65b0\u7684"),(0,l.kt)("p",null,"\u6216\u8005\uff0c\u60a8\u53ef\u4ee5\u901a\u77e5\u4e00\u7cfb\u5217\u6d4b\u8bd5\u4f5c\u4e3a ",(0,l.kt)("inlineCode",{parentName:"p"},"status"),"\u3002 \u5982\u679c\u6ca1\u6709\u9519\u8bef\u8fd4\u56de\uff08\u9000\u51fa\u72b6\u6001 0\uff09\uff0ctask \u88ab\u8ba4\u4e3a\u662f\u6700\u65b0\u7684\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u901a\u5e38\uff0c\u60a8\u4f1a\u5c06 ",(0,l.kt)("inlineCode",{parentName:"p"},"sources")," \u4e0e ",(0,l.kt)("inlineCode",{parentName:"p"},"generates")," \u7ed3\u5408\u4f7f\u7528 - \u4f46\u5bf9\u4e8e\u751f\u6210\u8fdc\u7a0b\u5de5\u4ef6\uff08Docker \u6620\u50cf\u3001\u90e8\u7f72\u3001CD \u7248\u672c\uff09\u7684 task\uff0cchecksum source \u548c timestamps \u9700\u8981\u8bbf\u95ee\u5de5\u4ef6\u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},".checksum")," \u6307\u7eb9\u6587\u4ef6\u3002"),(0,l.kt)("p",null,"\u4e24\u4e2a\u7279\u6b8a\u53d8\u91cf ",(0,l.kt)("inlineCode",{parentName:"p"},"{{.CHECKSUM}}")," \u548c ",(0,l.kt)("inlineCode",{parentName:"p"},"{{.TIMESTAMP}}")," \u53ef\u7528\u4e8e ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u547d\u4ee4\u4e2d\u7684\u63d2\u503c\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u5206\u914d\u7ed9 sources \u7684\u6307\u7eb9\u65b9\u6cd5\u3002 \u53ea\u6709 ",(0,l.kt)("inlineCode",{parentName:"p"},"source")," \u5757\u624d\u80fd\u751f\u6210\u6307\u7eb9\u3002"),(0,l.kt)("p",null,"\u8bf7\u6ce8\u610f\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"{{.TIMESTAMP}}")," \u53d8\u91cf\u662f\u4e00\u4e2a\u201c\u5b9e\u65f6\u201dGo ",(0,l.kt)("inlineCode",{parentName:"p"},"time.Time")," \u7ed3\u6784\uff0c\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"time.Time")," \u54cd\u5e94\u7684\u4efb\u4f55\u65b9\u6cd5\u8fdb\u884c\u683c\u5f0f\u5316\u3002"),(0,l.kt)("p",null,"\u6709\u5173\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u53c2\u9605 ",(0,l.kt)("a",{parentName:"p",href:"https://golang.org/pkg/time/"},"Go Time \u6587\u6863"),"\u3002"),(0,l.kt)("p",null,"\u5982\u679c\u4f60\u60f3\u5f3a\u5236\u4efb\u52a1\u8fd0\u884c\uff0c\u5373\u4f7f\u662f\u6700\u65b0\u7684\uff0c\u4f60\u4e5f\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"--force")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"-f"),"\u3002"),(0,l.kt)("p",null,"\u6b64\u5916\uff0c\u5982\u679c\u4efb\u4f55 task \u4e0d\u662f\u6700\u65b0\u7684\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"task --status [tasks]...")," \u5c06\u4ee5\u975e\u96f6\u9000\u51fa\u4ee3\u7801\u9000\u51fa\u3002"),(0,l.kt)("p",null,"\u5982\u679c source/generated \u7684\u5de5\u4ef6\u53d1\u751f\u53d8\u5316\uff0c\u6216\u8005\u7a0b\u5e8f\u68c0\u67e5\u5931\u8d25\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u53ef\u4ee5\u4e0e ",(0,l.kt)("a",{parentName:"p",href:"#%E9%80%9A%E8%BF%87%E6%8C%87%E7%BA%B9%E8%AF%86%E5%88%AB%E6%9C%AC%E5%9C%B0%E7%94%9F%E6%88%90%E7%9A%84%E6%96%87%E4%BB%B6%E5%8F%8A%E5%85%B6%E6%9D%A5%E6%BA%90"},"\u6307\u7eb9")," \u7ed3\u5408\u4ee5\u8fd0\u884c\u4efb\u52a1\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h3",{id:"\u4f7f\u7528\u7a0b\u5e8f\u68c0\u67e5\u53d6\u6d88\u4efb\u52a1\u53ca\u5176\u4f9d\u8d56\u9879\u7684\u6267\u884c"},"\u4f7f\u7528\u7a0b\u5e8f\u68c0\u67e5\u53d6\u6d88\u4efb\u52a1\u53ca\u5176\u4f9d\u8d56\u9879\u7684\u6267\u884c"),(0,l.kt)("p",null,"\u9664\u4e86 ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u68c0\u67e5\u4e4b\u5916\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"preconditions")," \u68c0\u67e5\u662f ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u68c0\u67e5\u7684\u903b\u8f91\u9006\u8fc7\u7a0b\u3002 \u4e5f\u5c31\u662f\u8bf4\uff0c\u5982\u679c\u60a8\u9700\u8981\u4e00\u7ec4\u7279\u5b9a\u7684\u6761\u4ef6\u4e3a ",(0,l.kt)("em",{parentName:"p"},"true"),"\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"preconditions"),"\u3002 ",(0,l.kt)("inlineCode",{parentName:"p"},"preconditions")," \u7c7b\u4f3c\u4e8e ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u884c\uff0c\u9664\u4e86\u5b83\u4eec\u652f\u6301 ",(0,l.kt)("inlineCode",{parentName:"p"},"sh")," \u6269\u5c55\uff0c\u5e76\u4e14\u5b83\u4eec\u5e94\u8be5\u5168\u90e8\u8fd4\u56de 0\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5148\u51b3\u6761\u4ef6\u53ef\u4ee5\u8bbe\u7f6e\u7279\u5b9a\u7684\u5931\u8d25\u6d88\u606f\uff0c\u8fd9\u4e9b\u6d88\u606f\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"msg")," \u5b57\u6bb5\u544a\u8bc9\u7528\u6237\u8981\u91c7\u53d6\u4ec0\u4e48\u6b65\u9aa4\u3002"),(0,l.kt)("p",null,"\u5982\u679c\u4e00\u4e2a task \u4f9d\u8d56\u4e8e\u4e00\u4e2a\u5177\u6709\u524d\u63d0\u6761\u4ef6\u7684\u5b50 task\uff0c\u5e76\u4e14\u4e0d\u6ee1\u8db3\u8be5\u524d\u63d0\u6761\u4ef6 - \u8c03\u7528 task \u5c06\u5931\u8d25\u3002 \u8bf7\u6ce8\u610f\uff0c\u9664\u975e\u7ed9\u51fa ",(0,l.kt)("inlineCode",{parentName:"p"},"--force")," \uff0c\u5426\u5219\u4ee5\u5931\u8d25\u7684\u524d\u63d0\u6761\u4ef6\u6267\u884c\u7684 task \u5c06\u4e0d\u4f1a\u8fd0\u884c\u3002"),(0,l.kt)("p",null,"\u4e0e ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," \u5224\u65ad task \u662f\u6700\u65b0\u72b6\u6001\u65f6\u4f1a\u8df3\u8fc7\u5e76\u7ee7\u7eed\u6267\u884c\u4e0d\u540c\uff0c ",(0,l.kt)("inlineCode",{parentName:"p"},"precondition")," \u5931\u8d25\u4f1a\u5bfc\u81f4 task \u5931\u8d25\uff0c\u4ee5\u53ca\u6240\u6709\u4f9d\u8d56\u5b83\u7684 task \u90fd\u4f1a\u5931\u8d25\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h3",{id:"\u5728\u4efb\u52a1\u8fd0\u884c\u65f6\u9650\u5236"},"\u5728\u4efb\u52a1\u8fd0\u884c\u65f6\u9650\u5236"),(0,l.kt)("p",null,"\u5982\u679c task \u7531\u591a\u4e2a ",(0,l.kt)("inlineCode",{parentName:"p"},"cmd")," \u6216\u591a\u4e2a ",(0,l.kt)("inlineCode",{parentName:"p"},"deps")," \u6267\u884c\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"run")," \u63a7\u5236\u4f55\u65f6\u6267\u884c\u3002 ",(0,l.kt)("inlineCode",{parentName:"p"},"run")," \u4e5f\u53ef\u4ee5\u8bbe\u7f6e\u5728 Taskfile \u7684\u6839\u76ee\u5f55\u4ee5\u66f4\u6539\u6240\u6709\u4efb\u52a1\u7684\u884c\u4e3a\uff0c\u9664\u975e\u88ab\u660e\u786e\u8986\u76d6\u3002"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"run")," \u652f\u6301\u7684\u503c\uff1a"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"always")," \uff08\u9ed8\u8ba4\uff09\u603b\u662f\u5c1d\u8bd5\u8c03\u7528 task\uff0c\u65e0\u8bba\u5148\u524d\u6267\u884c\u7684\u6b21\u6570\u5982\u4f55"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"once")," \u53ea\u8c03\u7528\u4e00\u6b21\u8fd9\u4e2a\u4efb\u52a1\uff0c\u4e0d\u7ba1\u5f15\u7528\u7684\u6570\u91cf"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"when_changed")," \u53ea\u4e3a\u4f20\u9012\u7ed9 task \u7684\u6bcf\u4e2a\u552f\u4e00\u53d8\u91cf\u96c6\u8c03\u7528\u4e00\u6b21 task")),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u53d8\u91cf"},"\u53d8\u91cf"),(0,l.kt)("p",null,"\u5728\u8fdb\u884c\u53d8\u91cf\u63d2\u503c\u65f6\uff0cTask \u5c06\u67e5\u627e\u4ee5\u4e0b\u5185\u5bb9\u3002 \u5b83\u4eec\u6309\u6743\u91cd\u987a\u5e8f\u5217\u5728\u4e0b\u9762\uff08\u5373\u6700\u91cd\u8981\u7684\u7b2c\u4e00\u4f4d\uff09\uff1a"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"task \u5185\u90e8\u5b9a\u4e49\u7684\u53d8\u91cf"),(0,l.kt)("li",{parentName:"ul"},"\u88ab\u5176\u5b83 task \u8c03\u7528\u65f6\u4f20\u5165\u7684\u53d8\u91cf(\u67e5\u770b ",(0,l.kt)("a",{parentName:"li",href:"#%E8%B0%83%E7%94%A8%E5%8F%A6%E4%B8%80%E4%B8%AA-task"},"\u8c03\u7528\u53e6\u4e00\u4e2a task"),")"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#%E5%8C%85%E5%90%AB%E5%85%B6%E4%BB%96-taskfile"},"\u5305\u542b\u5176\u4ed6 Taskfile")," \u4e2d\u7684\u53d8\u91cf (\u5f53\u5305\u542b\u5176\u4ed6 task \u65f6)"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"#%E5%8C%85%E5%90%AB-taskfile-%E7%9A%84%E5%8F%98%E9%87%8F"},"\u5305\u542b Taskfile")," \u7684\u53d8\u91cf\uff08\u5305\u542b task \u65f6\uff09"),(0,l.kt)("li",{parentName:"ul"},"\u5168\u5c40\u53d8\u91cf (\u5728 Taskfile \u7684 ",(0,l.kt)("inlineCode",{parentName:"li"},"vars:")," \u4e2d\u58f0\u660e)"),(0,l.kt)("li",{parentName:"ul"},"\u73af\u5883\u53d8\u91cf")),(0,l.kt)("p",null,"\u4f7f\u7528\u73af\u5883\u53d8\u91cf\u4f20\u8f93\u53c2\u6570\u7684\u793a\u4f8b\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"$ TASK_VARIABLE=a-value task do-something\n")),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"\u5305\u542b\u4efb\u52a1\u540d\u79f0\u7684\u7279\u6b8a\u53d8\u91cf ",(0,l.kt)("inlineCode",{parentName:"p"},".TASK")," \u59cb\u7ec8\u53ef\u7528\u3002")),(0,l.kt)("p",null,"\u7531\u4e8e\u67d0\u4e9b shell \u4e0d\u652f\u6301\u4e0a\u8ff0\u8bed\u6cd5\u6765\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf (Windows)\uff0ctask \u5728\u4e0d\u5728\u547d\u4ee4\u5f00\u5934\u65f6\u4e5f\u63a5\u53d7\u7c7b\u4f3c\u7684\u6837\u5f0f\u3002"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'$ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!"\n')),(0,l.kt)("p",null,"\u672c\u5730\u58f0\u660e\u7684\u53d8\u91cf\u793a\u4f8b\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Taskfile.yml")," \u4e2d\u7684\u5168\u5c40\u53d8\u91cf\u793a\u4f8b\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h3",{id:"\u52a8\u6001\u53d8\u91cf"},"\u52a8\u6001\u53d8\u91cf"),(0,l.kt)("p",null,"\u4ee5\u4e0b\u8bed\u6cd5 (",(0,l.kt)("inlineCode",{parentName:"p"},"sh:")," prop in a variable) \u88ab\u8ba4\u4e3a\u662f\u52a8\u6001\u53d8\u91cf\u3002 \u8be5\u503c\u5c06\u88ab\u89c6\u4e3a\u547d\u4ee4\u5e76\u4ea7\u751f\u8f93\u51fa\u7ed3\u679c\u7528\u4e8e\u8d4b\u503c\u3002 \u5982\u679c\u6709\u4e00\u4e2a\u6216\u591a\u4e2a\u5c3e\u968f\u6362\u884c\u7b26\uff0c\u6700\u540e\u4e00\u4e2a\u6362\u884c\u7b26\u5c06\u88ab\u4fee\u526a\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u8fd9\u9002\u7528\u4e8e\u6240\u6709\u7c7b\u578b\u7684\u53d8\u91cf\u3002"),(0,l.kt)("h2",{id:"\u5c06-cli-\u53c2\u6570\u8f6c\u53d1\u5230-cmds"},"\u5c06 CLI \u53c2\u6570\u8f6c\u53d1\u5230 cmds"),(0,l.kt)("p",null,"\u5982\u679c ",(0,l.kt)("inlineCode",{parentName:"p"},"--")," \u5728 CLI \u4e2d\u7ed9\u51fa\uff0c\u5219\u6240\u6709\u4ee5\u4e0b\u53c2\u6570\u90fd\u5c06\u6dfb\u52a0\u5230\u7279\u6b8a\u7684 ",(0,l.kt)("inlineCode",{parentName:"p"},".CLI_ARGS")," \u53d8\u91cf\u4e2d\u3002 \u8fd9\u5bf9\u4e8e\u5c06\u53c2\u6570\u8f6c\u53d1\u7ed9\u53e6\u4e00\u4e2a\u547d\u4ee4\u5f88\u6709\u7528\u3002"),(0,l.kt)("p",null,"\u4e0b\u9762\u7684\u793a\u4f8b\u5c06\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"yarn install"),"\u3002"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"$ task yarn -- install\n")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n yarn:\n cmds:\n - yarn {{.CLI_ARGS}}\n")),(0,l.kt)("h2",{id:"\u4f7f\u7528-defer-\u505a-task-\u6e05\u7406"},"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"h2"},"defer")," \u505a task \u6e05\u7406"),(0,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"defer")," \u5173\u952e\u5b57\uff0c\u53ef\u4ee5\u5b89\u6392\u5728 task \u5b8c\u6210\u540e\u8fd0\u884c\u6e05\u7406\u3002 \u4e0e\u4ec5\u5c06\u5176\u4f5c\u4e3a\u6700\u540e\u4e00\u4e2a\u547d\u4ee4\u7684\u4e0d\u540c\u4e4b\u5904\u5728\u4e8e\uff0c\u5373\u4f7f task \u5931\u8d25\uff0c\u8be5\u547d\u4ee4\u4e5f\u4f1a\u8fd0\u884c\u3002"),(0,l.kt)("p",null,"\u5728\u4e0b\u9762\u7684\u793a\u4f8b\u4e2d\uff0c\u5373\u4f7f\u7b2c\u4e09\u4e2a\u547d\u4ee4\u5931\u8d25\uff0c",(0,l.kt)("inlineCode",{parentName:"p"},"rm -rf tmpdir/")," \u4e5f\u4f1a\u8fd0\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4f7f\u7528\u5176\u5b83 task \u4f5c\u4e3a\u6e05\u7406\u4efb\u52a1\u7684\u547d\u4ee4\u65f6\uff0c\u53ef\u4ee5\u8fd9\u6837\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u7531\u4e8e ",(0,l.kt)("a",{parentName:"p",href:"https://go.dev/tour/flowcontrol/13"},"Go \u81ea\u8eab\u7684 ",(0,l.kt)("inlineCode",{parentName:"a"},"defer")," \u5de5\u4f5c\u65b9\u5f0f")," \u7684\u6027\u8d28\uff0c\u5982\u679c\u60a8\u5b89\u6392\u591a\u4e2a defer\u547d\u4ee4\uff0c\u5219 defer \u547d\u4ee4\u5c06\u4ee5\u76f8\u53cd\u7684\u987a\u5e8f\u6267\u884c\u3002")),(0,l.kt)("h2",{id:"go-\u7684\u6a21\u677f\u5f15\u64ce"},"Go \u7684\u6a21\u677f\u5f15\u64ce"),(0,l.kt)("p",null,"Task \u5728\u6267\u884c\u547d\u4ee4\u4e4b\u524d\u5c06\u547d\u4ee4\u89e3\u6790\u4e3a ",(0,l.kt)("a",{parentName:"p",href:"https://golang.org/pkg/text/template/"},"Go \u7684\u6a21\u677f\u5f15\u64ce"),"\u3002 \u53ef\u4ee5\u901a\u8fc7\u70b9\u8bed\u6cd5 (",(0,l.kt)("inlineCode",{parentName:"p"},".VARNAME"),") \u8bbf\u95ee\u53d8\u91cf\u3002"),(0,l.kt)("p",null,"Go \u7684 ",(0,l.kt)("a",{parentName:"p",href:"https://go-task.github.io/slim-sprig/"},"slim-sprig \u5e93")," \u7684\u6240\u6709\u529f\u80fd\u90fd\u53ef\u7528\u3002 \u4ee5\u4e0b\u793a\u4f8b\u6309\u7167\u7ed9\u5b9a\u683c\u5f0f\u83b7\u53d6\u5f53\u524d\u65e5\u671f\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"Task \u8fd8\u589e\u52a0\u4e86\u4ee5\u4e0b\u529f\u80fd\uff1a"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"OS"),"\uff1a\u8fd4\u56de\u64cd\u4f5c\u7cfb\u7edf\u3002 \u53ef\u80fd\u7684\u503c\u4e3a\u201cwindows\u201d\u3001\u201clinux\u201d\u3001\u201cdarwin\u201d(macOS) \u548c\u201cfreebsd\u201d\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"ARCH"),"\uff1a\u8fd4\u56de Task \u7684\u7f16\u8bd1\u67b6\u6784\u4e3a\uff1a\u201c386\u201d\u3001\u201camd64\u201d\u3001\u201carm\u201d\u6216\u201cs390x\u201d\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"splitLines"),"\uff1a\u62c6\u5206 Unix (\\n) \u548c Windows (\\r\\n) \u6837\u5f0f\u7684\u6362\u884c\u7b26\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"catLines"),"\uff1a\u7528\u7a7a\u683c\u66ff\u6362 Unix (\\n) \u548c Windows (\\r\\n) \u6837\u5f0f\u7684\u6362\u884c\u7b26\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"toSlash"),"\uff1a\u5728 Unix \u4e0a\u4e0d\u6267\u884c\u4efb\u4f55\u64cd\u4f5c\uff0c\u4f46\u5728 Windows \u4e0a\u5c06\u5b57\u7b26\u4e32\u4ece ",(0,l.kt)("inlineCode",{parentName:"li"},"\\")," \u8def\u5f84\u683c\u5f0f\u8f6c\u6362\u4e3a ",(0,l.kt)("inlineCode",{parentName:"li"},"/"),"\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"fromSlash"),"\uff1a\u4e0e ",(0,l.kt)("inlineCode",{parentName:"li"},"toSlash")," \u76f8\u53cd\u3002 \u5728 Unix \u4e0a\u4e0d\u6267\u884c\u4efb\u4f55\u64cd\u4f5c\uff0c\u4f46\u5728 Windows \u4e0a\u5c06\u5b57\u7b26\u4e32\u4ece ",(0,l.kt)("inlineCode",{parentName:"li"},"/")," \u8def\u5f84\u683c\u5f0f\u8f6c\u6362\u4e3a ",(0,l.kt)("inlineCode",{parentName:"li"},"\\"),"\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"exeExt"),"\uff1a\u8fd4\u56de\u5f53\u524d\u64cd\u4f5c\u7cfb\u7edf\u7684\u6b63\u786e\u53ef\u6267\u884c\u6587\u4ef6\u6269\u5c55\u540d\uff08Windows \u4e3a",(0,l.kt)("inlineCode",{parentName:"li"},"\u201c.exe\u201d"),"\uff0c\u5176\u4ed6\u64cd\u4f5c\u7cfb\u7edf\u4e3a",(0,l.kt)("inlineCode",{parentName:"li"},"\u201c\u201d"),"\uff09\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"shellQuote"),"\uff1a\u5f15\u7528\u4e00\u4e2a\u5b57\u7b26\u4e32\u4ee5\u4f7f\u5176\u5728 shell \u811a\u672c\u4e2d\u5b89\u5168\u4f7f\u7528\u3002 Task \u4e3a\u6b64\u4f7f\u7528\u4e86 ",(0,l.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote"},"\u8fd9\u4e2a Go \u51fd\u6570"),"\u3002 \u5047\u5b9a\u4f7f\u7528 Bash \u8bed\u6cd5\u3002"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"splitArgs"),"\uff1a\u5c06\u5b57\u7b26\u4e32\u4f5c\u4e3a\u547d\u4ee4\u7684\u53c2\u6570\u8fdb\u884c\u62c6\u5206\u3002 Task \u4f7f\u7528 ",(0,l.kt)("a",{parentName:"li",href:"https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/shell#Fields"},"\u8fd9\u4e2a Go \u51fd\u6570"))),(0,l.kt)("p",null,"\u793a\u4f8b\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u5e2e\u52a9"},"\u5e2e\u52a9"),(0,l.kt)("p",null,"\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"task --list"),"\uff08\u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"task -l"),"\uff09\u5217\u51fa\u6240\u6709\u5e26\u6709\u63cf\u8ff0\u7684\u4efb\u52a1\u3002 \u4ee5\u4e0b Taskfile\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5c06\u6253\u5370\u4ee5\u4e0b\u8f93\u51fa\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"* build: Build the go binary.\n* test: Run all the go tests.\n")),(0,l.kt)("p",null,"\u5982\u679c\u60a8\u60f3\u67e5\u770b\u6240\u6709\u4efb\u52a1\uff0c\u8fd8\u6709\u4e00\u4e2a ",(0,l.kt)("inlineCode",{parentName:"p"},"--list-all"),"\uff08\u522b\u540d ",(0,l.kt)("inlineCode",{parentName:"p"},"-a"),"\uff09\u6807\u5fd7\u3002"),(0,l.kt)("h2",{id:"\u663e\u793a\u4efb\u52a1\u6458\u8981"},"\u663e\u793a\u4efb\u52a1\u6458\u8981"),(0,l.kt)("p",null,"\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"task --summary task-name")," \u5c06\u663e\u793a\u4efb\u52a1\u7684\u6458\u8981\u3002 \u4ee5\u4e0b Taskfile\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"task --summary release")," \u5c06\u6253\u5370\u4ee5\u4e0b\u8f93\u51fa\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5982\u679c\u7f3a\u5c11\u6458\u8981\uff0c\u5c06\u6253\u5370\u63cf\u8ff0\u3002 \u5982\u679c\u4efb\u52a1\u6ca1\u6709\u6458\u8981\u6216\u63cf\u8ff0\uff0c\u5219\u4f1a\u6253\u5370\u4e00\u6761\u8b66\u544a\u3002"),(0,l.kt)("p",null,"\u8bf7\u6ce8\u610f\uff1a",(0,l.kt)("em",{parentName:"p"},"\u663e\u793a\u6458\u8981\u4e0d\u4f1a\u6267\u884c\u547d\u4ee4"),"\u3002"),(0,l.kt)("h2",{id:"task-\u522b\u540d"},"Task \u522b\u540d"),(0,l.kt)("p",null,"Aliases \u662f task \u7684\u66ff\u4ee3\u540d\u79f0\u3002 \u5b83\u4eec\u53ef\u4ee5\u4f7f\u8fd0\u884c\u5177\u6709\u957f\u540d\u79f0\u6216\u96be\u4ee5\u952e\u5165\u540d\u79f0\u7684 task \u53d8\u5f97\u66f4\u52a0\u5bb9\u6613\u548c\u5feb\u901f\u3002 \u60a8\u53ef\u4ee5\u5728\u547d\u4ee4\u884c\u4e0a\u4f7f\u7528\u5b83\u4eec\uff0c\u5728\u60a8\u7684 Taskfile \u4e2d ",(0,l.kt)("a",{parentName:"p",href:"#%E8%B0%83%E7%94%A8%E5%8F%A6%E4%B8%80%E4%B8%AA-task"},"\u8c03\u7528\u5b50\u4efb\u52a1")," \u65f6\u4ee5\u53ca\u5728 ",(0,l.kt)("a",{parentName:"p",href:"#%E5%8C%85%E5%90%AB%E5%85%B6%E4%BB%96-taskfile"},"\u5305\u542b\u6765\u81ea\u53e6\u4e00\u4e2a Taskfile")," \u7684\u522b\u540d task \u65f6\u3002 \u5b83\u4eec\u4e5f\u53ef\u4ee5\u4e0e ",(0,l.kt)("a",{parentName:"p",href:"#%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E5%88%AB%E5%90%8D"},"\u547d\u540d\u7a7a\u95f4\u522b\u540d")," \u4e00\u8d77\u4f7f\u7528\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u8986\u76d6-task-\u540d\u79f0"},"\u8986\u76d6 Task \u540d\u79f0"),(0,l.kt)("p",null,"\u6709\u65f6\u4f60\u53ef\u80fd\u60f3\u8986\u76d6\u6253\u5370\u5728\u6458\u8981\u4e0a\u7684 task \u540d\u79f0\uff0c\u6700\u65b0\u6d88\u606f\u5230 STDOUT \u7b49\u3002 \u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u4f60\u53ef\u4ee5\u53ea\u8bbe\u7f6e ",(0,l.kt)("inlineCode",{parentName:"p"},"label:"),"\uff0c\u4e5f\u53ef\u4ee5\u7528\u53d8\u91cf\u8fdb\u884c\u63d2\u503c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u9759\u9ed8\u6a21\u5f0f"},"\u9759\u9ed8\u6a21\u5f0f"),(0,l.kt)("p",null,"\u9759\u9ed8\u6a21\u5f0f\u5728 Task \u8fd0\u884c\u547d\u4ee4\u4e4b\u524d\u7981\u7528\u547d\u4ee4\u56de\u663e\u3002 \u5bf9\u4e8e\u4ee5\u4e0b Taskfile\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n")),(0,l.kt)("p",null,"\u901a\u5e38\u8fd9\u5c06\u6253\u5370\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},'echo "Print something"\nPrint something\n')),(0,l.kt)("p",null,"\u5f00\u542f\u9759\u9ed8\u6a21\u5f0f\u540e\uff0c\u5c06\u6253\u5370\u4ee5\u4e0b\u5185\u5bb9\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"Print something\n")),(0,l.kt)("p",null,"\u5f00\u542f\u9759\u9ed8\u6a21\u5f0f\u6709\u56db\u79cd\u65b9\u5f0f\uff1a"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\u5728 cmds \u7ea7\u522b\uff1a")),(0,l.kt)("pre",null,(0,l.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,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\u5728 task \u7ea7\u522b\uff1a")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n silent: true\n")),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\u5728 Taskfile \u5168\u5c40\u7ea7\u522b\uff1a")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\nsilent: true\n\ntasks:\n echo:\n cmds:\n - echo \"Print something\"\n")),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\u6216\u8005\u5168\u5c40\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"li"},"--silent")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"li"},"-s")," \u6807\u5fd7")),(0,l.kt)("p",null,"\u5982\u679c\u60a8\u60f3\u6539\u4e3a\u7981\u6b62 STDOUT\uff0c\u53ea\u9700\u5c06\u547d\u4ee4\u91cd\u5b9a\u5411\u5230 ",(0,l.kt)("inlineCode",{parentName:"p"},"/dev/null"),"\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"\u8bd5\u8fd0\u884c\u6a21\u5f0f"},"\u8bd5\u8fd0\u884c\u6a21\u5f0f"),(0,l.kt)("p",null,"\u8bd5\u8fd0\u884c\u6a21\u5f0f (",(0,l.kt)("inlineCode",{parentName:"p"},"--dry"),") \u7f16\u8bd1\u5e76\u9010\u6b65\u5b8c\u6210\u6bcf\u4e2a task\uff0c\u6253\u5370\u5c06\u8fd0\u884c\u4f46\u4e0d\u6267\u884c\u5b83\u4eec\u7684\u547d\u4ee4\u3002 \u8fd9\u5bf9\u4e8e\u8c03\u8bd5\u60a8\u7684 Taskfile \u5f88\u6709\u7528\u3002"),(0,l.kt)("h2",{id:"\u5ffd\u7565\u9519\u8bef"},"\u5ffd\u7565\u9519\u8bef"),(0,l.kt)("p",null,"\u60a8\u53ef\u4ee5\u9009\u62e9\u5728\u547d\u4ee4\u6267\u884c\u671f\u95f4\u5ffd\u7565\u9519\u8bef\u3002 \u7ed9\u5b9a\u4ee5\u4e0b Taskfile\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\ntasks:\n echo:\n cmds:\n - exit 1\n - echo \"Hello World\"\n")),(0,l.kt)("p",null,"Task \u5c06\u5728\u8fd0\u884c ",(0,l.kt)("inlineCode",{parentName:"p"},"exit 1")," \u540e\u4e2d\u6b62\u6267\u884c\uff0c\u56e0\u4e3a\u72b6\u6001\u4ee3\u7801 ",(0,l.kt)("inlineCode",{parentName:"p"},"1")," \u4ee3\u8868 ",(0,l.kt)("inlineCode",{parentName:"p"},"EXIT_FAILURE"),"\u3002 \u4f46\u662f\uff0c\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"ignore_error")," \u7ee7\u7eed\u6267\u884c\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u4e5f\u53ef\u4ee5\u4e3a task \u8bbe\u7f6e ",(0,l.kt)("inlineCode",{parentName:"p"},"ignore_error"),"\uff0c\u8fd9\u610f\u5473\u7740\u6240\u6709\u547d\u4ee4\u7684\u9519\u8bef\u90fd\u5c06\u88ab\u5ffd\u7565\u3002 \u4e0d\u8fc7\uff0c\u8bf7\u8bb0\u4f4f\uff0c\u6b64\u9009\u9879\u4e0d\u4f1a\u4f20\u64ad\u5230\u7531 deps \u6216 cmds \u8c03\u7528\u7684\u5176\u4ed6 task\uff01"),(0,l.kt)("h2",{id:"\u8f93\u51fa\u8bed\u6cd5"},"\u8f93\u51fa\u8bed\u6cd5"),(0,l.kt)("p",null,"\u9ed8\u8ba4\u60c5\u51b5\u4e0b\uff0cTask \u53ea\u662f\u5c06\u6b63\u5728\u8fd0\u884c\u7684\u547d\u4ee4\u7684 STDOUT \u548c STDERR \u5b9e\u65f6\u91cd\u5b9a\u5411\u5230 shell\u3002 \u8fd9\u6709\u5229\u4e8e\u901a\u8fc7\u547d\u4ee4\u6253\u5370\u65e5\u5fd7\u8bb0\u5f55\u7684\u5b9e\u65f6\u53cd\u9988\uff0c\u4f46\u5982\u679c\u540c\u65f6\u8fd0\u884c\u591a\u4e2a\u547d\u4ee4\u5e76\u6253\u5370\u5927\u91cf\u5185\u5bb9\uff0c\u8f93\u51fa\u53ef\u80fd\u4f1a\u53d8\u5f97\u6df7\u4e71\u3002"),(0,l.kt)("p",null,"\u4e3a\u4e86\u4f7f\u5176\u66f4\u5177\u53ef\u5b9a\u5236\u6027\uff0c\u76ee\u524d\u60a8\u53ef\u4ee5\u9009\u62e9\u4e09\u79cd\u4e0d\u540c\u7684\u8f93\u51fa\u9009\u9879\uff1a"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"interleaved")," (\u9ed8\u8ba4)"),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"group")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("inlineCode",{parentName:"li"},"prefixed"))),(0,l.kt)("p",null,"\u8981\u9009\u62e9\u53e6\u4e00\u4e2a\uff0c\u53ea\u9700\u5728 Taskfile \u6839\u76ee\u5f55\u4e2d\u8bbe\u7f6e\u5373\u53ef\uff1a"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-yaml"},"version: '3'\n\noutput: 'group'\n\ntasks:\n # ...\n")),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"group")," \u8f93\u51fa\u5c06\u5728\u547d\u4ee4\u5b8c\u6210\u540e\u6253\u5370\u4e00\u6b21\u547d\u4ee4\u7684\u5168\u90e8\u8f93\u51fa\uff0c\u56e0\u6b64\u60a8\u4e0d\u4f1a\u5bf9\u9700\u8981\u5f88\u957f\u65f6\u95f4\u8fd0\u884c\u7684\u547d\u4ee4\u6709\u5b9e\u65f6\u53cd\u9988\u3002"),(0,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"group")," \u8f93\u51fa\u65f6\uff0c\u60a8\u53ef\u4ee5\u9009\u62e9\u63d0\u4f9b\u6a21\u677f\u5316\u6d88\u606f\u4ee5\u5728\u7ec4\u7684\u5f00\u59cb\u548c\u7ed3\u675f\u5904\u6253\u5370\u3002 \u8fd9\u5bf9\u4e8e\u6307\u793a CI \u7cfb\u7edf\u5bf9\u7ed9\u5b9a\u4efb\u52a1\u7684\u6240\u6709\u8f93\u51fa\u8fdb\u884c\u5206\u7ec4\u975e\u5e38\u6709\u7528\uff0c\u4f8b\u5982\u4f7f\u7528 ",(0,l.kt)("a",{parentName:"p",href:"https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#grouping-log-lines"},"GitHub Actions \u7684 ",(0,l.kt)("inlineCode",{parentName:"a"},"::group::")," \u547d\u4ee4")," \u6216 ",(0,l.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"),"\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"$ task default\n::group::default\nHello, World!\n::endgroup::\n")),(0,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"group")," \u8f93\u51fa\u65f6\uff0c\u5982\u679c\u6ca1\u6709\u5931\u8d25\uff08\u96f6\u9000\u51fa\u4ee3\u7801\uff09\uff0c\u60a8\u53ef\u4ee5\u5728\u6807\u51c6\u8f93\u51fa\u548c\u6807\u51c6\u9519\u8bef\u4e0a\u6267\u884c\u547d\u4ee4\u7684\u8f93\u51fa\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("pre",null,(0,l.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,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"prefix")," \u8f93\u51fa\u5c06\u4e3a\u547d\u4ee4\u6253\u5370\u7684\u6bcf\u4e00\u884c\u6dfb\u52a0\u524d\u7f00 ",(0,l.kt)("inlineCode",{parentName:"p"},"[task-name]")," \u4f5c\u4e3a\u524d\u7f00\uff0c\u4f46\u60a8\u53ef\u4ee5\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"prefix:")," \u5c5e\u6027\u81ea\u5b9a\u4e49\u547d\u4ee4\u7684\u524d\u7f00\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"$ task default\n[print-foo] foo\n[print-bar] bar\n[print-baz] baz\n")),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},(0,l.kt)("inlineCode",{parentName:"p"},"output")," \u9009\u9879\u4e5f\u53ef\u4ee5\u7531 ",(0,l.kt)("inlineCode",{parentName:"p"},"--output")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"-o")," \u6807\u5fd7\u6307\u5b9a\u3002")),(0,l.kt)("h2",{id:"\u4ea4\u4e92\u5f0f-cli-\u5e94\u7528"},"\u4ea4\u4e92\u5f0f CLI \u5e94\u7528"),(0,l.kt)("p",null,"Task \u6267\u884c\u5305\u542b\u4ea4\u4e92\u5f0f\u7684\u547d\u4ee4\u65f6\u6709\u65f6\u4f1a\u51fa\u73b0\u5947\u602a\u7684\u7ed3\u679c\uff0c \u5c24\u5176\u5f53 ",(0,l.kt)("a",{parentName:"p",href:"#%E8%BE%93%E5%87%BA%E8%AF%AD%E6%B3%95"},"\u8f93\u51fa\u6a21\u5f0f")," \u8bbe\u7f6e\u7684\u4e0d\u662f ",(0,l.kt)("inlineCode",{parentName:"p"},"interleaved")," \uff08\u9ed8\u8ba4\uff09\uff0c \u6216\u8005\u5f53\u4ea4\u4e92\u5f0f\u5e94\u7528\u4e0e\u5176\u5b83 task \u5e76\u53d1\u6267\u884c\u65f6\u3002"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"interactive: true")," \u544a\u8bc9 Task \u8fd9\u662f\u4e00\u4e2a\u4ea4\u4e92\u5f0f\u5e94\u7528\u7a0b\u5e8f\uff0cTask \u5c06\u5c1d\u8bd5\u9488\u5bf9\u5b83\u8fdb\u884c\u4f18\u5316\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("p",null,"\u5982\u679c\u60a8\u5728\u901a\u8fc7 Task \u8fd0\u884c\u4ea4\u4e92\u5f0f\u5e94\u7528\u7a0b\u5e8f\u65f6\u4ecd\u7136\u9047\u5230\u95ee\u9898\uff0c\u8bf7\u6253\u5f00\u4e00\u4e2a\u5173\u4e8e\u5b83\u7684 Issue\u3002"),(0,l.kt)("h2",{id:"\u77ed-task-\u8bed\u6cd5"},"\u77ed Task \u8bed\u6cd5"),(0,l.kt)("p",null,"\u4ece Task v3 \u5f00\u59cb\uff0c\u5982\u679c task \u5177\u6709\u9ed8\u8ba4\u8bbe\u7f6e\uff08\u4f8b\u5982\uff1a\u6ca1\u6709\u81ea\u5b9a\u4e49 ",(0,l.kt)("inlineCode",{parentName:"p"},"env:"),"\u3001",(0,l.kt)("inlineCode",{parentName:"p"},"vars:"),"\u3001",(0,l.kt)("inlineCode",{parentName:"p"},"desc:"),"\u3001",(0,l.kt)("inlineCode",{parentName:"p"},"silent:")," \u7b49\uff09\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u4f7f\u7528\u66f4\u77ed\u7684\u8bed\u6cd5\u7f16\u5199task\uff1a"),(0,l.kt)("pre",null,(0,l.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,l.kt)("h2",{id:"set-\u548c-shopt"},(0,l.kt)("inlineCode",{parentName:"h2"},"set")," \u548c ",(0,l.kt)("inlineCode",{parentName:"h2"},"shopt")),(0,l.kt)("p",null,"\u53ef\u4ee5\u4e3a ",(0,l.kt)("a",{parentName:"p",href:"https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html"},(0,l.kt)("inlineCode",{parentName:"a"},"set"))," \u548c ",(0,l.kt)("a",{parentName:"p",href:"https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html"},(0,l.kt)("inlineCode",{parentName:"a"},"shopt"))," \u5185\u7f6e\u51fd\u6570\u6307\u5b9a\u9009\u9879\u3002 \u8fd9\u53ef\u4ee5\u5728\u5168\u5c40\u3001task \u6216\u547d\u4ee4\u7ea7\u522b\u6dfb\u52a0\u3002"),(0,l.kt)("pre",null,(0,l.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,l.kt)("admonition",{type:"info"},(0,l.kt)("p",{parentName:"admonition"},"\u8bf7\u8bb0\u4f4f\uff0c\u5e76\u975e\u6240\u6709\u9009\u9879\u5728 Task \u4f7f\u7528\u7684 ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/mvdan/sh"},"shell \u89e3\u91ca\u5668\u5e93")," \u4e2d\u90fd\u53ef\u7528\u3002")),(0,l.kt)("h2",{id:"\u89c2\u5bdf-task"},"\u89c2\u5bdf task"),(0,l.kt)("p",null,"\u4f7f\u7528 ",(0,l.kt)("inlineCode",{parentName:"p"},"--watch")," \u6216 ",(0,l.kt)("inlineCode",{parentName:"p"},"-w")," \u53c2\u6570\u53ef\u4ee5\u89c2\u5bdf\u6587\u4ef6\u53d8\u5316\uff0c\u7136\u540e\u91cd\u65b0\u6267\u884c task\u3002 \u8fd9\u9700\u8981\u914d\u7f6e ",(0,l.kt)("inlineCode",{parentName:"p"},"sources")," \u5c5e\u6027\uff0ctask \u624d\u77e5\u9053\u89c2\u5bdf\u54ea\u4e9b\u6587\u4ef6\u3002"),(0,l.kt)("p",null,"\u9ed8\u8ba4\u76d1\u63a7\u7684\u65f6\u95f4\u95f4\u9694\u662f 5 \u79d2\uff0c\u4f46\u53ef\u4ee5\u901a\u8fc7 Taskfile \u4e2d\u6839\u5c5e\u6027 ",(0,l.kt)("inlineCode",{parentName:"p"},"interval: '500ms'")," \u8bbe\u7f6e\uff0c\u4e5f\u53ef\u4ee5\u901a\u8fc7\u547d\u4ee4\u884c \u53c2\u6570 ",(0,l.kt)("inlineCode",{parentName:"p"},"--interval=500ms")," \u8bbe\u7f6e\u3002"))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/zh-Hans/assets/js/1fd60438.357460eb.js b/zh-Hans/assets/js/1fd60438.9b55ac4e.js similarity index 99% rename from zh-Hans/assets/js/1fd60438.357460eb.js rename to zh-Hans/assets/js/1fd60438.9b55ac4e.js index 965c9b74..080494cf 100644 --- a/zh-Hans/assets/js/1fd60438.357460eb.js +++ b/zh-Hans/assets/js/1fd60438.9b55ac4e.js @@ -1 +1 @@ -"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[634],{3905:function(e,n,t){t.d(n,{Zo:function(){return k},kt:function(){return d}});var a=t(7294);function l(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(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||(l[t]=e[t]);return l}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(l[t]=e[t])}return l}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},k=function(e){var n=p(e.components);return a.createElement(s.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,l=e.mdxType,r=e.originalType,s=e.parentName,k=o(e,["components","mdxType","originalType","parentName"]),u=p(t),c=l,d=u["".concat(s,".").concat(c)]||u[c]||m[c]||r;return t?a.createElement(d,i(i({ref:n},k),{},{components:t})):a.createElement(d,i({ref:n},k))}));function d(e,n){var t=arguments,l=n&&n.mdxType;if("string"==typeof e||l){var r=t.length,i=new Array(r);i[0]=c;var o={};for(var s in n)hasOwnProperty.call(n,s)&&(o[s]=n[s]);o.originalType=e,o[u]="string"==typeof e?e:l,i[1]=o;for(var p=2;p=0||(l[t]=e[t]);return l}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(l[t]=e[t])}return l}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},k=function(e){var n=p(e.components);return a.createElement(s.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,l=e.mdxType,r=e.originalType,s=e.parentName,k=o(e,["components","mdxType","originalType","parentName"]),u=p(t),c=l,d=u["".concat(s,".").concat(c)]||u[c]||m[c]||r;return t?a.createElement(d,i(i({ref:n},k),{},{components:t})):a.createElement(d,i({ref:n},k))}));function d(e,n){var t=arguments,l=n&&n.mdxType;if("string"==typeof e||l){var r=t.length,i=new Array(r);i[0]=c;var o={};for(var s in n)hasOwnProperty.call(n,s)&&(o[s]=n[s]);o.originalType=e,o[u]="string"==typeof e?e:l,i[1]=o;for(var p=2;p=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}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",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),c=u(n),f=a,d=c["".concat(s,".").concat(f)]||c[f]||m[f]||l;return n?r.createElement(d,i(i({ref:t},p),{},{components:n})):r.createElement(d,i({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,i=new Array(l);i[0]=f;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[c]="string"==typeof e?e:a,i[1]=o;for(var u=2;u')," \u4e4b\u7c7b\u7684\u4e1c\u897f\u6765\u68c0\u6d4b windows \u5e76\u76f4\u63a5\u5728 Powershell \u4e2d\u8fd0\u884c\u547d\u4ee4\u3002"),(0,a.kt)("li",{parentName:"ul"},"\u5728 Windows \u4e0a\u4f7f\u7528\u652f\u6301\u8fd9\u4e9b\u547d\u4ee4\u7684 shell \u4f5c\u4e3a\u5185\u7f6e\u547d\u4ee4\uff0c\u4f8b\u5982 ",(0,a.kt)("a",{parentName:"li",href:"https://gitforwindows.org/"},"Git Bash")," \u6216 ",(0,a.kt)("a",{parentName:"li",href:"https://learn.microsoft.com/en-us/windows/wsl/install"},"WSL"),"\u3002")),(0,a.kt)("p",null,"\u6211\u4eec\u5e0c\u671b\u5bf9 Task \u7684\u8fd9\u4e00\u90e8\u5206\u8fdb\u884c\u6539\u8fdb\uff0c\u4e0b\u9762\u7684 Issue \u4f1a\u8ddf\u8e2a\u8fd9\u9879\u5de5\u4f5c\u3002 \u975e\u5e38\u6b22\u8fce\u5efa\u8bbe\u6027\u7684\u610f\u89c1\u548c\u8d21\u732e\uff01"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/go-task/task/issues/197"},"#197")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/mvdan/sh/issues/93"},"mvdan/sh#93")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/mvdan/sh/issues/97"},"mvdan/sh#97"))))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[889],{3905:function(e,t,n){n.d(t,{Zo:function(){return p},kt:function(){return d}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(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||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}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",m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),c=u(n),f=a,d=c["".concat(s,".").concat(f)]||c[f]||m[f]||l;return n?r.createElement(d,i(i({ref:t},p),{},{components:n})):r.createElement(d,i({ref:t},p))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,i=new Array(l);i[0]=f;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[c]="string"==typeof e?e:a,i[1]=o;for(var u=2;u')," \u4e4b\u7c7b\u7684\u4e1c\u897f\u6765\u68c0\u6d4b windows \u5e76\u76f4\u63a5\u5728 Powershell \u4e2d\u8fd0\u884c\u547d\u4ee4\u3002"),(0,a.kt)("li",{parentName:"ul"},"\u5728 Windows \u4e0a\u4f7f\u7528\u652f\u6301\u8fd9\u4e9b\u547d\u4ee4\u7684 shell \u4f5c\u4e3a\u5185\u7f6e\u547d\u4ee4\uff0c\u4f8b\u5982 ",(0,a.kt)("a",{parentName:"li",href:"https://gitforwindows.org/"},"Git Bash")," \u6216 ",(0,a.kt)("a",{parentName:"li",href:"https://learn.microsoft.com/en-us/windows/wsl/install"},"WSL"),"\u3002")),(0,a.kt)("p",null,"\u6211\u4eec\u5e0c\u671b\u5bf9 Task \u7684\u8fd9\u4e00\u90e8\u5206\u8fdb\u884c\u6539\u8fdb\uff0c\u4e0b\u9762\u7684 Issue \u4f1a\u8ddf\u8e2a\u8fd9\u9879\u5de5\u4f5c\u3002 \u975e\u5e38\u6b22\u8fce\u5efa\u8bbe\u6027\u7684\u610f\u89c1\u548c\u8d21\u732e\uff01"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/go-task/task/issues/197"},"#197")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/mvdan/sh/issues/93"},"mvdan/sh#93")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://github.com/mvdan/sh/issues/97"},"mvdan/sh#97"))))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/zh-Hans/assets/js/5b2a233e.584908ce.js b/zh-Hans/assets/js/5b2a233e.584908ce.js new file mode 100644 index 00000000..2febe0b4 --- /dev/null +++ b/zh-Hans/assets/js/5b2a233e.584908ce.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[863],{3905:function(M,N,D){D.d(N,{Zo:function(){return E},kt:function(){return t}});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 z(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 z=Object.getOwnPropertySymbols(M);for(j=0;j=0||Object.prototype.propertyIsEnumerable.call(M,D)&&(T[D]=M[D])}return T}var u=j.createContext({}),A=function(M){var N=j.useContext(u),D=N;return M&&(D="function"==typeof M?M(N):I(I({},N),M)),D},E=function(M){var N=A(M.components);return j.createElement(u.Provider,{value:N},M.children)},O="mdxType",y={inlineCode:"code",wrapper:function(M){var N=M.children;return j.createElement(j.Fragment,{},N)}},e=j.forwardRef((function(M,N){var D=M.components,T=M.mdxType,z=M.originalType,u=M.parentName,E=g(M,["components","mdxType","originalType","parentName"]),O=A(D),e=T,t=O["".concat(u,".").concat(e)]||O[e]||y[e]||z;return D?j.createElement(t,I(I({ref:N},E),{},{components:D})):j.createElement(t,I({ref:N},E))}));function t(M,N){var D=arguments,T=N&&N.mdxType;if("string"==typeof M||T){var z=D.length,I=new Array(z);I[0]=e;var g={};for(var u in N)hasOwnProperty.call(N,u)&&(g[u]=N[u]);g.originalType=M,g[O]="string"==typeof M?M:T,I[1]=g;for(var A=2;A=0||(T[D]=M[D]);return T}(M,N);if(Object.getOwnPropertySymbols){var z=Object.getOwnPropertySymbols(M);for(j=0;j=0||Object.prototype.propertyIsEnumerable.call(M,D)&&(T[D]=M[D])}return T}var u=j.createContext({}),A=function(M){var N=j.useContext(u),D=N;return M&&(D="function"==typeof M?M(N):I(I({},N),M)),D},E=function(M){var N=A(M.components);return j.createElement(u.Provider,{value:N},M.children)},O="mdxType",y={inlineCode:"code",wrapper:function(M){var N=M.children;return j.createElement(j.Fragment,{},N)}},e=j.forwardRef((function(M,N){var D=M.components,T=M.mdxType,z=M.originalType,u=M.parentName,E=g(M,["components","mdxType","originalType","parentName"]),O=A(D),e=T,t=O["".concat(u,".").concat(e)]||O[e]||y[e]||z;return D?j.createElement(t,I(I({ref:N},E),{},{components:D})):j.createElement(t,I({ref:N},E))}));function t(M,N){var D=arguments,T=N&&N.mdxType;if("string"==typeof M||T){var z=D.length,I=new Array(z);I[0]=e;var g={};for(var u in N)hasOwnProperty.call(N,u)&&(g[u]=N[u]);g.originalType=M,g[O]="string"==typeof M?M:T,I[1]=g;for(var A=2;A=0||(s[a]=t[a]);return s}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(s[a]=t[a])}return s}var o=i.createContext({}),k=function(t){var e=i.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},h=function(t){var e=k(t.components);return i.createElement(o.Provider,{value:e},t.children)},p="mdxType",m={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},u=i.forwardRef((function(t,e){var a=t.components,s=t.mdxType,n=t.originalType,o=t.parentName,h=r(t,["components","mdxType","originalType","parentName"]),p=k(a),u=s,d=p["".concat(o,".").concat(u)]||p[u]||m[u]||n;return a?i.createElement(d,l(l({ref:e},h),{},{components:a})):i.createElement(d,l({ref:e},h))}));function d(t,e){var a=arguments,s=e&&e.mdxType;if("string"==typeof t||s){var n=a.length,l=new Array(n);l[0]=u;var r={};for(var o in e)hasOwnProperty.call(e,o)&&(r[o]=e[o]);r.originalType=t,r[p]="string"==typeof t?t:s,l[1]=r;for(var k=2;k=0||(s[a]=t[a]);return s}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(s[a]=t[a])}return s}var o=i.createContext({}),k=function(t){var e=i.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):l(l({},e),t)),a},h=function(t){var e=k(t.components);return i.createElement(o.Provider,{value:e},t.children)},p="mdxType",m={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},u=i.forwardRef((function(t,e){var a=t.components,s=t.mdxType,n=t.originalType,o=t.parentName,h=r(t,["components","mdxType","originalType","parentName"]),p=k(a),u=s,d=p["".concat(o,".").concat(u)]||p[u]||m[u]||n;return a?i.createElement(d,l(l({ref:e},h),{},{components:a})):i.createElement(d,l({ref:e},h))}));function d(t,e){var a=arguments,s=e&&e.mdxType;if("string"==typeof t||s){var n=a.length,l=new Array(n);l[0]=u;var r={};for(var o in e)hasOwnProperty.call(e,o)&&(r[o]=e[o]);r.originalType=t,r[p]="string"==typeof t?t:s,l[1]=r;for(var k=2;k=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({}),k=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=k(t.components);return a.createElement(p.Provider,{value:e},t.children)},N="mdxType",o={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"]),N=k(n),u=l,g=N["".concat(p,".").concat(u)]||N[u]||o[u]||r;return n?a.createElement(g,i(i({ref:e},m),{},{components:n})):a.createElement(g,i({ref:e},m))}));function g(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[N]="string"==typeof t?t:l,i[1]=d;for(var k=2;k=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({}),m=function(t){var e=a.useContext(p),n=e;return t&&(n="function"==typeof t?t(e):i(i({},e),t)),n},k=function(t){var e=m(t.components);return a.createElement(p.Provider,{value:e},t.children)},N="mdxType",o={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,k=d(t,["components","mdxType","originalType","parentName"]),N=m(n),u=l,g=N["".concat(p,".").concat(u)]||N[u]||o[u]||r;return n?a.createElement(g,i(i({ref:e},k),{},{components:n})):a.createElement(g,i({ref:e},k))}));function g(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[N]="string"==typeof t?t:l,i[1]=d;for(var m=2;m=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 s=a.createContext({}),p=function(e){var t=a.useContext(s),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(s.Provider,{value:t},e.children)},k="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),k=p(n),c=r,d=k["".concat(s,".").concat(c)]||k[c]||m[c]||i;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,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[k]="string"==typeof e?e:r,o[1]=l;for(var p=2;p "),"\u3002"),(0,r.kt)("p",null,"\u8981\u8fd0\u884c Task for Visual Studio Code\uff0c\u60a8\u53ef\u4ee5\u5728 VSCode \u4e2d\u6253\u5f00\u9879\u76ee\u5e76\u6309 F5\uff08\u6216\u4efb\u4f55\u60a8\u8bbe\u7f6e\u7ed1\u5b9a\u7684\u8c03\u8bd5\u952e\uff09\u3002 \u8fd9\u5c06\u6253\u5f00\u4e00\u4e2a\u65b0\u7684 VSCode \u7a97\u53e3\uff0c\u6269\u5c55\u6b63\u5728\u8fd0\u884c\u3002 \u5efa\u8bae\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u8fdb\u884c\u8c03\u8bd5\uff0c\u56e0\u4e3a\u5b83\u5141\u8bb8\u60a8\u8bbe\u7f6e\u65ad\u70b9\u5e76\u5355\u6b65\u6267\u884c\u4ee3\u7801\u3002 \u6216\u8005\uff0c\u60a8\u53ef\u4ee5\u8fd0\u884c ",(0,r.kt)("inlineCode",{parentName:"p"},"task package"),"\uff0c\u8fd9\u5c06\u751f\u6210\u4e00\u4e2a\u53ef\u7528\u4e8e\u624b\u52a8\u5b89\u88c5\u6269\u5c55\u7684 ",(0,r.kt)("inlineCode",{parentName:"p"},".vsix")," \u6587\u4ef6\u3002"),(0,r.kt)("h3",{id:"\u66f4\u65b0\u6587\u6863"},"\u66f4\u65b0\u6587\u6863"),(0,r.kt)("p",null,"Task \u4f7f\u7528 ",(0,r.kt)("a",{parentName:"p",href:"https://docusaurus.io"},"Docusaurus")," \u6765\u6258\u7ba1\u6587\u6863\u670d\u52a1\u5668\u3002 \u6b64\u4ee3\u7801\u4f4d\u4e8e Task \u6838\u5fc3\u5b58\u50a8\u5e93\u4e2d\u3002 \u8fd9\u53ef\u4ee5\u901a\u8fc7\u4f7f\u7528 ",(0,r.kt)("inlineCode",{parentName:"p"},"task docs"),"\uff08\u9700\u8981 ",(0,r.kt)("inlineCode",{parentName:"p"},"nodejs")," \u548c ",(0,r.kt)("inlineCode",{parentName:"p"},"yarn"),"\uff09\u5728\u672c\u5730\u8bbe\u7f6e\u548c\u8fd0\u884c\u3002 \u6240\u6709\u5185\u5bb9\u5747\u4f7f\u7528 Markdown \u7f16\u5199\uff0c\u4f4d\u4e8e ",(0,r.kt)("inlineCode",{parentName:"p"},"docs/docs")," \u76ee\u5f55\u4e2d\u3002 \u6240\u6709 Markdown \u6587\u6863\u90fd\u5e94\u6709 80 \u4e2a\u5b57\u7b26\u7684\u6362\u884c\u9650\u5236\uff08\u7531 Prettier \u5f3a\u5236\u6267\u884c\uff09\u3002"),(0,r.kt)("p",null,"\u8fdb\u884c\u53d8\u66f4\u65f6\uff0c\u8bf7\u8003\u8651\u662f\u5426\u6709\u5fc5\u8981\u66f4\u6539 ",(0,r.kt)("a",{parentName:"p",href:"/zh-Hans/usage/"},"\u4f7f\u7528\u6307\u5357"),"\u3002 \u672c\u6587\u6863\u5305\u542b\u6709\u5173\u5982\u4f55\u4f7f\u7528\u4efb\u52a1\u529f\u80fd\u7684\u8bf4\u660e\u548c\u793a\u4f8b\u3002 \u5982\u679c\u60a8\u8981\u6dfb\u52a0\u65b0\u529f\u80fd\uff0c\u8bf7\u5c1d\u8bd5\u627e\u5230\u5408\u9002\u7684\u4f4d\u7f6e\u6765\u6dfb\u52a0\u65b0\u90e8\u5206\u3002 \u5982\u679c\u60a8\u8981\u66f4\u65b0\u73b0\u6709\u529f\u80fd\uff0c\u8bf7\u786e\u4fdd\u6587\u6863\u548c\u6240\u6709\u793a\u4f8b\u90fd\u662f\u6700\u65b0\u7684\u3002 \u786e\u4fdd\u4efb\u4f55\u793a\u4f8b\u90fd\u9075\u5faa ",(0,r.kt)("a",{parentName:"p",href:"/zh-Hans/styleguide/"},"Taskfile \u98ce\u683c\u6307\u5357"),"\u3002"),(0,r.kt)("p",null,"\u5982\u679c\u60a8\u6dfb\u52a0\u4e86\u65b0\u5b57\u6bb5\u3001\u547d\u4ee4\u6216\u6807\u5fd7\uff0c\u8bf7\u786e\u4fdd\u5c06\u5176\u6dfb\u52a0\u5230 ",(0,r.kt)("a",{parentName:"p",href:"/zh-Hans/api/"},"API \u53c2\u8003")," \u4e2d\u3002 \u8fd8\u9700\u8981\u5c06\u65b0\u5b57\u6bb5\u6dfb\u52a0\u5230 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/blob/main/docs/static/schema.json"},"JSON Schema")," \u4e2d\u3002 API \u53c2\u8003\u548c schema \u4e2d\u7684\u5b57\u6bb5\u63cf\u8ff0\u5e94\u8be5\u5339\u914d\u3002"),(0,r.kt)("h3",{id:"\u7f16\u5199\u6d4b\u8bd5"},"\u7f16\u5199\u6d4b\u8bd5"),(0,r.kt)("p",null,"\u8bb8\u591a Task \u7684\u6d4b\u8bd5\u90fd\u4fdd\u5b58\u5728\u9879\u76ee\u6839\u76ee\u5f55\u4e0b\u7684 ",(0,r.kt)("inlineCode",{parentName:"p"},"task_test.go")," \u6587\u4ef6\u4e2d\uff0c\u8fd9\u4e5f\u662f\u60a8\u6700\u6709\u53ef\u80fd\u60f3\u8981\u6dfb\u52a0\u65b0\u6d4b\u8bd5\u7684\u5730\u65b9\u3002 \u5927\u591a\u6570\u8fd9\u4e9b\u6d4b\u8bd5\u5728 ",(0,r.kt)("inlineCode",{parentName:"p"},"testdata")," \u76ee\u5f55\u4e2d\u4e5f\u6709\u4e00\u4e2a\u5b50\u76ee\u5f55\uff0c\u5176\u4e2d\u5b58\u50a8\u4e86\u8fd0\u884c\u6d4b\u8bd5\u6240\u9700\u7684\u4efb\u4f55 Taskfiles/\u6570\u636e\u3002"),(0,r.kt)("p",null,"\u8fdb\u884c\u66f4\u6539\u65f6\uff0c\u8bf7\u8003\u8651\u662f\u5426\u9700\u8981\u6dfb\u52a0\u65b0\u7684\u6d4b\u8bd5\u3002 \u8fd9\u4e9b\u6d4b\u8bd5\u5e94\u786e\u4fdd\u60a8\u6dfb\u52a0\u7684\u529f\u80fd\u5728\u672a\u6765\u6301\u7eed\u5de5\u4f5c\u3002 \u5982\u679c\u60a8\u66f4\u6539\u4e86 Task \u7684\u884c\u4e3a\uff0c\u5219\u73b0\u6709\u6d4b\u8bd5\u4e5f\u53ef\u80fd\u9700\u8981\u66f4\u65b0\u3002"),(0,r.kt)("p",null,"\u60a8\u8fd8\u53ef\u4ee5\u8003\u8651\u4e3a\u60a8\u6dfb\u52a0\u7684\u4efb\u4f55\u65b0\u529f\u80fd\u6dfb\u52a0\u5355\u5143\u6d4b\u8bd5\u3002 \u5355\u5143\u6d4b\u8bd5\u5e94\u9075\u5faa Go \u7ea6\u5b9a\uff0c\u5373\u4f4d\u4e8e\u4e0e\u88ab\u6d4b\u8bd5\u4ee3\u7801\u76f8\u540c\u7684\u5305\u4e2d\u540d\u4e3a ",(0,r.kt)("inlineCode",{parentName:"p"},"*_test.go")," \u7684\u6587\u4ef6\u4e2d\u3002"),(0,r.kt)("h2",{id:"3-\u63d0\u4ea4\u4ee3\u7801"},"3. \u63d0\u4ea4\u4ee3\u7801"),(0,r.kt)("p",null,"\u5c1d\u8bd5\u7f16\u5199\u6709\u610f\u4e49\u7684\u63d0\u4ea4\u6d88\u606f\u5e76\u907f\u514d\u5728 PR \u4e0a\u6709\u592a\u591a\u63d0\u4ea4\u3002 \u5927\u591a\u6570 PR \u5e94\u8be5\u6709\u4e00\u4e2a\u5355\u4e00\u7684\u63d0\u4ea4\uff08\u5c3d\u7ba1\u5bf9\u4e8e\u66f4\u5927\u7684 PR \u5c06\u5b83\u5206\u6210\u51e0\u4e2a\u53ef\u80fd\u662f\u5408\u7406\u7684\uff09\u3002 Git squash(\u5e76\u548c) \u548c rebase(\u53d8\u57fa) \u662f\u4f60\u7684\u597d\u670b\u53cb!"),(0,r.kt)("p",null,"\u5982\u679c\u60a8\u4e0d\u786e\u5b9a\u5982\u4f55\u683c\u5f0f\u5316\u63d0\u4ea4\u6d88\u606f\uff0c\u8bf7\u67e5\u770b ",(0,r.kt)("a",{parentName:"p",href:"https://www.conventionalcommits.org"},"\u7ea6\u5b9a\u5f0f\u63d0\u4ea4"),"\u3002 \u8fd9\u79cd\u98ce\u683c\u4e0d\u662f\u5f3a\u5236\u7684\uff0c\u4f46\u5b83\u662f\u4f7f\u60a8\u7684\u63d0\u4ea4\u6d88\u606f\u66f4\u5177\u53ef\u8bfb\u6027\u548c\u4e00\u81f4\u6027\u7684\u597d\u65b9\u6cd5\u3002"),(0,r.kt)("h2",{id:"4-\u63d0\u4ea4-pr"},"4. \u63d0\u4ea4 PR"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"\u63cf\u8ff0\u53d8\u66f4")," - \u786e\u4fdd\u60a8\u63d0\u4f9b\u5bf9\u66f4\u6539\u7684\u5168\u9762\u63cf\u8ff0\u3002"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Issue/PR \u94fe\u63a5")," - \u94fe\u63a5\u5230\u4e4b\u524d\u76f8\u5173\u7684 Issue \u6216 PR\u3002 \u8bf7\u63cf\u8ff0\u5f53\u524d\u5de5\u4f5c\u4e0e\u4e4b\u524d\u7684\u4e0d\u540c\u4e4b\u5904\u3002"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"\u793a\u4f8b")," - \u6dfb\u52a0\u60a8\u8ba4\u4e3a\u6709\u52a9\u4e8e\u5c55\u793a\u66f4\u6539\u6548\u679c\u7684\u4efb\u4f55\u793a\u4f8b\u6216\u5c4f\u5e55\u622a\u56fe\u3002"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"PR \u8349\u6848")," - \u5982\u679c\u53d8\u66f4\u8fd8\u672a\u5b8c\u6210\uff0c\u4f46\u60a8\u60f3\u8ba8\u8bba\u5b83\u4eec\uff0c\u8bf7\u5c06 PR \u4f5c\u4e3a\u8349\u7a3f\u6253\u5f00\u5e76\u6dfb\u52a0\u8bc4\u8bba\u4ee5\u5f00\u59cb\u8ba8\u8bba\u3002 \u4f7f\u7528\u8bc4\u8bba\u800c\u4e0d\u662f PR \u63cf\u8ff0\u5141\u8bb8\u7a0d\u540e\u66f4\u65b0\u63cf\u8ff0\uff0c\u540c\u65f6\u4fdd\u7559\u8ba8\u8bba\u3002")),(0,r.kt)("h2",{id:"\u5e38\u89c1\u95ee\u9898"},"\u5e38\u89c1\u95ee\u9898"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"\u6211\u60f3\u8d21\u732e\uff0c\u6211\u4ece\u54ea\u91cc\u5f00\u59cb\uff1f")),(0,r.kt)("p",null,"\u67e5\u770b ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/issues"},"Task")," \u6216 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/vscode-task/issues"},"Task for Visual Studio Code")," \u7684\u672a\u89e3\u51b3\u95ee\u9898\u5217\u8868\u3002 \u6211\u4eec\u6709\u4e00\u4e2a ",(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")," \u6807\u7b7e\uff0c\u7528\u4e8e\u66f4\u7b80\u5355\u7684\u95ee\u9898\uff0c\u975e\u5e38\u9002\u5408\u9996\u6b21\u8d21\u732e\u3002"),(0,r.kt)("p",null,"\u6b22\u8fce\u5404\u79cd\u8d21\u732e\uff0c\u65e0\u8bba\u662f\u62fc\u5199\u9519\u8bef\u4fee\u590d\u8fd8\u662f\u5f88\u5c0f\u7684\u65b0\u529f\u80fd\u3002 \u60a8\u8fd8\u53ef\u4ee5\u901a\u8fc7\u5bf9 Issue \u8fdb\u884c\u6295\u7968/\u8bc4\u8bba\u3001\u5e2e\u52a9\u56de\u7b54\u95ee\u9898\u6216\u5e2e\u52a9 ",(0,r.kt)("a",{parentName:"p",href:"/zh-Hans/community/"},"\u5176\u4ed6\u793e\u533a\u9879\u76ee")," \u6765\u505a\u51fa\u8d21\u732e\u3002"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"\u6211\u88ab\u56f0\u4f4f\u4e86\uff0c\u6211\u5728\u54ea\u91cc\u53ef\u4ee5\u83b7\u5f97\u5e2e\u52a9\uff1f")),(0,r.kt)("p",null,"\u5982\u679c\u60a8\u6709\u4efb\u4f55\u7591\u95ee\uff0c\u8bf7\u968f\u65f6\u5728\u6211\u4eec\u7684 ",(0,r.kt)("a",{parentName:"p",href:"https://discord.gg/6TY36E39UK"},"Discord \u670d\u52a1\u5668")," \u4e0a\u7684 ",(0,r.kt)("inlineCode",{parentName:"p"},"#help")," \u8bba\u575b\u9891\u9053\u4e2d\u63d0\u95ee\uff0c\u6216\u5728 GitHub \u4e0a\u6253\u5f00 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/discussions"},"\u8ba8\u8bba"),"\u3002"),(0,r.kt)("hr",null))}k.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunktaskfile_dev=self.webpackChunktaskfile_dev||[]).push([[188],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return d}});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 s=a.createContext({}),p=function(e){var t=a.useContext(s),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(s.Provider,{value:t},e.children)},k="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},c=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),k=p(n),c=r,d=k["".concat(s,".").concat(c)]||k[c]||m[c]||i;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,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[k]="string"==typeof e?e:r,o[1]=l;for(var p=2;p "),"\u3002"),(0,r.kt)("p",null,"\u8981\u8fd0\u884c Task for Visual Studio Code\uff0c\u60a8\u53ef\u4ee5\u5728 VSCode \u4e2d\u6253\u5f00\u9879\u76ee\u5e76\u6309 F5\uff08\u6216\u4efb\u4f55\u60a8\u8bbe\u7f6e\u7ed1\u5b9a\u7684\u8c03\u8bd5\u952e\uff09\u3002 \u8fd9\u5c06\u6253\u5f00\u4e00\u4e2a\u65b0\u7684 VSCode \u7a97\u53e3\uff0c\u6269\u5c55\u6b63\u5728\u8fd0\u884c\u3002 \u5efa\u8bae\u4ee5\u8fd9\u79cd\u65b9\u5f0f\u8fdb\u884c\u8c03\u8bd5\uff0c\u56e0\u4e3a\u5b83\u5141\u8bb8\u60a8\u8bbe\u7f6e\u65ad\u70b9\u5e76\u5355\u6b65\u6267\u884c\u4ee3\u7801\u3002 \u6216\u8005\uff0c\u60a8\u53ef\u4ee5\u8fd0\u884c ",(0,r.kt)("inlineCode",{parentName:"p"},"task package"),"\uff0c\u8fd9\u5c06\u751f\u6210\u4e00\u4e2a\u53ef\u7528\u4e8e\u624b\u52a8\u5b89\u88c5\u6269\u5c55\u7684 ",(0,r.kt)("inlineCode",{parentName:"p"},".vsix")," \u6587\u4ef6\u3002"),(0,r.kt)("h3",{id:"\u66f4\u65b0\u6587\u6863"},"\u66f4\u65b0\u6587\u6863"),(0,r.kt)("p",null,"Task \u4f7f\u7528 ",(0,r.kt)("a",{parentName:"p",href:"https://docusaurus.io"},"Docusaurus")," \u6765\u6258\u7ba1\u6587\u6863\u670d\u52a1\u5668\u3002 \u6b64\u4ee3\u7801\u4f4d\u4e8e Task \u6838\u5fc3\u5b58\u50a8\u5e93\u4e2d\u3002 \u8fd9\u53ef\u4ee5\u901a\u8fc7\u4f7f\u7528 ",(0,r.kt)("inlineCode",{parentName:"p"},"task docs"),"\uff08\u9700\u8981 ",(0,r.kt)("inlineCode",{parentName:"p"},"nodejs")," \u548c ",(0,r.kt)("inlineCode",{parentName:"p"},"yarn"),"\uff09\u5728\u672c\u5730\u8bbe\u7f6e\u548c\u8fd0\u884c\u3002 \u6240\u6709\u5185\u5bb9\u5747\u4f7f\u7528 Markdown \u7f16\u5199\uff0c\u4f4d\u4e8e ",(0,r.kt)("inlineCode",{parentName:"p"},"docs/docs")," \u76ee\u5f55\u4e2d\u3002 \u6240\u6709 Markdown \u6587\u6863\u90fd\u5e94\u6709 80 \u4e2a\u5b57\u7b26\u7684\u6362\u884c\u9650\u5236\uff08\u7531 Prettier \u5f3a\u5236\u6267\u884c\uff09\u3002"),(0,r.kt)("p",null,"\u8fdb\u884c\u53d8\u66f4\u65f6\uff0c\u8bf7\u8003\u8651\u662f\u5426\u6709\u5fc5\u8981\u66f4\u6539 ",(0,r.kt)("a",{parentName:"p",href:"/zh-Hans/usage/"},"\u4f7f\u7528\u6307\u5357"),"\u3002 \u672c\u6587\u6863\u5305\u542b\u6709\u5173\u5982\u4f55\u4f7f\u7528\u4efb\u52a1\u529f\u80fd\u7684\u8bf4\u660e\u548c\u793a\u4f8b\u3002 \u5982\u679c\u60a8\u8981\u6dfb\u52a0\u65b0\u529f\u80fd\uff0c\u8bf7\u5c1d\u8bd5\u627e\u5230\u5408\u9002\u7684\u4f4d\u7f6e\u6765\u6dfb\u52a0\u65b0\u90e8\u5206\u3002 \u5982\u679c\u60a8\u8981\u66f4\u65b0\u73b0\u6709\u529f\u80fd\uff0c\u8bf7\u786e\u4fdd\u6587\u6863\u548c\u6240\u6709\u793a\u4f8b\u90fd\u662f\u6700\u65b0\u7684\u3002 \u786e\u4fdd\u4efb\u4f55\u793a\u4f8b\u90fd\u9075\u5faa ",(0,r.kt)("a",{parentName:"p",href:"/zh-Hans/styleguide/"},"Taskfile \u98ce\u683c\u6307\u5357"),"\u3002"),(0,r.kt)("p",null,"\u5982\u679c\u60a8\u6dfb\u52a0\u4e86\u65b0\u5b57\u6bb5\u3001\u547d\u4ee4\u6216\u6807\u5fd7\uff0c\u8bf7\u786e\u4fdd\u5c06\u5176\u6dfb\u52a0\u5230 ",(0,r.kt)("a",{parentName:"p",href:"/zh-Hans/api/"},"API \u53c2\u8003")," \u4e2d\u3002 \u8fd8\u9700\u8981\u5c06\u65b0\u5b57\u6bb5\u6dfb\u52a0\u5230 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/blob/main/docs/static/schema.json"},"JSON Schema")," \u4e2d\u3002 API \u53c2\u8003\u548c schema \u4e2d\u7684\u5b57\u6bb5\u63cf\u8ff0\u5e94\u8be5\u5339\u914d\u3002"),(0,r.kt)("h3",{id:"\u7f16\u5199\u6d4b\u8bd5"},"\u7f16\u5199\u6d4b\u8bd5"),(0,r.kt)("p",null,"\u8bb8\u591a Task \u7684\u6d4b\u8bd5\u90fd\u4fdd\u5b58\u5728\u9879\u76ee\u6839\u76ee\u5f55\u4e0b\u7684 ",(0,r.kt)("inlineCode",{parentName:"p"},"task_test.go")," \u6587\u4ef6\u4e2d\uff0c\u8fd9\u4e5f\u662f\u60a8\u6700\u6709\u53ef\u80fd\u60f3\u8981\u6dfb\u52a0\u65b0\u6d4b\u8bd5\u7684\u5730\u65b9\u3002 \u5927\u591a\u6570\u8fd9\u4e9b\u6d4b\u8bd5\u5728 ",(0,r.kt)("inlineCode",{parentName:"p"},"testdata")," \u76ee\u5f55\u4e2d\u4e5f\u6709\u4e00\u4e2a\u5b50\u76ee\u5f55\uff0c\u5176\u4e2d\u5b58\u50a8\u4e86\u8fd0\u884c\u6d4b\u8bd5\u6240\u9700\u7684\u4efb\u4f55 Taskfiles/\u6570\u636e\u3002"),(0,r.kt)("p",null,"\u8fdb\u884c\u66f4\u6539\u65f6\uff0c\u8bf7\u8003\u8651\u662f\u5426\u9700\u8981\u6dfb\u52a0\u65b0\u7684\u6d4b\u8bd5\u3002 \u8fd9\u4e9b\u6d4b\u8bd5\u5e94\u786e\u4fdd\u60a8\u6dfb\u52a0\u7684\u529f\u80fd\u5728\u672a\u6765\u6301\u7eed\u5de5\u4f5c\u3002 \u5982\u679c\u60a8\u66f4\u6539\u4e86 Task \u7684\u884c\u4e3a\uff0c\u5219\u73b0\u6709\u6d4b\u8bd5\u4e5f\u53ef\u80fd\u9700\u8981\u66f4\u65b0\u3002"),(0,r.kt)("p",null,"\u60a8\u8fd8\u53ef\u4ee5\u8003\u8651\u4e3a\u60a8\u6dfb\u52a0\u7684\u4efb\u4f55\u65b0\u529f\u80fd\u6dfb\u52a0\u5355\u5143\u6d4b\u8bd5\u3002 \u5355\u5143\u6d4b\u8bd5\u5e94\u9075\u5faa Go \u7ea6\u5b9a\uff0c\u5373\u4f4d\u4e8e\u4e0e\u88ab\u6d4b\u8bd5\u4ee3\u7801\u76f8\u540c\u7684\u5305\u4e2d\u540d\u4e3a ",(0,r.kt)("inlineCode",{parentName:"p"},"*_test.go")," \u7684\u6587\u4ef6\u4e2d\u3002"),(0,r.kt)("h2",{id:"3-\u63d0\u4ea4\u4ee3\u7801"},"3. \u63d0\u4ea4\u4ee3\u7801"),(0,r.kt)("p",null,"\u5c1d\u8bd5\u7f16\u5199\u6709\u610f\u4e49\u7684\u63d0\u4ea4\u6d88\u606f\u5e76\u907f\u514d\u5728 PR \u4e0a\u6709\u592a\u591a\u63d0\u4ea4\u3002 \u5927\u591a\u6570 PR \u5e94\u8be5\u6709\u4e00\u4e2a\u5355\u4e00\u7684\u63d0\u4ea4\uff08\u5c3d\u7ba1\u5bf9\u4e8e\u66f4\u5927\u7684 PR \u5c06\u5b83\u5206\u6210\u51e0\u4e2a\u53ef\u80fd\u662f\u5408\u7406\u7684\uff09\u3002 Git squash(\u5e76\u548c) \u548c rebase(\u53d8\u57fa) \u662f\u4f60\u7684\u597d\u4f19\u4f34!"),(0,r.kt)("p",null,"\u5982\u679c\u60a8\u4e0d\u786e\u5b9a\u5982\u4f55\u683c\u5f0f\u5316\u63d0\u4ea4\u6d88\u606f\uff0c\u8bf7\u67e5\u770b ",(0,r.kt)("a",{parentName:"p",href:"https://www.conventionalcommits.org"},"\u7ea6\u5b9a\u5f0f\u63d0\u4ea4"),"\u3002 \u8fd9\u79cd\u98ce\u683c\u4e0d\u662f\u5f3a\u5236\u7684\uff0c\u4f46\u5b83\u662f\u4f7f\u60a8\u7684\u63d0\u4ea4\u6d88\u606f\u66f4\u5177\u53ef\u8bfb\u6027\u548c\u4e00\u81f4\u6027\u7684\u597d\u65b9\u6cd5\u3002"),(0,r.kt)("h2",{id:"4-\u63d0\u4ea4-pr"},"4. \u63d0\u4ea4 PR"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"\u63cf\u8ff0\u53d8\u66f4")," - \u786e\u4fdd\u60a8\u63d0\u4f9b\u5bf9\u66f4\u6539\u7684\u5168\u9762\u63cf\u8ff0\u3002"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"Issue/PR \u94fe\u63a5")," - \u94fe\u63a5\u5230\u4e4b\u524d\u76f8\u5173\u7684 Issue \u6216 PR\u3002 \u8bf7\u63cf\u8ff0\u5f53\u524d\u5de5\u4f5c\u4e0e\u4e4b\u524d\u7684\u4e0d\u540c\u4e4b\u5904\u3002"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"\u793a\u4f8b")," - \u6dfb\u52a0\u60a8\u8ba4\u4e3a\u6709\u52a9\u4e8e\u5c55\u793a\u66f4\u6539\u6548\u679c\u7684\u4efb\u4f55\u793a\u4f8b\u6216\u5c4f\u5e55\u622a\u56fe\u3002"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"PR \u8349\u6848")," - \u5982\u679c\u53d8\u66f4\u8fd8\u672a\u5b8c\u6210\uff0c\u4f46\u60a8\u60f3\u8ba8\u8bba\u5b83\u4eec\uff0c\u8bf7\u5c06 PR \u4f5c\u4e3a\u8349\u7a3f\u6253\u5f00\u5e76\u6dfb\u52a0\u8bc4\u8bba\u4ee5\u5f00\u59cb\u8ba8\u8bba\u3002 \u4f7f\u7528\u8bc4\u8bba\u800c\u4e0d\u662f PR \u63cf\u8ff0\u5141\u8bb8\u7a0d\u540e\u66f4\u65b0\u63cf\u8ff0\uff0c\u540c\u65f6\u4fdd\u7559\u8ba8\u8bba\u3002")),(0,r.kt)("h2",{id:"\u5e38\u89c1\u95ee\u9898"},"\u5e38\u89c1\u95ee\u9898"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"\u6211\u60f3\u8d21\u732e\uff0c\u6211\u4ece\u54ea\u91cc\u5f00\u59cb\uff1f")),(0,r.kt)("p",null,"\u67e5\u770b ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/issues"},"Task")," \u6216 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/vscode-task/issues"},"Task for Visual Studio Code")," \u7684\u672a\u89e3\u51b3\u95ee\u9898\u5217\u8868\u3002 \u6211\u4eec\u6709\u4e00\u4e2a ",(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")," \u6807\u7b7e\uff0c\u7528\u4e8e\u66f4\u7b80\u5355\u7684\u95ee\u9898\uff0c\u975e\u5e38\u9002\u5408\u9996\u6b21\u8d21\u732e\u3002"),(0,r.kt)("p",null,"\u6b22\u8fce\u5404\u79cd\u8d21\u732e\uff0c\u65e0\u8bba\u662f\u62fc\u5199\u9519\u8bef\u4fee\u590d\u8fd8\u662f\u5f88\u5c0f\u7684\u65b0\u529f\u80fd\u3002 \u60a8\u8fd8\u53ef\u4ee5\u901a\u8fc7\u5bf9 Issue \u8fdb\u884c\u6295\u7968/\u8bc4\u8bba\u3001\u5e2e\u52a9\u56de\u7b54\u95ee\u9898\u6216\u5e2e\u52a9 ",(0,r.kt)("a",{parentName:"p",href:"/zh-Hans/community/"},"\u5176\u4ed6\u793e\u533a\u9879\u76ee")," \u6765\u505a\u51fa\u8d21\u732e\u3002"),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"\u6211\u88ab\u56f0\u4f4f\u4e86\uff0c\u6211\u5728\u54ea\u91cc\u53ef\u4ee5\u83b7\u5f97\u5e2e\u52a9\uff1f")),(0,r.kt)("p",null,"\u5982\u679c\u60a8\u6709\u4efb\u4f55\u7591\u95ee\uff0c\u8bf7\u968f\u65f6\u5728\u6211\u4eec\u7684 ",(0,r.kt)("a",{parentName:"p",href:"https://discord.gg/6TY36E39UK"},"Discord \u670d\u52a1\u5668")," \u4e0a\u7684 ",(0,r.kt)("inlineCode",{parentName:"p"},"#help")," \u8bba\u575b\u9891\u9053\u4e2d\u63d0\u95ee\uff0c\u6216\u5728 GitHub \u4e0a\u6253\u5f00 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/go-task/task/discussions"},"\u8ba8\u8bba"),"\u3002"),(0,r.kt)("hr",null))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/zh-Hans/assets/js/runtime~main.0f948608.js b/zh-Hans/assets/js/runtime~main.fcbb3c15.js similarity index 93% rename from zh-Hans/assets/js/runtime~main.0f948608.js rename to zh-Hans/assets/js/runtime~main.fcbb3c15.js index 95a8f4bd..d31ca3c8 100644 --- a/zh-Hans/assets/js/runtime~main.0f948608.js +++ b/zh-Hans/assets/js/runtime~main.fcbb3c15.js @@ -1 +1 @@ -!function(){"use strict";var e,t,n,r,o,f={},a={};function u(e){var t=a[e];if(void 0!==t)return t.exports;var n=a[e]={id:e,loaded:!1,exports:{}};return f[e].call(n.exports,n,n.exports,u),n.loaded=!0,n.exports}u.m=f,u.c=a,e=[],u.O=function(t,n,r,o){if(!n){var f=1/0;for(d=0;d=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/"+({2:"4fc1c6af",31:"51de5da2",38:"14b2bd35",53:"935f2afb",97:"835b845c",133:"f1d66b0d",188:"dd4fb81f",204:"89e58501",425:"87f30f6b",514:"1be78505",595:"d0766b26",597:"8152bf4e",634:"1fd60438",701:"01713e21",825:"0f29a59d",863:"5b2a233e",868:"8faba80b",889:"49514f56",918:"17896441",920:"1a4e3797"}[e]||e)+"."+{2:"78ad6e5b",31:"0c47d2e3",38:"c717b5ee",53:"3254df08",97:"0a3e0609",133:"6862b446",188:"11511906",204:"418fa946",425:"e73575d1",514:"9062895a",595:"c5627647",597:"dafec294",634:"357460eb",701:"8536f7d0",780:"b979b06f",825:"ea44a842",863:"d9ce1ba9",868:"70950a98",889:"db0b6f85",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(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/"+({2:"4fc1c6af",31:"51de5da2",38:"14b2bd35",53:"935f2afb",97:"835b845c",133:"f1d66b0d",188:"dd4fb81f",204:"89e58501",425:"87f30f6b",514:"1be78505",595:"d0766b26",597:"8152bf4e",634:"1fd60438",701:"01713e21",825:"0f29a59d",863:"5b2a233e",868:"8faba80b",889:"49514f56",918:"17896441",920:"1a4e3797"}[e]||e)+"."+{2:"78ad6e5b",31:"0c47d2e3",38:"c717b5ee",53:"723d1027",97:"0a3e0609",133:"6862b446",188:"80728a3d",204:"418fa946",425:"3e4343d2",514:"9062895a",595:"c5627647",597:"dafec294",634:"9b55ac4e",701:"c7d3f8fb",780:"b979b06f",825:"ea44a842",863:"584908ce",868:"136a10d7",889:"457f5236",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 -更新日志 | Task +更新日志 | Task - +
-

更新日志

v3.24.0 - 2023-04-15

v3.23.0 - 2023-03-26

Task 现在已经有了一个由 @pd93 贡献的 Visual Studio Code 官方扩展程序! 🎉该扩展现在在 go-task 组织的 新存储库 中进行维护。 我们希望从社区收集反馈,请尝试并通过discussionissueDiscord 告诉我们您的想法!

注意: 扩展 需要安装 v3.23.0 才能正常工作。

  • The website was integrated with Crowdin to allow the community to contribute with translations! Chinese is the first language available (#1057, #1058 by @misitebao).
  • Added task location data to the --json flag output (#1056 by @pd93)
  • Change the name of the file generated by task --init from Taskfile.yaml to Taskfile.yml (#1062 by @misitebao).
  • Added new splitArgs template function ({{splitArgs "foo bar 'foo bar baz'"}}) to ensure string is split as arguments (#1040, #1059 by @dhanusaputra).
  • Fix the value of {{.CHECKSUM}} variable in status (#1076, #1080 by @pd93).
  • Fixed deep copy implementation (#1072 by @pd93)
  • Created a tool to assist with releases (#1086 by @pd93).

v3.22.0 - 2023-03-10

  • Add a brand new --global (-g) flag that will run a Taskfile from your $HOME directory. This is useful to have automation that you can run from anywhere in your system! (Documentation, #1029 by @andreynering).
  • Add ability to set error_only: true on the group output mode. This will instruct Task to only print a command output if it returned with a non-zero exit code (#664, #1022 by @jaedle).
  • Fixed bug where .task/checksum file was sometimes not being created when task also declares a status: (#840, #1035 by @harelwa, #1037 by @pd93).
  • Refactored and decoupled fingerprinting from the main Task executor (#1039 by @pd93).
  • Fixed deadlock issue when using run: once (#715, #1025 by @theunrepentantgeek).

v3.21.0 - 2023-02-22

  • Added new TASK_VERSION special variable (#990, #1014 by @ja1code).
  • Fixed a bug where tasks were sometimes incorrectly marked as internal (#1007 by @pd93).
  • Update to Go 1.20 (bump minimum version to 1.19) (#1010 by @pd93)
  • Added environment variable FORCE_COLOR support to force color output. Usefull for environments without TTY (#1003 by @automation-stack)

v3.20.0 - 2023-01-14

  • Improve behavior and performance of status checking when using the timestamp mode (#976, #977 by @aminya).
  • Performance optimizations were made for large Taskfiles (#982 by @pd93).
  • Add ability to configure options for the set and shopt builtins (#908, #929 by @pd93, Documentation).
  • Add new platforms: attribute to task and cmd, so it's now possible to choose in which platforms that given task or command will be run on. Possible values are operating system (GOOS), architecture (GOARCH) or a combination of the two. Example: platforms: [linux], platforms: [amd64] or platforms: [linux/amd64]. Other platforms will be skipped (#978, #980 by @leaanthony).

v3.19.1 - 2022-12-31

  • Small bug fix: closing Taskfile.yml once we're done reading it (#963, #964 by @HeCorr).
  • Fixes a bug in v2 that caused a panic when using a Taskfile_{{OS}}.yml file (#961, #971 by @pd93).
  • Fixed a bug where watch intervals set in the Taskfile were not being respected (#969, #970 by @pd93)
  • Add --json flag (alias -j) with the intent to improve support for code editors and add room to other possible integrations. This is basic for now, but we plan to add more info in the near future (#936 by @davidalpert, #764).

v3.19.0 - 2022-12-05

v3.18.0 - 2022-11-12

  • Show aliases on task --list --silent (task --ls). This means that aliases will be completed by the completion scripts (#919).
  • Tasks in the root Taskfile will now be displayed first in --list/--list-all output (#806, #890).
  • It's now possible to call a default task in an included Taskfile by using just the namespace. For example: docs:default is now automatically aliased to docs (#661, #815).

v3.17.0 - 2022-10-14

  • Add a "Did you mean ...?" suggestion when a task does not exits another one with a similar name is found (#867, #880).
  • Now YAML parse errors will print which Taskfile failed to parse (#885, #887).
  • Add ability to set aliases for tasks and namespaces (#268, #340, #879).
  • Improvements to Fish shell completion (#897).
  • Added ability to set a different watch interval by setting interval: '500ms' or using the --interval=500ms flag (#813, #865).
  • Add colored output to --list, --list-all and --summary flags (#845, #874).
  • Fix unexpected behavior where label: was being shown instead of the task name on --list (#603, #877).

v3.16.0 - 2022-09-29

  • Add npm as new installation method: npm i -g [@go](https://github.com/go)-task/cli (#870, #871, npm package).
  • Add support to marking tasks and includes as internal, which will hide them from --list and --list-all (#818).

v3.15.2 - 2022-09-08

  • Fix error when using variable in env: introduced in the previous release (#858, #866).
  • Fix handling of CLI_ARGS (--) in Bash completion (#863).
  • On zsh completion, add ability to replace --list-all with --list as already possible on the Bash completion (#861).

v3.15.0 - 2022-09-03

  • Add new special variables ROOT_DIR and TASKFILE_DIR. This was a highly requested feature (#215, #857, Documentation).
  • Follow symlinks on sources (#826, #831).
  • Improvements and fixes to Bash completion (#835, #844).

v3.14.1 - 2022-08-03

  • Always resolve relative include paths relative to the including Taskfile (#822, #823).
  • Fix ZSH and PowerShell completions to consider all tasks instead of just the public ones (those with descriptions) (#803).

v3.14.0 - 2022-07-08

  • Add ability to override the .task directory location with the TASK_TEMP_DIR environment variable.
  • Allow to override Task colors using environment variables: TASK_COLOR_RESET, TASK_COLOR_BLUE, TASK_COLOR_GREEN, TASK_COLOR_CYAN, TASK_COLOR_YELLOW, TASK_COLOR_MAGENTA and TASK_COLOR_RED (#568, #792).
  • Fixed bug when using the output: group mode where STDOUT and STDERR were being print in separated blocks instead of in the right order (#779).
  • Starting on this release, ARM architecture binaries are been released to Snap as well (#795).
  • i386 binaries won't be available anymore on Snap because Ubuntu removed the support for this architecture.
  • Upgrade mvdan.cc/sh, which fixes a bug with associative arrays (#785, mvdan/sh[#884](https://github.com/go-task/task/issues/884), mvdan/sh[#893](https://github.com/go-task/task/issues/893)).

v3.13.0 - 2022-06-13

  • Added -n as an alias to --dry (#776, #777).
  • Fix behavior of interrupt (SIGINT, SIGTERM) signals. Task will now give time for the processes running to do cleanup work (#458, #479, #728, #769).
  • Add new --exit-code (-x) flag that will pass-through the exit form the command being ran (#755).

v3.12.1 - 2022-05-10

  • Fixed bug where, on Windows, variables were ending with \r because we were only removing the final \n but not \r\n (#717).

v3.12.0 - 2022-03-31

  • The --list and --list-all flags can now be combined with the --silent flag to print the task names only, without their description (#691).
  • Added support for multi-level inclusion of Taskfiles. This means that included Taskfiles can also include other Taskfiles. Before this was limited to one level (#390, #623, #656).
  • Add ability to specify vars when including a Taskfile. Check out the documentation for more information (#677).

v3.11.0 - 2022-02-19

v3.10.0 - 2022-01-04

  • A new --list-all (alias -a) flag is now available. It's similar to the exiting --list (-l) but prints all tasks, even those without a description (#383, #401).
  • It's now possible to schedule cleanup commands to run once a task finishes with the defer: keyword (Documentation, #475, #626).
  • Remove long deprecated and undocumented $ variable prefix and ^ command prefix (#642, #644, #645).
  • Add support for .yaml extension (as an alternative to .yml). This was requested multiple times throughout the years. Enjoy! (#183, #184, #369, #584, #621).
  • Fixed error when computing a variable when the task directory do not exist yet (#481, #579).

v3.9.2 - 2021-12-02

v3.9.1 - 2021-11-28

v3.9.0 - 2021-10-02

v3.8.0 - 2021-09-26

  • Add interactive: true setting to improve support for interactive CLI apps (#217, #563).
  • Fix some nil errors (#534, #573).
  • Add ability to declare an included Taskfile as optional (#519, #552).
  • Add support for including Taskfiles in the home directory by using ~ (#539, #557).

v3.7.3 - 2021-09-04

v3.7.0 - 2021-07-31

  • Add run: setting to control if tasks should run multiple times or not. Available options are always (the default), when_changed (if a variable modified the task) and once (run only once no matter what). This is a long time requested feature. Enjoy! (#53, #359).

v3.6.0 - 2021-07-10

  • Allow using both sources: and status: in the same task (#411, #427, #477).
  • Small optimization and bug fix: don't compute variables if not needed for dotenv: (#517).

v3.5.0 - 2021-07-04

  • Add support for interpolation in dotenv: (#433, #434, #453).

v3.4.3 - 2021-05-30

v3.4.2 - 2021-04-23

  • On watch, report which file failed to read (#472).
  • Do not try to catch SIGKILL signal, which are not actually possible (#476).
  • Improve version reporting when building Task from source using Go Modules (#462, #473).

v3.4.1 - 2021-04-17

  • Improve error reporting when parsing YAML: in some situations where you would just see an generic error, you'll now see the actual error with more detail: the YAML line the failed to parse, for example (#467).
  • A JSON Schema was published here and is automatically being used by some editors like Visual Studio Code (#135).
  • Print task name before the command in the log output (#398).

v3.3.0 - 2021-03-20

  • Add support for delegating CLI arguments to commands with -- and a special CLI_ARGS variable (#327).
  • Add a --concurrency (alias -C) flag, to limit the number of tasks that run concurrently. This is useful for heavy workloads. (#345).

v3.2.2 - 2021-01-12

  • Improve performance of --list and --summary by skipping running shell variables for these flags (#332).
  • Fixed a bug where an environment in a Taskfile was not always overridable by the system environment (#425).
  • Fixed environment from .env files not being available as variables (#379).
  • The install script is now working for ARM platforms (#428).

v3.2.1 - 2021-01-09

  • Fixed some bugs and regressions regarding dynamic variables and directories (#426).
  • The slim-sprig package was updated with the upstream sprig.

v3.2.0 - 2021-01-07

  • Fix the .task directory being created in the task directory instead of the Taskfile directory (#247).
  • Fix a bug where dynamic variables (those declared with sh:) were not running in the task directory when the task has a custom dir or it was in an included Taskfile (#384).
  • The watch feature (via the --watch flag) got a few different bug fixes and should be more stable now (#423, #365).

v3.1.0 - 2021-01-03

  • Fix a bug when the checksum up-to-date resolution is used by a task with a custom label: attribute (#412).
  • Starting from this release, we're releasing official ARMv6 and ARM64 binaries for Linux (#375, #418).
  • Task now respects the order of declaration of included Taskfiles when evaluating variables declaring by them (#393).
  • set -e is now automatically set on every command. This was done to fix an issue where multiline string commands wouldn't really fail unless the sentence was in the last line (#403).

v3.0.1 - 2020-12-26

  • Allow use as a library by moving the required packages out of the internal directory (#358).
  • Do not error if a specified dotenv file does not exist (#378, #385).
  • Fix panic when you have empty tasks in your Taskfile (#338, #362).

v3.0.0 - 2020-08-16

  • On v3, all CLI variables will be considered global variables (#336, #341)
  • Add support to .env like files (#324, #356).
  • Add label: to task so you can override the task name in the logs ([#321](https://github.com/go-task/task/issues/321), #337).
  • Refactor how variables work on version 3 (#311).
  • Disallow expansions on v3 since it has no effect.
  • Taskvars.yml is not automatically included anymore.
  • Taskfile_{{OS}}.yml is not automatically included anymore.
  • Allow interpolation on includes, so you can manually include a Taskfile based on operation system, for example.
  • Expose .TASK variable in templates with the task name (#252).
  • Implement short task syntax (#194, #240).
  • Added option to make included Taskfile run commands on its own directory (#260, #144)
  • Taskfiles in version 1 are not supported anymore (#237).
  • Added global method: option. With this option, you can set a default method to all tasks in a Taskfile (#246).
  • Changed default method from timestamp to checksum (#246).
  • New magic variables are now available when using status:: .TIMESTAMP which contains the greatest modification date from the files listed in sources:, and .CHECKSUM, which contains a checksum of all files listed in status:. This is useful for manual checking when using external, or even remote, artifacts when using status: (#216).
  • We're now using slim-sprig instead of sprig, which allowed a file size reduction of about 22% (#219).
  • We now use some colors on Task output to better distinguish message types - commands are green, errors are red, etc (#207).

v2.8.1 - 2020-05-20

  • Fix error code for the --help flag (#300, #330).
  • Print version to stdout instead of stderr (#299, #329).
  • Supress context errors when using the --watch flag (#313, #317).
  • Support templating on description (#276, #283).

v2.8.0 - 2019-12-07

  • Add --parallel flag (alias -p) to run tasks given by the command line in parallel (#266).
  • Fixed bug where calling the task CLI only informing global vars would not execute the default task.
  • Add hability to silent all tasks by adding silent: true a the root of the Taskfile.

v2.7.1 - 2019-11-10

  • Fix error being raised when exit 0 was called (#251).

v2.7.0 - 2019-09-22

  • Fixed panic bug when assigning a global variable (#229, #243).
  • A task with method: checksum will now re-run if generated files are deleted (#228, #238).

v2.6.0 - 2019-07-21

  • Fixed some bugs regarding minor version checks on version:.
  • Add preconditions: to task (#205).
  • Create directory informed on dir: if it doesn't exist (#209, #211).
  • We now have a --taskfile flag (alias -t), which can be used to run another Taskfile (other than the default Taskfile.yml) (#221).
  • It's now possible to install Task using Homebrew on Linux (go-task/homebrew-tap[#1](https://github.com/go-task/task/issues/1)).

v2.5.2 - 2019-05-11

2.5.1 - 2019-04-27

  • Fixed some issues with interactive command line tools, where sometimes the output were not being shown, and similar issues (#114, #190, #200).
  • Upgraded go-yaml/yaml from v2 to v3.

v2.5.0 - 2019-03-16

v2.4.0 - 2019-02-21

  • Allow calling a task of the root Taskfile from an included Taskfile by prefixing it with : (#161, #172).
  • Add flag to override the output option (#173).
  • Fix bug where Task was persisting the new checksum on the disk when the Dry Mode is enabled (#166).
  • Fix file timestamp issue when the file name has spaces (#176).
  • Mitigating path expanding issues on Windows (#170).

v2.3.0 - 2019-01-02

  • On Windows, Task can now be installed using Scoop (#152).
  • Fixed issue with file/directory globing (#153).
  • Added ability to globally set environment variables (#138, #159).

v2.2.1 - 2018-12-09

  • This repository now uses Go Modules (#143). We'll still keep the vendor directory in sync for some time, though;
  • Fixing a bug when the Taskfile has no tasks but includes another Taskfile (#150);
  • Fix a bug when calling another task or a dependency in an included Taskfile (#151).

v2.2.0 - 2018-10-25

  • Added support for including other Taskfiles (#98)
    • This should be considered experimental. For now, only including local files is supported, but support for including remote Taskfiles is being discussed. If you have any feedback, please comment on #98.
  • Task now have a dedicated documentation site: https://taskfile.org
    • Thanks to Docsify for making this pretty easy. To check the source code, just take a look at the docs directory of this repository. Contributions to the documentation is really appreciated.

v2.1.1 - 2018-09-17

  • Fix suggestion to use task --init not being shown anymore (when a Taskfile.yml is not found)
  • Fix error when using checksum method and no file exists for a source glob (#131)
  • Fix signal handling when the --watch flag is given (#132)

v2.1.0 - 2018-08-19

  • Add a ignore_error option to task and command (#123)
  • Add a dry run mode (--dry flag) (#126)

v2.0.3 - 2018-06-24

  • Expand environment variables on "dir", "sources" and "generates" (#116)
  • Fix YAML merging syntax (#112)
  • Add ZSH completion (#111)
  • Implement new output option. Please check out the documentation

v2.0.2 - 2018-05-01

  • Fix merging of YAML anchors (#112)

v2.0.1 - 2018-03-11

  • Fixes panic on task --list

v2.0.0 - 2018-03-08

Version 2.0.0 is here, with a new Taskfile format.

Please, make sure to read the Taskfile versions document, since it describes in depth what changed for this version.

  • New Taskfile version 2 (#77)
  • Possibility to have global variables in the Taskfile.yml instead of Taskvars.yml (#66)
  • Small improvements and fixes

v1.4.4 - 2017-11-19

  • Handle SIGINT and SIGTERM (#75);
  • List: print message with there's no task with description;
  • Expand home dir ("~" symbol) on paths (#74);
  • Add Snap as an installation method;
  • Move examples to its own repo;
  • Watch: also walk on tasks called on on "cmds", and not only on "deps";
  • Print logs to stderr instead of stdout (#68);
  • Remove deprecated set keyword;
  • Add checksum based status check, alternative to timestamp based.

v1.4.3 - 2017-09-07

  • Allow assigning variables to tasks at run time via CLI (#33)
  • Added suport for multiline variables from sh (#64)
  • Fixes env: remove square braces and evaluate shell (#62)
  • Watch: change watch library and few fixes and improvements
  • When use watching, cancel and restart long running process on file change (#59 and #60)

v1.4.2 - 2017-07-30

  • Flag to set directory of execution
  • Always echo command if is verbose mode
  • Add silent mode to disable echoing of commands
  • Fixes and improvements of variables (#56)

v1.4.1 - 2017-07-15

  • Allow use of YAML for dynamic variables instead of $ prefix
    • VAR: {sh: echo Hello} instead of VAR: $echo Hello
  • Add --list (or -l) flag to print existing tasks
  • OS specific Taskvars file (e.g. Taskvars_windows.yml, Taskvars_linux.yml, etc)
  • Consider task up-to-date on equal timestamps (#49)
  • Allow absolute path in generates section (#48)
  • Bugfix: allow templating when calling deps (#42)
  • Fix panic for invalid task in cyclic dep detection
  • Better error output for dynamic variables in Taskvars.yml (#41)
  • Allow template evaluation in parameters

v1.4.0 - 2017-07-06

  • Cache dynamic variables
  • Add verbose mode (-v flag)
  • Support to task parameters (overriding vars) (#31) (#32)
  • Print command, also when "set:" is specified (#35)
  • Improve task command help text (#35)

v1.3.1 - 2017-06-14

  • Fix glob not working on commands (#28)
  • Add ExeExt template function
  • Add --init flag to create a new Taskfile
  • Add status option to prevent task from running (#27)
  • Allow interpolation on generates and sources attributes (#26)

v1.3.0 - 2017-04-24

  • Migrate from os/exec.Cmd to a native Go sh/bash interpreter
    • This is a potentially breaking change if you use Windows.
    • Now, cmd is not used anymore on Windows. Always use Bash-like syntax for your commands, even on Windows.
  • Add "ToSlash" and "FromSlash" to template functions
  • Use functions defined on github.com/Masterminds/sprig
  • Do not redirect stdin while running variables commands
  • Using context and errgroup packages (this will make other tasks to be cancelled, if one returned an error)

v1.2.0 - 2017-04-02

  • More tests and Travis integration
  • Watch a task (experimental)
  • Possibility to call another task
  • Fix "=" not being reconized in variables/environment variables
  • Tasks can now have a description, and help will print them (#10)
  • Task dependencies now run concurrently
  • Support for a default task (#16)

v1.1.0 - 2017-03-08

  • Support for YAML, TOML and JSON (#1)
  • Support running command in another directory (#4)
  • --force or -f flag to force execution of task even when it's up-to-date
  • Detection of cyclic dependencies (#5)
  • Support for variables (#6, #9, #14)
  • Operation System specific commands and variables (#13)

v1.0.0 - 2017-02-28

  • Add LICENSE file
- +

更新日志

v3.25.0 - 2023-05-22

  • 调用其他任务时支持 silent: (由 @danquah#680#1142 完成)。
  • 改进 PowerShell 完成脚本(由 @trim21#1168 完成)。
  • 在网站菜单中添加更多语言并显示翻译进度百分比( by 由 @misitebao#1173 完成)。
  • 从此版本开始,FreeBSD 的官方二进制文件将可供下载(由 @andreynering#1068 完成)。
  • 修复一些被意外抑制的错误(由 @clintmod#1134 修复)。
  • 修复 Taskfile 中省略 version 时的 nil 指针错误(由 @pd93#1148#1149 修复)。
  • 修复 task 不存在时的重复错误消息(由 @pd93#1141#1144 修复)。

v3.24.0 - 2023-04-15

v3.23.0 - 2023-03-26

Task 现在已经有了一个由 @pd93 贡献的 Visual Studio Code 官方扩展程序! 🎉该扩展现在在 go-task 组织的 新存储库 中进行维护。 我们希望从社区收集反馈,请尝试并通过discussionissueDiscord 告诉我们您的想法!

注意: 扩展 需要安装 v3.23.0 才能正常工作。

  • The website was integrated with Crowdin to allow the community to contribute with translations! Chinese is the first language available (#1057, #1058 by @misitebao).
  • Added task location data to the --json flag output (#1056 by @pd93)
  • Change the name of the file generated by task --init from Taskfile.yaml to Taskfile.yml (#1062 by @misitebao).
  • Added new splitArgs template function ({{splitArgs "foo bar 'foo bar baz'"}}) to ensure string is split as arguments (#1040, #1059 by @dhanusaputra).
  • Fix the value of {{.CHECKSUM}} variable in status (#1076, #1080 by @pd93).
  • Fixed deep copy implementation (#1072 by @pd93)
  • Created a tool to assist with releases (#1086 by @pd93).

v3.22.0 - 2023-03-10

  • Add a brand new --global (-g) flag that will run a Taskfile from your $HOME directory. This is useful to have automation that you can run from anywhere in your system! (Documentation, #1029 by @andreynering).
  • Add ability to set error_only: true on the group output mode. This will instruct Task to only print a command output if it returned with a non-zero exit code (#664, #1022 by @jaedle).
  • Fixed bug where .task/checksum file was sometimes not being created when task also declares a status: (#840, #1035 by @harelwa, #1037 by @pd93).
  • Refactored and decoupled fingerprinting from the main Task executor (#1039 by @pd93).
  • Fixed deadlock issue when using run: once (#715, #1025 by @theunrepentantgeek).

v3.21.0 - 2023-02-22

  • Added new TASK_VERSION special variable (#990, #1014 by @ja1code).
  • Fixed a bug where tasks were sometimes incorrectly marked as internal (#1007 by @pd93).
  • Update to Go 1.20 (bump minimum version to 1.19) (#1010 by @pd93)
  • Added environment variable FORCE_COLOR support to force color output. Usefull for environments without TTY (#1003 by @automation-stack)

v3.20.0 - 2023-01-14

  • Improve behavior and performance of status checking when using the timestamp mode (#976, #977 by @aminya).
  • Performance optimizations were made for large Taskfiles (#982 by @pd93).
  • Add ability to configure options for the set and shopt builtins (#908, #929 by @pd93, Documentation).
  • Add new platforms: attribute to task and cmd, so it's now possible to choose in which platforms that given task or command will be run on. Possible values are operating system (GOOS), architecture (GOARCH) or a combination of the two. Example: platforms: [linux], platforms: [amd64] or platforms: [linux/amd64]. Other platforms will be skipped (#978, #980 by @leaanthony).

v3.19.1 - 2022-12-31

  • Small bug fix: closing Taskfile.yml once we're done reading it (#963, #964 by @HeCorr).
  • Fixes a bug in v2 that caused a panic when using a Taskfile_{{OS}}.yml file (#961, #971 by @pd93).
  • Fixed a bug where watch intervals set in the Taskfile were not being respected (#969, #970 by @pd93)
  • Add --json flag (alias -j) with the intent to improve support for code editors and add room to other possible integrations. This is basic for now, but we plan to add more info in the near future (#936 by @davidalpert, #764).

v3.19.0 - 2022-12-05

v3.18.0 - 2022-11-12

  • Show aliases on task --list --silent (task --ls). This means that aliases will be completed by the completion scripts (#919).
  • Tasks in the root Taskfile will now be displayed first in --list/--list-all output (#806, #890).
  • It's now possible to call a default task in an included Taskfile by using just the namespace. For example: docs:default is now automatically aliased to docs (#661, #815).

v3.17.0 - 2022-10-14

  • Add a "Did you mean ...?" suggestion when a task does not exits another one with a similar name is found (#867, #880).
  • Now YAML parse errors will print which Taskfile failed to parse (#885, #887).
  • Add ability to set aliases for tasks and namespaces (#268, #340, #879).
  • Improvements to Fish shell completion (#897).
  • Added ability to set a different watch interval by setting interval: '500ms' or using the --interval=500ms flag (#813, #865).
  • Add colored output to --list, --list-all and --summary flags (#845, #874).
  • Fix unexpected behavior where label: was being shown instead of the task name on --list (#603, #877).

v3.16.0 - 2022-09-29

  • Add npm as new installation method: npm i -g [@go](https://github.com/go)-task/cli (#870, #871, npm package).
  • Add support to marking tasks and includes as internal, which will hide them from --list and --list-all (#818).

v3.15.2 - 2022-09-08

  • Fix error when using variable in env: introduced in the previous release (#858, #866).
  • Fix handling of CLI_ARGS (--) in Bash completion (#863).
  • On zsh completion, add ability to replace --list-all with --list as already possible on the Bash completion (#861).

v3.15.0 - 2022-09-03

  • Add new special variables ROOT_DIR and TASKFILE_DIR. This was a highly requested feature (#215, #857, Documentation).
  • Follow symlinks on sources (#826, #831).
  • Improvements and fixes to Bash completion (#835, #844).

v3.14.1 - 2022-08-03

  • Always resolve relative include paths relative to the including Taskfile (#822, #823).
  • Fix ZSH and PowerShell completions to consider all tasks instead of just the public ones (those with descriptions) (#803).

v3.14.0 - 2022-07-08

  • Add ability to override the .task directory location with the TASK_TEMP_DIR environment variable.
  • Allow to override Task colors using environment variables: TASK_COLOR_RESET, TASK_COLOR_BLUE, TASK_COLOR_GREEN, TASK_COLOR_CYAN, TASK_COLOR_YELLOW, TASK_COLOR_MAGENTA and TASK_COLOR_RED (#568, #792).
  • Fixed bug when using the output: group mode where STDOUT and STDERR were being print in separated blocks instead of in the right order (#779).
  • Starting on this release, ARM architecture binaries are been released to Snap as well (#795).
  • i386 binaries won't be available anymore on Snap because Ubuntu removed the support for this architecture.
  • Upgrade mvdan.cc/sh, which fixes a bug with associative arrays (#785, mvdan/sh[#884](https://github.com/go-task/task/issues/884), mvdan/sh[#893](https://github.com/go-task/task/issues/893)).

v3.13.0 - 2022-06-13

  • Added -n as an alias to --dry (#776, #777).
  • Fix behavior of interrupt (SIGINT, SIGTERM) signals. Task will now give time for the processes running to do cleanup work (#458, #479, #728, #769).
  • Add new --exit-code (-x) flag that will pass-through the exit form the command being ran (#755).

v3.12.1 - 2022-05-10

  • Fixed bug where, on Windows, variables were ending with \r because we were only removing the final \n but not \r\n (#717).

v3.12.0 - 2022-03-31

  • The --list and --list-all flags can now be combined with the --silent flag to print the task names only, without their description (#691).
  • Added support for multi-level inclusion of Taskfiles. This means that included Taskfiles can also include other Taskfiles. Before this was limited to one level (#390, #623, #656).
  • Add ability to specify vars when including a Taskfile. Check out the documentation for more information (#677).

v3.11.0 - 2022-02-19

v3.10.0 - 2022-01-04

  • A new --list-all (alias -a) flag is now available. It's similar to the exiting --list (-l) but prints all tasks, even those without a description (#383, #401).
  • It's now possible to schedule cleanup commands to run once a task finishes with the defer: keyword (Documentation, #475, #626).
  • Remove long deprecated and undocumented $ variable prefix and ^ command prefix (#642, #644, #645).
  • Add support for .yaml extension (as an alternative to .yml). This was requested multiple times throughout the years. Enjoy! (#183, #184, #369, #584, #621).
  • Fixed error when computing a variable when the task directory do not exist yet (#481, #579).

v3.9.2 - 2021-12-02

v3.9.1 - 2021-11-28

v3.9.0 - 2021-10-02

v3.8.0 - 2021-09-26

  • Add interactive: true setting to improve support for interactive CLI apps (#217, #563).
  • Fix some nil errors (#534, #573).
  • Add ability to declare an included Taskfile as optional (#519, #552).
  • Add support for including Taskfiles in the home directory by using ~ (#539, #557).

v3.7.3 - 2021-09-04

v3.7.0 - 2021-07-31

  • Add run: setting to control if tasks should run multiple times or not. Available options are always (the default), when_changed (if a variable modified the task) and once (run only once no matter what). This is a long time requested feature. Enjoy! (#53, #359).

v3.6.0 - 2021-07-10

  • Allow using both sources: and status: in the same task (#411, #427, #477).
  • Small optimization and bug fix: don't compute variables if not needed for dotenv: (#517).

v3.5.0 - 2021-07-04

  • Add support for interpolation in dotenv: (#433, #434, #453).

v3.4.3 - 2021-05-30

v3.4.2 - 2021-04-23

  • On watch, report which file failed to read (#472).
  • Do not try to catch SIGKILL signal, which are not actually possible (#476).
  • Improve version reporting when building Task from source using Go Modules (#462, #473).

v3.4.1 - 2021-04-17

  • Improve error reporting when parsing YAML: in some situations where you would just see an generic error, you'll now see the actual error with more detail: the YAML line the failed to parse, for example (#467).
  • A JSON Schema was published here and is automatically being used by some editors like Visual Studio Code (#135).
  • Print task name before the command in the log output (#398).

v3.3.0 - 2021-03-20

  • Add support for delegating CLI arguments to commands with -- and a special CLI_ARGS variable (#327).
  • Add a --concurrency (alias -C) flag, to limit the number of tasks that run concurrently. This is useful for heavy workloads. (#345).

v3.2.2 - 2021-01-12

  • Improve performance of --list and --summary by skipping running shell variables for these flags (#332).
  • Fixed a bug where an environment in a Taskfile was not always overridable by the system environment (#425).
  • Fixed environment from .env files not being available as variables (#379).
  • The install script is now working for ARM platforms (#428).

v3.2.1 - 2021-01-09

  • Fixed some bugs and regressions regarding dynamic variables and directories (#426).
  • The slim-sprig package was updated with the upstream sprig.

v3.2.0 - 2021-01-07

  • Fix the .task directory being created in the task directory instead of the Taskfile directory (#247).
  • Fix a bug where dynamic variables (those declared with sh:) were not running in the task directory when the task has a custom dir or it was in an included Taskfile (#384).
  • The watch feature (via the --watch flag) got a few different bug fixes and should be more stable now (#423, #365).

v3.1.0 - 2021-01-03

  • Fix a bug when the checksum up-to-date resolution is used by a task with a custom label: attribute (#412).
  • Starting from this release, we're releasing official ARMv6 and ARM64 binaries for Linux (#375, #418).
  • Task now respects the order of declaration of included Taskfiles when evaluating variables declaring by them (#393).
  • set -e is now automatically set on every command. This was done to fix an issue where multiline string commands wouldn't really fail unless the sentence was in the last line (#403).

v3.0.1 - 2020-12-26

  • Allow use as a library by moving the required packages out of the internal directory (#358).
  • Do not error if a specified dotenv file does not exist (#378, #385).
  • Fix panic when you have empty tasks in your Taskfile (#338, #362).

v3.0.0 - 2020-08-16

  • On v3, all CLI variables will be considered global variables (#336, #341)
  • Add support to .env like files (#324, #356).
  • Add label: to task so you can override the task name in the logs ([#321](https://github.com/go-task/task/issues/321), #337).
  • Refactor how variables work on version 3 (#311).
  • Disallow expansions on v3 since it has no effect.
  • Taskvars.yml is not automatically included anymore.
  • Taskfile_{{OS}}.yml is not automatically included anymore.
  • Allow interpolation on includes, so you can manually include a Taskfile based on operation system, for example.
  • Expose .TASK variable in templates with the task name (#252).
  • Implement short task syntax (#194, #240).
  • Added option to make included Taskfile run commands on its own directory (#260, #144)
  • Taskfiles in version 1 are not supported anymore (#237).
  • Added global method: option. With this option, you can set a default method to all tasks in a Taskfile (#246).
  • Changed default method from timestamp to checksum (#246).
  • New magic variables are now available when using status:: .TIMESTAMP which contains the greatest modification date from the files listed in sources:, and .CHECKSUM, which contains a checksum of all files listed in status:. This is useful for manual checking when using external, or even remote, artifacts when using status: (#216).
  • We're now using slim-sprig instead of sprig, which allowed a file size reduction of about 22% (#219).
  • We now use some colors on Task output to better distinguish message types - commands are green, errors are red, etc (#207).

v2.8.1 - 2020-05-20

  • Fix error code for the --help flag (#300, #330).
  • Print version to stdout instead of stderr (#299, #329).
  • Supress context errors when using the --watch flag (#313, #317).
  • Support templating on description (#276, #283).

v2.8.0 - 2019-12-07

  • Add --parallel flag (alias -p) to run tasks given by the command line in parallel (#266).
  • Fixed bug where calling the task CLI only informing global vars would not execute the default task.
  • Add hability to silent all tasks by adding silent: true a the root of the Taskfile.

v2.7.1 - 2019-11-10

  • Fix error being raised when exit 0 was called (#251).

v2.7.0 - 2019-09-22

  • Fixed panic bug when assigning a global variable (#229, #243).
  • A task with method: checksum will now re-run if generated files are deleted (#228, #238).

v2.6.0 - 2019-07-21

  • Fixed some bugs regarding minor version checks on version:.
  • Add preconditions: to task (#205).
  • Create directory informed on dir: if it doesn't exist (#209, #211).
  • We now have a --taskfile flag (alias -t), which can be used to run another Taskfile (other than the default Taskfile.yml) (#221).
  • It's now possible to install Task using Homebrew on Linux (go-task/homebrew-tap[#1](https://github.com/go-task/task/issues/1)).

v2.5.2 - 2019-05-11

2.5.1 - 2019-04-27

  • Fixed some issues with interactive command line tools, where sometimes the output were not being shown, and similar issues (#114, #190, #200).
  • Upgraded go-yaml/yaml from v2 to v3.

v2.5.0 - 2019-03-16

v2.4.0 - 2019-02-21

  • Allow calling a task of the root Taskfile from an included Taskfile by prefixing it with : (#161, #172).
  • Add flag to override the output option (#173).
  • Fix bug where Task was persisting the new checksum on the disk when the Dry Mode is enabled (#166).
  • Fix file timestamp issue when the file name has spaces (#176).
  • Mitigating path expanding issues on Windows (#170).

v2.3.0 - 2019-01-02

  • On Windows, Task can now be installed using Scoop (#152).
  • Fixed issue with file/directory globing (#153).
  • Added ability to globally set environment variables (#138, #159).

v2.2.1 - 2018-12-09

  • This repository now uses Go Modules (#143). We'll still keep the vendor directory in sync for some time, though;
  • Fixing a bug when the Taskfile has no tasks but includes another Taskfile (#150);
  • Fix a bug when calling another task or a dependency in an included Taskfile (#151).

v2.2.0 - 2018-10-25

  • Added support for including other Taskfiles (#98)
    • This should be considered experimental. For now, only including local files is supported, but support for including remote Taskfiles is being discussed. If you have any feedback, please comment on #98.
  • Task now have a dedicated documentation site: https://taskfile.org
    • Thanks to Docsify for making this pretty easy. To check the source code, just take a look at the docs directory of this repository. Contributions to the documentation is really appreciated.

v2.1.1 - 2018-09-17

  • Fix suggestion to use task --init not being shown anymore (when a Taskfile.yml is not found)
  • Fix error when using checksum method and no file exists for a source glob (#131)
  • Fix signal handling when the --watch flag is given (#132)

v2.1.0 - 2018-08-19

  • Add a ignore_error option to task and command (#123)
  • Add a dry run mode (--dry flag) (#126)

v2.0.3 - 2018-06-24

  • Expand environment variables on "dir", "sources" and "generates" (#116)
  • Fix YAML merging syntax (#112)
  • Add ZSH completion (#111)
  • Implement new output option. Please check out the documentation

v2.0.2 - 2018-05-01

  • Fix merging of YAML anchors (#112)

v2.0.1 - 2018-03-11

  • Fixes panic on task --list

v2.0.0 - 2018-03-08

Version 2.0.0 is here, with a new Taskfile format.

Please, make sure to read the Taskfile versions document, since it describes in depth what changed for this version.

  • New Taskfile version 2 (#77)
  • Possibility to have global variables in the Taskfile.yml instead of Taskvars.yml (#66)
  • Small improvements and fixes

v1.4.4 - 2017-11-19

  • Handle SIGINT and SIGTERM (#75);
  • List: print message with there's no task with description;
  • Expand home dir ("~" symbol) on paths (#74);
  • Add Snap as an installation method;
  • Move examples to its own repo;
  • Watch: also walk on tasks called on on "cmds", and not only on "deps";
  • Print logs to stderr instead of stdout (#68);
  • Remove deprecated set keyword;
  • Add checksum based status check, alternative to timestamp based.

v1.4.3 - 2017-09-07

  • Allow assigning variables to tasks at run time via CLI (#33)
  • Added suport for multiline variables from sh (#64)
  • Fixes env: remove square braces and evaluate shell (#62)
  • Watch: change watch library and few fixes and improvements
  • When use watching, cancel and restart long running process on file change (#59 and #60)

v1.4.2 - 2017-07-30

  • Flag to set directory of execution
  • Always echo command if is verbose mode
  • Add silent mode to disable echoing of commands
  • Fixes and improvements of variables (#56)

v1.4.1 - 2017-07-15

  • Allow use of YAML for dynamic variables instead of $ prefix
    • VAR: {sh: echo Hello} instead of VAR: $echo Hello
  • Add --list (or -l) flag to print existing tasks
  • OS specific Taskvars file (e.g. Taskvars_windows.yml, Taskvars_linux.yml, etc)
  • Consider task up-to-date on equal timestamps (#49)
  • Allow absolute path in generates section (#48)
  • Bugfix: allow templating when calling deps (#42)
  • Fix panic for invalid task in cyclic dep detection
  • Better error output for dynamic variables in Taskvars.yml (#41)
  • Allow template evaluation in parameters

v1.4.0 - 2017-07-06

  • Cache dynamic variables
  • Add verbose mode (-v flag)
  • Support to task parameters (overriding vars) (#31) (#32)
  • Print command, also when "set:" is specified (#35)
  • Improve task command help text (#35)

v1.3.1 - 2017-06-14

  • Fix glob not working on commands (#28)
  • Add ExeExt template function
  • Add --init flag to create a new Taskfile
  • Add status option to prevent task from running (#27)
  • Allow interpolation on generates and sources attributes (#26)

v1.3.0 - 2017-04-24

  • Migrate from os/exec.Cmd to a native Go sh/bash interpreter
    • This is a potentially breaking change if you use Windows.
    • Now, cmd is not used anymore on Windows. Always use Bash-like syntax for your commands, even on Windows.
  • Add "ToSlash" and "FromSlash" to template functions
  • Use functions defined on github.com/Masterminds/sprig
  • Do not redirect stdin while running variables commands
  • Using context and errgroup packages (this will make other tasks to be cancelled, if one returned an error)

v1.2.0 - 2017-04-02

  • More tests and Travis integration
  • Watch a task (experimental)
  • Possibility to call another task
  • Fix "=" not being reconized in variables/environment variables
  • Tasks can now have a description, and help will print them (#10)
  • Task dependencies now run concurrently
  • Support for a default task (#16)

v1.1.0 - 2017-03-08

  • Support for YAML, TOML and JSON (#1)
  • Support running command in another directory (#4)
  • --force or -f flag to force execution of task even when it's up-to-date
  • Detection of cyclic dependencies (#5)
  • Support for variables (#6, #9, #14)
  • Operation System specific commands and variables (#13)

v1.0.0 - 2017-02-28

  • Add LICENSE file
+ \ No newline at end of file diff --git a/zh-Hans/community/index.html b/zh-Hans/community/index.html index 2f5b4c41..b4c4dd0b 100644 --- a/zh-Hans/community/index.html +++ b/zh-Hans/community/index.html @@ -10,13 +10,13 @@ - +

社区

一些改善 Task 生态的工作是由社区完成,包括安装方法或代码编辑器集成。 我(指作者)非常感谢所有帮助提升整体体验的人们。

翻译

@DeronW此存储库 中维护网站的 中文翻译

集成

我们的许多集成都是由社区贡献和维护的。 您可以在 此处 查看社区集成的完整列表。

安装方法

有些安装方式是通过第三方维护的:

更多

同时,感谢所有 代码贡献者资金赞助,以及 提交问题解答问题 的人。

如果你发现文档有哪些遗漏信息,欢迎提交 PR。

- + \ No newline at end of file diff --git a/zh-Hans/contributing/index.html b/zh-Hans/contributing/index.html index a70c289e..8c33b802 100644 --- a/zh-Hans/contributing/index.html +++ b/zh-Hans/contributing/index.html @@ -10,14 +10,14 @@ - +
-

贡献

非常欢迎对 Task 的贡献,但我们要求您在提交 PR 之前阅读本文档。

备注

本文档适用于核心 Task 存储库 Task for Visual Studio Code

开始之前

  • 检查已有工作 - 是否已经存在 PR? 是否存在 Issue 正在讨论您要进行的功能/更改? 请确保你的工作中确实考虑了这些相关的讨论内容。
  • 向后兼容 - 你的变更是否破坏了已经存在的 Taskfile? 向后兼容的变更会更容易被合并进去。 您是否可以采取一种方法来保持这种兼容性? 如果没有,请考虑先提出一个 Issue,以便在您投入时间进行 PR 之前讨论 API 的更改。

1. 设置

  • Go - Task 使用 Go 编写。 我们始终支持最新的两个主要 Go 版本,因此请确保您的版本足够新。
  • Node.js - Node.js 用于托管 Task 的文档服务器,如果您想在本地运行此服务器,则需要它。 如果您想为 Visual Studio Code 扩展做贡献,也需要它。
  • Yarn - Yarn 是 Task 使用的 Node.js 包管理器。

2. 进行变更

  • 代码风格 - 尽量保持现有的代码风格。 Go 代码应该由 gofumpt 格式化并使用 golangci-lint 进行检查。 任何 Markdown 或 TypeScript 文件都应该由 Prettier 格式化和检查。 这种风格由我们的 CI 强制执行,以确保我们在整个项目中拥有一致的风格。 您可以使用 task lint 命令在本地检查代码,并使用 task lint:fix 命令自动修复发现的任何问题。
  • 文档 - 确保添加/更新了相关文档。 请参阅下面的 更新文档 部分。
  • 测试 - 确保添加/更新了相关测试,并且在提交 PR 前已通过所有测试。 请参阅下面的 编写测试 部分。

运行您的变更

要运行带有工作变更的任务,您可以使用 go run ./cmd/task。 要针对 testdata 中的测试任务文件运行任务的开发构建,您可以使用 go -run ./cmd/task --dir ./testdata/<my_test_dir> <task_name>

要运行 Task for Visual Studio Code,您可以在 VSCode 中打开项目并按 F5(或任何您设置绑定的调试键)。 这将打开一个新的 VSCode 窗口,扩展正在运行。 建议以这种方式进行调试,因为它允许您设置断点并单步执行代码。 或者,您可以运行 task package,这将生成一个可用于手动安装扩展的 .vsix 文件。

更新文档

Task 使用 Docusaurus 来托管文档服务器。 此代码位于 Task 核心存储库中。 这可以通过使用 task docs(需要 nodejsyarn)在本地设置和运行。 所有内容均使用 Markdown 编写,位于 docs/docs 目录中。 所有 Markdown 文档都应有 80 个字符的换行限制(由 Prettier 强制执行)。

进行变更时,请考虑是否有必要更改 使用指南。 本文档包含有关如何使用任务功能的说明和示例。 如果您要添加新功能,请尝试找到合适的位置来添加新部分。 如果您要更新现有功能,请确保文档和所有示例都是最新的。 确保任何示例都遵循 Taskfile 风格指南

如果您添加了新字段、命令或标志,请确保将其添加到 API 参考 中。 还需要将新字段添加到 JSON Schema 中。 API 参考和 schema 中的字段描述应该匹配。

编写测试

许多 Task 的测试都保存在项目根目录下的 task_test.go 文件中,这也是您最有可能想要添加新测试的地方。 大多数这些测试在 testdata 目录中也有一个子目录,其中存储了运行测试所需的任何 Taskfiles/数据。

进行更改时,请考虑是否需要添加新的测试。 这些测试应确保您添加的功能在未来持续工作。 如果您更改了 Task 的行为,则现有测试也可能需要更新。

您还可以考虑为您添加的任何新功能添加单元测试。 单元测试应遵循 Go 约定,即位于与被测试代码相同的包中名为 *_test.go 的文件中。

3. 提交代码

尝试编写有意义的提交消息并避免在 PR 上有太多提交。 大多数 PR 应该有一个单一的提交(尽管对于更大的 PR 将它分成几个可能是合理的)。 Git squash(并和) 和 rebase(变基) 是你的好朋友!

如果您不确定如何格式化提交消息,请查看 约定式提交。 这种风格不是强制的,但它是使您的提交消息更具可读性和一致性的好方法。

4. 提交 PR

  • 描述变更 - 确保您提供对更改的全面描述。
  • Issue/PR 链接 - 链接到之前相关的 Issue 或 PR。 请描述当前工作与之前的不同之处。
  • 示例 - 添加您认为有助于展示更改效果的任何示例或屏幕截图。
  • PR 草案 - 如果变更还未完成,但您想讨论它们,请将 PR 作为草稿打开并添加评论以开始讨论。 使用评论而不是 PR 描述允许稍后更新描述,同时保留讨论。

常见问题

我想贡献,我从哪里开始?

查看 TaskTask for Visual Studio Code 的未解决问题列表。 我们有一个 good first issue 标签,用于更简单的问题,非常适合首次贡献。

欢迎各种贡献,无论是拼写错误修复还是很小的新功能。 您还可以通过对 Issue 进行投票/评论、帮助回答问题或帮助 其他社区项目 来做出贡献。

我被困住了,我在哪里可以获得帮助?

如果您有任何疑问,请随时在我们的 Discord 服务器 上的 #help 论坛频道中提问,或在 GitHub 上打开 讨论


- +

贡献

非常欢迎对 Task 的贡献,但我们要求您在提交 PR 之前阅读本文档。

备注

本文档适用于 Task 核心存储库 Task for Visual Studio Code

开始之前

  • 检查已有工作 - 是否已经存在 PR? 是否存在 Issue 正在讨论您要进行的功能/更改? 请确保你的工作中确实考虑了这些相关的讨论内容。
  • 向后兼容 - 你的变更是否破坏了已经存在的 Taskfile? 向后兼容的变更会更容易被合并进去。 您是否可以采取一种方法来保持这种兼容性? 如果没有,请考虑先提出一个 Issue,以便在您投入时间进行 PR 之前讨论 API 的更改。

1. 设置

  • Go - Task 使用 Go 编写。 我们始终支持最新的两个主要 Go 版本,因此请确保您的版本足够新。
  • Node.js - Node.js 用于托管 Task 的文档服务器,如果您想在本地运行此服务器,则需要它。 如果您想为 Visual Studio Code 扩展做贡献,也需要它。
  • Yarn - Yarn 是 Task 使用的 Node.js 包管理器。

2. 进行变更

  • 代码风格 - 尽量保持现有的代码风格。 Go 代码应该由 gofumpt 格式化并使用 golangci-lint 进行检查。 任何 Markdown 或 TypeScript 文件都应该由 Prettier 格式化和检查。 这种风格由我们的 CI 强制执行,以确保我们在整个项目中拥有一致的风格。 您可以使用 task lint 命令在本地检查代码,并使用 task lint:fix 命令自动修复发现的任何问题。
  • 文档 - 确保添加/更新了相关文档。 请参阅下面的 更新文档 部分。
  • 测试 - 确保添加/更新了相关测试,并且在提交 PR 前已通过所有测试。 请参阅下面的 编写测试 部分。

运行您的变更

要运行带有工作变更的任务,您可以使用 go run ./cmd/task。 要针对 testdata 中的测试任务文件运行任务的开发构建,您可以使用 go +run ./cmd/task --dir ./testdata/<my_test_dir> <task_name>

要运行 Task for Visual Studio Code,您可以在 VSCode 中打开项目并按 F5(或任何您设置绑定的调试键)。 这将打开一个新的 VSCode 窗口,扩展正在运行。 建议以这种方式进行调试,因为它允许您设置断点并单步执行代码。 或者,您可以运行 task package,这将生成一个可用于手动安装扩展的 .vsix 文件。

更新文档

Task 使用 Docusaurus 来托管文档服务器。 此代码位于 Task 核心存储库中。 这可以通过使用 task docs(需要 nodejsyarn)在本地设置和运行。 所有内容均使用 Markdown 编写,位于 docs/docs 目录中。 所有 Markdown 文档都应有 80 个字符的换行限制(由 Prettier 强制执行)。

进行变更时,请考虑是否有必要更改 使用指南。 本文档包含有关如何使用任务功能的说明和示例。 如果您要添加新功能,请尝试找到合适的位置来添加新部分。 如果您要更新现有功能,请确保文档和所有示例都是最新的。 确保任何示例都遵循 Taskfile 风格指南

如果您添加了新字段、命令或标志,请确保将其添加到 API 参考 中。 还需要将新字段添加到 JSON Schema 中。 API 参考和 schema 中的字段描述应该匹配。

编写测试

许多 Task 的测试都保存在项目根目录下的 task_test.go 文件中,这也是您最有可能想要添加新测试的地方。 大多数这些测试在 testdata 目录中也有一个子目录,其中存储了运行测试所需的任何 Taskfiles/数据。

进行更改时,请考虑是否需要添加新的测试。 这些测试应确保您添加的功能在未来持续工作。 如果您更改了 Task 的行为,则现有测试也可能需要更新。

您还可以考虑为您添加的任何新功能添加单元测试。 单元测试应遵循 Go 约定,即位于与被测试代码相同的包中名为 *_test.go 的文件中。

3. 提交代码

尝试编写有意义的提交消息并避免在 PR 上有太多提交。 大多数 PR 应该有一个单一的提交(尽管对于更大的 PR 将它分成几个可能是合理的)。 Git squash(并和) 和 rebase(变基) 是你的好伙伴!

如果您不确定如何格式化提交消息,请查看 约定式提交。 这种风格不是强制的,但它是使您的提交消息更具可读性和一致性的好方法。

4. 提交 PR

  • 描述变更 - 确保您提供对更改的全面描述。
  • Issue/PR 链接 - 链接到之前相关的 Issue 或 PR。 请描述当前工作与之前的不同之处。
  • 示例 - 添加您认为有助于展示更改效果的任何示例或屏幕截图。
  • PR 草案 - 如果变更还未完成,但您想讨论它们,请将 PR 作为草稿打开并添加评论以开始讨论。 使用评论而不是 PR 描述允许稍后更新描述,同时保留讨论。

常见问题

我想贡献,我从哪里开始?

查看 TaskTask for Visual Studio Code 的未解决问题列表。 我们有一个 good first issue 标签,用于更简单的问题,非常适合首次贡献。

欢迎各种贡献,无论是拼写错误修复还是很小的新功能。 您还可以通过对 Issue 进行投票/评论、帮助回答问题或帮助 其他社区项目 来做出贡献。

我被困住了,我在哪里可以获得帮助?

如果您有任何疑问,请随时在我们的 Discord 服务器 上的 #help 论坛频道中提问,或在 GitHub 上打开 讨论


+ \ No newline at end of file diff --git a/zh-Hans/donate/index.html b/zh-Hans/donate/index.html index c6949b25..2d4e1750 100644 --- a/zh-Hans/donate/index.html +++ b/zh-Hans/donate/index.html @@ -10,13 +10,13 @@ - +

赞助

如果您觉得这个项目有用,您可以考虑使用下面列出的渠道之一进行捐赠。

这只是一种表达“感谢”的方式,它不会给你任何好处,比如在 Issue 上的更高优先级或类似的东西。

每月捐赠至少 50 美元的公司将在网站主页和 GitHub 存储库 README 中被标为“金牌赞助商”。 请与 @andreynering 联系,说明你希望显示的标志。 不过,可疑的企业(赌博、赌场等)将不被允许。

GitHub Sponsors

捐赠给维护者的首选方式是通过 GitHub Sponsors。 只需使用以下链接就可以进行捐赠:

Open Collective

如果你喜欢 Open Collective,你可以通过这些链接进行捐赠:

PayPal

你也可以通过 PayPal 向 @andreynering 捐款。

PIX (仅巴西)

如果你是巴西人,你也可以通过 PIX 使用这个QR码@andreynering 捐款。

- + \ No newline at end of file diff --git a/zh-Hans/faq/index.html b/zh-Hans/faq/index.html index dacd9bdc..866f63c5 100644 --- a/zh-Hans/faq/index.html +++ b/zh-Hans/faq/index.html @@ -10,13 +10,13 @@ - +
-

常见问题

此页面包含有关 Task 的常见问题列表。

为什么我的 task 不会更新我的 shell 环境?

这是 shell 工作方式的限制。 任务作为当前 shell 的子进程运行,因此它不能更改启动它的 shell 的环境。 其他任务运行器和构建工具也有此限制。

解决此问题的一种常见方法是创建一个 task,该任务将生成可由您的 shell 解析的输出。 例如,要在 shell 上设置环境变量,您可以编写如下任务:

my-shell-env:
cmds:
- echo "export FOO=foo"
- echo "export BAR=bar"

现在运行 eval $(task my-shell-env) 变量 $FOO$BAR 将在您的 shell 中可用。

内置的 'x' 命令在 Windows 上不起作用

Windows 上的默认 shell(cmdpowershell)没有像 rmcp 这样的内置命令。 这意味着这些命令将不起作用。 如果你想让你的 Taskfile 完全跨平台,你需要使用以下方法之一来解决这个限制:

  • 使用 {{OS}} 函数运行特定于操作系统的脚本。
  • 使用 {{if eq OS "windows"}}powershell {{end}}<my_cmd> 之类的东西来检测 windows 并直接在 Powershell 中运行命令。
  • 在 Windows 上使用支持这些命令的 shell 作为内置命令,例如 Git BashWSL

我们希望对 Task 的这一部分进行改进,下面的 Issue 会跟踪这项工作。 非常欢迎建设性的意见和贡献!

- +

常见问题

此页面包含有关 Task 的常见问题列表。

为什么我的 task 不会更新我的 shell 环境?

这是 shell 工作方式的限制。 Task 作为当前 shell 的子进程运行,因此它不能更改启动它的 shell 的环境。 其他任务运行器和构建工具也有此限制。

解决此问题的一种常见方法是创建一个 task,该任务将生成可由您的 shell 解析的输出。 例如,要在 shell 上设置环境变量,您可以编写如下任务:

my-shell-env:
cmds:
- echo "export FOO=foo"
- echo "export BAR=bar"

现在运行 eval $(task my-shell-env) 变量 $FOO$BAR 将在您的 shell 中可用。

内置的 'x' 命令在 Windows 上不起作用

Windows 上的默认 shell(cmdpowershell)没有像 rmcp 这样的内置命令。 这意味着这些命令将不起作用。 如果你想让你的 Taskfile 完全跨平台,你需要使用以下方法之一来解决这个限制:

  • 使用 {{OS}} 函数运行特定于操作系统的脚本。
  • 使用 {{if eq OS "windows"}}powershell {{end}}<my_cmd> 之类的东西来检测 windows 并直接在 Powershell 中运行命令。
  • 在 Windows 上使用支持这些命令的 shell 作为内置命令,例如 Git BashWSL

我们希望对 Task 的这一部分进行改进,下面的 Issue 会跟踪这项工作。 非常欢迎建设性的意见和贡献!

+ \ No newline at end of file diff --git a/zh-Hans/index.html b/zh-Hans/index.html index 79c933d2..f028f258 100644 --- a/zh-Hans/index.html +++ b/zh-Hans/index.html @@ -10,13 +10,13 @@ - +
-

Task

Task 是一个任务运行器/构建工具,旨在比 GNU Make 等更简单易用。

由于它是用 Go 编写的,Task 只是一个二进制文件,没有其他依赖项,这意味着您不需要为了使用构建工具而烦恼任何复杂的安装设置。

安装 后,您只需在名为 Taskfile.yml 的文件中使用简单的 YAML 规则描述您的构建任务:

Taskfile.yml
version: '3'

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

然后通过从您的终端运行 task hello 来调用它。

上面的示例只是一个开始,您可以查看 使用指南 以检查完整的模式文档和任务功能。

特性

  • 易于安装:只需要下载一个二进制文件,添加到 $PATH 即可! 或者,您也可以根据需要使用 HomebrewSnapcraftScoop 进行安装。
  • 可以在 CI 中使用:只要添加 这个命令 到 CI 安装脚本中,然后就可以把 Task 当做 CI 的一个功能来使用了。
  • 真正的跨平台:虽然大多数构建工具只能在 Linux 或 macOS 上运行良好,但由于 这个用于 Go 的 shell 解释器,Task 也支持 Windows。
  • 非常适合代码生成:如果给定的一组文件自上次运行以来没有更改(基于其时间戳或内容),您可以轻松地 阻止任务运行

金牌赞助商

- +

Task

Task 是一个任务运行器/构建工具,旨在比 GNU Make 等更简单易用。

由于它是用 Go 编写的,Task 只是一个二进制文件,没有其他依赖项,这意味着您不需要为了使用构建工具而烦恼任何复杂的安装设置。

安装 后,您只需在名为 Taskfile.yml 的文件中使用简单的 YAML 规则描述您的构建任务:

Taskfile.yml
version: '3'

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

然后通过从您的终端运行 task hello 来调用它。

上面的示例只是一个开始,您可以查看 使用指南 以检查完整的规则文档和 Task 功能。

特性

  • 易于安装:只需要下载一个二进制文件,添加到 $PATH 即可! 或者,您也可以根据需要使用 HomebrewSnapcraftScoop 进行安装。
  • 可以在 CI 中使用:只要添加 这个命令 到 CI 安装脚本中,然后就可以把 Task 当做 CI 的一个功能来使用了。
  • 真正的跨平台:虽然大多数构建工具只能在 Linux 或 macOS 上运行良好,但由于 这个用于 Go 的 shell 解释器,Task 也支持 Windows。
  • 非常适合代码生成:如果给定的一组文件自上次运行以来没有更改(基于其时间戳或内容),您可以轻松地 阻止 task 运行

金牌赞助商

+ \ No newline at end of file diff --git a/zh-Hans/installation/index.html b/zh-Hans/installation/index.html index 2f7e62c1..da76dd84 100644 --- a/zh-Hans/installation/index.html +++ b/zh-Hans/installation/index.html @@ -10,13 +10,13 @@ - +

安装

Task 提供以下多种安装方式。 查看以下可用方法。

包管理工具

Homebrew

如果您使用的是 macOS 或 Linux 并安装了 Homebrew,获取 Task 就像运行以下命令一样简单:

brew install go-task/tap/go-task

上面的公式是 我们自己维护 的。

最近,官方 Homebrew 存储库 中也提供了 Task,因此如果您愿意,也可以使用该选项:

brew install go-task

Snap

Task 在 Snapcraft 中可用,但请记住,您的 Linux 发行版应该符合 Snaps 的基本要求才能正确安装:

sudo snap install task --classic

Chocolatey

如果 Windows 上安装了 Chocolatey,再安装 Task 只要这样:

choco install go-task

这种安装方式是社区维护的。

Scoop

如果 Windows 上安装了 Scoop,再安装 Task 只要这样:

scoop install task

这种安装方式是社区维护的。 新版 Task 发布后,需要过一段时间才能通过 Scoop 安装。

AUR

如果你使用的是 Arch Linux,你可以使用你最喜欢的包管理器(例如 yaypacauryaourt)从 AUR 安装 Task:

yay -S go-task-bin

或者,有一个从源代码安装的 软件包,而不是从 发布页面 下载二进制文件:

yay -S go-task

这种安装方式是社区维护的。

Fedora

如果您使用的是 Fedora Linux,则可以使用 dnf官方 Fedora 存储库 安装 Task:

sudo dnf install go-task

这种安装方式是社区维护的。 新版 Task 发布后,需要一段时间才能通过 Fedora 安装。

Nix

如果您使用的是 NixOS 或安装了 Nix,则可以从 nixpkgs 安装 Task:

nix-env -iA nixpkgs.go-task

这种安装方式是社区维护的。 新版本的 Task 发布后,可能需要一些时间才能在 nixpkgs 中可用。

npm

您也可以通过使用 Node 和 npm 安装 此包 来安装 Task。

npm install -g @go-task/cli

Winget

如果您正在使用 Windows 并且安装了 winget 软件包管理工具,您可以从 winget-pkgs 安装 Task。

winget install Task.Task

获取二进制文件

二进制文件

您可以从 GitHub 上的发布页面 下载二进制文件并添加到您的 $PATH 中。

还支持 DEB 和 RPM 包。

task_checksums.txt 文件包含每个文件的 SHA-256 checksum。

安装脚本

我们还有一个 安装脚本,它在 CI 等场景中非常有用。 非常感谢 GoDownloader 使这个脚本的生成变得容易。

默认情况下,它安装在相对于工作目录的 ./bin 目录中:

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

可以使用 -b 参数覆盖安装目录。 通过 -b 参数可以自定义安装目录,在 Linux 中当前用户安装一般会选择 ~/.local/bin~/bin, 全局用户安装会选择 /usr/local/bin

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

在 macOS 和 Windows 上,~/.local/bin~/bin 默认情况下不会添加到 $PATH

GitHub Actions

如果你想在 GitHub Actions 中安装 Task,你可以尝试使用 Arduino 团队的 这个 action

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

这种安装方式是社区维护的。

从源码构建

Go Modules

确保您已正确安装和设置受支持的 Go 版本。 您可以在 go.mod 文件中找到最低要求的 Go 版本。

然后,您可以通过运行以下命令全局安装最新版本:

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

或者你可以安装到另一个目录:

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

对于 CI 环境,我们建议改用 安装脚本,它更快更稳定,因为它只会下载最新发布的二进制文件。

自动完成

下载与您的 shell 对应的自动完成文件。

所有自动完成都在 Task 存储库中可用

Bash

首先,确认你通过包管理安装了 bash-completion。

使完成文件可执行:

chmod +x path/to/task.bash

然后在 ~/.bash_profile 文件中添加:

source path/to/task.bash

ZSH

_task 文件放到你的 $FPATH 中:

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

~/.zshrc 文件中添加:

autoload -U compinit
compinit -i

建议使用 ZSH 5.7 或更高版本。

Fish

移动 task.fish 完成脚本:

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

PowerShell

使用以下命令打开您的配置文件脚本:

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

添加这行并保存文件:

Invoke-Expression -Command path/to/task.ps1
- + \ No newline at end of file diff --git a/zh-Hans/integrations/index.html b/zh-Hans/integrations/index.html index 6681609e..b295171d 100644 --- a/zh-Hans/integrations/index.html +++ b/zh-Hans/integrations/index.html @@ -10,13 +10,13 @@ - +

集成

Visual Studio Code 扩展

Task 有一个 针对 Visual Studio Code 的官方扩展。 这个项目的代码可以在 这里 找到。 要使用此扩展,您的系统上必须安装 Task v3.23.0+。

此扩展提供以下功能(以及更多):

  • 在侧边栏中查看 task。
  • 从侧边栏和命令面板运行 task。
  • 从侧边栏和命令面板转到定义。
  • 运行上一个 task 命令。
  • 多根工作区支持。
  • 在当前工作空间中初始化一个 Taskfile。

要获得 Taskfile 的自动完成和验证,请参阅下面的 Schema 部分。

Task for Visual Studio Code

Schema

这最初是由 @KROSF这个 Gist 中创建的,现在在 这个 文件中正式维护,并在 https://taskfile.dev/schema.json 上提供。 这个 schema 可用于验证 Taskfile 并在许多代码编辑器中提供自动完成功能:

Visual Studio Code

要将 schema 集成到 VS Code 中,您需要安装 Red Hat 的 YAML 扩展。 项目中的任何 Taskfile.yml 都应该被自动检测到,并且验证/自动完成应该可以工作。 如果这不起作用或者您想为具有不同名称的文件手动配置它,您可以将以下内容添加到您的 settings.json

// settings.json
{
"yaml.schemas": {
"https://taskfile.dev/schema.json": [
"**/Taskfile.yml",
"./path/to/any/other/taskfile.yml"
]
}
}

您还可以通过将以下注释添加到文件顶部来直接在 Taskfile 中配置 schema:

# yaml-language-server: $schema=https://taskfile.dev/schema.json
version: '3'

您可以在 YAML 语言服务器项目 中找到更多相关信息。

社区集成

除了我们的官方集成之外,还有一个很棒的开发人员社区,他们为 Task 创建了自己的集成:

如果你做了一些与 Task 集成的东西,请随意打开一个 PR 将它添加到这个列表中。

- + \ No newline at end of file diff --git a/zh-Hans/releasing/index.html b/zh-Hans/releasing/index.html index 3c2ffd71..be210ea3 100644 --- a/zh-Hans/releasing/index.html +++ b/zh-Hans/releasing/index.html @@ -10,13 +10,13 @@ - +

发布

Task 的发布流程是在 GoReleaser 的帮助下完成的。 本地调用 Taskfile 的 test-release task 可以测试发布流程。

GitHub Actions 会在新 tag 推送到 main 分支的时候,自动发布产出物(原生的可执行文件、DEB 和 RPM 包)。

从 v3.15.0 开始,原始可执行文件也可以通过检查特定的标签并调用 goreleaser build,使用上述 GitHub Actions 中定义的 Go 版本,在本地进行复制和验证。

Homebrew

Goreleaser 会自动向 Homebrew tap 仓库中的 Formula/go-task.rb 文件推送一个新的提交,以发布新的版本。

npm

要发布到 npm ,请更新 package.json 文件中的版本,然后运行 task npm:publish 来推送它。

Snapcraft

snap package 发布新版本需要手动执行下面步骤:

Scoop

Scoop 是一个 Windows 系统的命令行包管理工具。 Scoop 的包清单由社区维护。 Scoop 的维护人通常会在 这个文件 里维护版本。 如果发现 Task 版本是旧的,请提交一个 Issue 通知我们。

Nix

Nix 安装由社区维护。 Nix 包的维护人员通常会在 这个文件 里维护版本。 如果发现 Task 版本是旧的,请提交一个 Issue 通知我们。

- + \ No newline at end of file diff --git a/zh-Hans/search/index.html b/zh-Hans/search/index.html index acc64ed6..4e689968 100644 --- a/zh-Hans/search/index.html +++ b/zh-Hans/search/index.html @@ -10,13 +10,13 @@ - + - + \ No newline at end of file diff --git a/zh-Hans/styleguide/index.html b/zh-Hans/styleguide/index.html index fa94eaf9..aa2d62ad 100644 --- a/zh-Hans/styleguide/index.html +++ b/zh-Hans/styleguide/index.html @@ -10,13 +10,13 @@ - +

风格指南

这是对 Taskfile.yml 文件的官方风格指南。 本指南包含一些基本说明,可让您的任务文件保持简洁易用。

这包含一般准则,但不一定需要严格遵守。 如果你需要或想要,请随时提出不同意见,并在某些时候以不同方式进行。 此外,请随时打开 Issue 或 PR,对本指南进行改进。

使用 Taskfile.yml 而不是 taskfile.yml

# bad
taskfile.yml


# good
Taskfile.yml

这对于 Linux 用户尤其重要。 Windows 和 macOS 的文件系统不区分大小写,因此 taskfile.yml 最终会正常工作,即使它不受官方支持。 不过,在 Linux 上,只有 Taskfile.yml 可以工作。

使用正确的关键字顺序

  • version:
  • includes:
  • 可选配置命令,比如 output:silent:method:run:
  • vars:
  • env:dotenv:
  • tasks:

使用 2 个空格缩进

这是 YAML 文件最常见的约定,Task 同样也遵循它。

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


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

用空行分隔主要部分

# 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:
# ...

用空行分隔 task

# 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'

使用大写变量名称

# 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}} .

模板中不要用空格包住变量

# bad
version: '3'

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


# good
version: '3'

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

这个约定也被大多数人用于 Go 模板。

用破折号分隔任务名称单词

# bad
version: '3'

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


# good
version: '3'

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

使用冒号作为任务命名空间

# good
version: '3'

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

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

这在使用包含的任务文件时也会自动完成。

- + \ No newline at end of file diff --git a/zh-Hans/taskfile-versions/index.html b/zh-Hans/taskfile-versions/index.html index 1ed9cec1..0d2970af 100644 --- a/zh-Hans/taskfile-versions/index.html +++ b/zh-Hans/taskfile-versions/index.html @@ -10,13 +10,13 @@ - +
-

Taskfile 版本

Taskfile 语法和功能随着时间的推移而改变。 本文档解释了每个版本的变化以及如何升级您的任务文件。

Taskfile 版本的含义

Taskfile 版本遵循 Task 版本。 例如, taskfile version 2 意味着应该切换为 Task v2.0.0 以支持它。

Taskfile 文件的 version: 关键字接受语义化字符串, 所以 2, 2.02.0.0 都可以。 如果使用版本号 2.0,那么 Task 就不会使用 2.1 的功能, 但如果使用版本号 2, 那么任意 2.x.x 版本中的功能都是可用的, 但 3.0.0+ 的功能不可用。

版本 1

注意:Task v3.0.0 以后就不再支持 Taskfiles 的 1 版本了。

最初的 Taskfile 并不支持 version: 关键字,因为 YAML 文档中的根属性都是 task。 就像这样:

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

变量的优先级也不同:

  1. 调用变量
  2. 环境变量
  3. Task 变量
  4. Taskvars.yml 定义变量

版本 2.0

到了 2.0 版本,我们引入了 version: 字段, 在不破坏已存在的 Taskfiles 的前提下,在 Task 中引入新功能。 新语法如下:

version: '2'

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

如果您不想创建 Taskvars.yml,版本 2 允许您直接在 Taskfile 中写入全局变量:

version: '2'

vars:
GREETING: Hello, World!

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

变量的优先级调整为:

  1. Task 变量
  2. 调用变量
  3. Taskfile 定义变量
  4. Taskvars 文件定义变量
  5. 环境变量

添加了一个新的全局配置项来配置变量扩展的数量(默认为 2):

version: '2'

expansions: 3

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

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

版本 2.1

2.1 版包括一个全局 output 选项,以允许更好地控制如何将命令输出打印到控制台(有关更多信息,请参阅 文档):

version: '2'

output: prefixed

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

从这个版本开始,也可以忽略命令或 task 的错误(在 此处 查看文档):

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

版本 2.2

2.2 版带有全局 includes 选项来包含其他 Taskfiles:

version: '2'

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

版本 2.6

2.6 版本增加任务的先决条件字段 preconditions

version: '2'

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

请检查 文档

版本 3

以下是 v3 所做的一些主要变更:

  • Task 的日志使用彩色输出
  • 支持类 .env 文件
  • 添加 label: 设置后可以覆盖任务名称在日志中的显示方式
  • 添加了全局 method: 允许设置默认方法,Task 的默认值更改为 checksum
  • 使用 status:: CHECKSUMTIMESTAMP 时新增了两个魔术变量,分别包含 sources: 列出的文件的 md5 checksum 和最大修改时间戳
  • 另外,TASK 变量总是可以使用当前的任务名称
  • CLI 变量始终被视为全局变量
  • includes 添加了 dir: 选项,以允许选择包含的任务文件将在哪个目录上运行:
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!"
  • 对变量的处理方式进行了重大重构。 现在它们更容易理解了。 expansions: 设置被删除了,因为它变得不必要。 这是 Task 处理变量的顺序,每一层都可以看到前一层设置的变量并覆盖这些变量。
    • 环境变量
    • 全局或 CLI 变量
    • 调用变量
    • Task 内的变量
- +

Taskfile 版本

Taskfile 语法和功能随着时间的推移而改变。 本文档解释了每个版本的变化以及如何升级您的任务文件。

Taskfile 版本的含义

Taskfile 版本遵循 Task 版本。 例如, taskfile version 2 意味着应该切换为 Task v2.0.0 以支持它。

Taskfile 文件的 version: 关键字接受语义化字符串, 所以 2, 2.02.0.0 都可以。 如果使用版本号 2.0,那么 Task 就不会使用 2.1 的功能, 但如果使用版本号 2, 那么任意 2.x.x 版本中的功能都是可用的, 但 3.0.0+ 的功能不可用。

版本 1

注意:Task v3.0.0 以后就不再支持 Taskfiles 的 1 版本了。

最初的 Taskfile 并不支持 version: 关键字,因为 YAML 文档中的根属性都是 task。 就像这样:

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

变量的优先级也不同:

  1. 调用变量
  2. 环境变量
  3. Task 变量
  4. Taskvars.yml 定义变量

版本 2.0

到了 2.0 版本,我们引入了 version: 字段, 在不破坏已存在的 Taskfiles 的前提下,在 Task 中引入新功能。 新语法如下:

version: '2'

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

如果您不想创建 Taskvars.yml,版本 2 允许您直接在 Taskfile 中写入全局变量:

version: '2'

vars:
GREETING: Hello, World!

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

变量的优先级调整为:

  1. Task 变量
  2. 调用变量
  3. Taskfile 定义变量
  4. Taskvars 文件定义变量
  5. 环境变量

添加了一个新的全局配置项来配置变量扩展的数量(默认为 2):

version: '2'

expansions: 3

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

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

版本 2.1

2.1 版包括一个全局 output 选项,以允许更好地控制如何将命令输出打印到控制台(有关更多信息,请参阅 文档):

version: '2'

output: prefixed

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

从这个版本开始,也可以忽略命令或 task 的错误(在 此处 查看文档):

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

版本 2.2

2.2 版带有全局 includes 选项来包含其他 Taskfiles:

version: '2'

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

版本 2.6

2.6 版本增加任务的先决条件字段 preconditions

version: '2'

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

请检查 文档

版本 3

以下是 v3 所做的一些主要变更:

  • Task 的日志使用彩色输出
  • 支持类 .env 文件
  • 添加 label: 设置后可以覆盖任务名称在日志中的显示方式
  • 添加了全局 method: 允许设置默认方法,Task 的默认值更改为 checksum
  • 使用 status:: CHECKSUMTIMESTAMP 时新增了两个魔术变量,分别包含 sources: 列出的文件的 md5 checksum 和最大修改时间戳
  • 另外,TASK 变量总是可以使用当前的任务名称
  • CLI 变量始终被视为全局变量
  • includes 添加了 dir: 选项,以允许选择包含的任务文件将在哪个目录上运行:
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!"
  • 对变量的处理方式进行了重大重构。 现在它们更容易理解了。 expansions: 设置被删除了,因为它变得不必要。 这是 Task 处理变量的顺序,每一层都可以看到前一层设置的变量并覆盖这些变量。
    • 环境变量
    • 全局或 CLI 变量
    • 调用变量
    • Task 变量
+ \ No newline at end of file diff --git a/zh-Hans/translate/index.html b/zh-Hans/translate/index.html index 35a23fdf..29068d37 100644 --- a/zh-Hans/translate/index.html +++ b/zh-Hans/translate/index.html @@ -10,13 +10,13 @@ - +

翻译

想帮助我们翻译此文档吗? 在本文档中,我们解释了如何解决这一问题。

不要直接在 GitHub 存储库上编辑翻译后的 markdown 文件! 我们使用 Crowdin 来允许贡献者进行翻译工作。 存储库会根据 Crowdin 的进展定期更新。

如果您想访问 Crowdin 项目以提供翻译建议,请在 我们的 Discord 服务器上的 #translations 频道 上申请访问权限。 如果给定的语言尚未显示给 Crowdin,请询问,我们可以对其进行配置。

- + \ No newline at end of file diff --git a/zh-Hans/usage/index.html b/zh-Hans/usage/index.html index 379704b8..bdd37622 100644 --- a/zh-Hans/usage/index.html +++ b/zh-Hans/usage/index.html @@ -10,13 +10,13 @@ - +
-

使用指南

快速入门

在项目的根目录中创建一个名为 Taskfile.yml 的文件。 cmds 属性应包含 task 的命令。 下面的示例允许编译 Go 应用程序并使用 esbuild 将多个 CSS 文件合并并缩小为一个文件。

version: '3'

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

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

运行 task 就这样简单:

task assets build

Task 使用 mvdan.cc/sh,一个原生的 Go sh 解释器。 因此,您可以编写 sh/bash 命令,它甚至可以在 Windows 上运行,而 shbash 通常不可用。 请记住,任何被调用的可执行文件都必须在操作系统或 PATH 中可用。

如果不传 task 的名字,默认会调用 "default"。

支持的文件名称

Task 会按以下顺序查找配置文件:

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

使用 .dist 变体的目的是允许项目有一个提交版本 (.dist),同时仍然允许个人用户通过添加额外的 Taskfile.yml(将在 .gitignore 上)来覆盖 Taskfile。

从子目录运行 Taskfile

如果在当前工作目录中找不到 Taskfile,它将沿着文件树向上查找,直到找到一个(类似于 git 的工作方式)。 当从这样的子目录运行 Task 时,它的行为就像从包含 Taskfile 的目录运行它一样。

您可以将此功能与特殊的 {{.USER_WORKING_DIR}} 变量一起使用来创建一些非常有用的可重用 task。 例如,如果你有一个包含每个微服务目录的 monorepo,你可以 cd 进入一个微服务目录并运行一个 task 命令来启动它,而不必创建多个 task 或具有相同内容的 Taskfile。 例如:

version: '3'

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

在此示例中,我们可以运行 cd <service>task up,只要 <service> 目录包含 docker-compose.yml,就会启动 Docker Compose。

运行全局 Taskfile

如果您使用 --global(别名 -g)标志调用 Task,它将查找您的 home 目录而不是您的工作目录。 简而言之,Task 将在 $HOME/Taskfile.yml$HOME/Taskfile.yaml 路径上寻找 Taskfile。

这对于您可以在系统的任何地方运行的自动化很有用!

信息

当使用 -g 运行全局 Taskfile 时,task 将默认在 $HOME 上运行,而不是在您的工作目录上!

如前一节所述,{{.USER_WORKING_DIR}} 特殊变量在这里可以非常方便地在您从中调用 task -g 的目录中运行内容。

version: '3'

tasks:
from-home:
cmds:
- pwd

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

环境变量

Task

你可以使用 env 给每个 task 设置自定义环境变量:

version: '3'

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

此外,您可以设置可用于所有 task 的全局环境变量:

version: '3'

env:
GREETING: Hey, there!

tasks:
greet:
cmds:
- echo $GREETING
信息

env 支持扩展和检索 shell 命令的输出,就像变量一样,如您在 变量 部分中看到的那样。

.env 文件

您还可以使用 dotenv: 设置要求 tasks 包含 .env 之类的文件

.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"

也可以在 task 级别指定 .env 文件:

version: '3'

env:
ENV: testing

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

在 task 级别明确指定的环境变量将覆盖点文件中定义的变量:

version: '3'

env:
ENV: testing

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

请注意,您目前无法在包含的 Taskfile 中使用 dotenv 键。

包含其他 Taskfile

如果要在不同项目(Taskfile)之间共享任务,可以使用导入机制使用 includes 关键字包含其他任务文件:

version: '3'

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

给定的 Taskfile 中描述的任务将在指定的命名空间中提供。 因此,您可以调用 task docs:servedocumentation/Taskfile.yml 运行 serve task,或者调用 task docker:buildDockerTasks.yml 文件运行 build task。

相对路径是相对于包含包含 Taskfile 的目录解析的。

操作系统特定 Taskfile

version: '2' 中,task 会自动尝试引入 Taskfile_{{OS}}.yml 文件 (例如Taskfile_windows.yml, Taskfile_linux.ymlTaskfile_darwin.yml)。 但是因为过于隐晦,在版本 3 中被移除了, 在版本 3 可以通过明确的引用来实现类似功能:

version: '3'

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

包含 Taskfile 的目录

默认情况下,包含的 Taskfile 的 task 在当前目录中运行,即使 Taskfile 在另一个目录中,但您可以使用以下替代语法强制其 task 在另一个目录中运行:

version: '3'

includes:
docs:
taskfile: ./docs/Taskfile.yml
dir: ./docs
信息

包含的 Taskfile 必须使用与主 Taskfile 使用的相同规则版本。

可选 includes

如果包含文件丢失,标记为可选的包含将允许 task 继续正常执行。

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"

内部 includes

标记为 internal 的包含会将包含文件的所有 task 也设置为内部 task(请参阅下面的 内部-tasks 部分)。 这在包含不打算由用户直接使用的实用程序任务时很有用。

version: '3'

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

包含 Taskfile 的变量

您还可以在包含 Taskfile 时指定变量。 这对于拥有可以调整甚至多次包含的可重用 Taskfile 可能很有用:

version: '3'

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

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

命名空间别名

包含 Taskfile 时,您可以为命名空间提供一个 aliases 列表。 这与 task 别名 的工作方式相同,可以一起使用来创建更短且更易于键入的命令。

version: '3'

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

在包含的 Taskfile 中声明的变量优先于包含 Taskfile 中的变量! 如果您希望包含的 Taskfile 中的变量可被覆盖,请使用 默认方法MY_VAR: '{{.MY_VAR | default "my-default-value"}}'

内部 tasks

内部 task 是用户不能直接调用的 task。 运行 task --list|--list-all 时,它们不会出现在输出中。 其他 task 可以照常调用内部 task。 这对于创建在命令行上没有用处的可重用、类似函数的 task 很有用。

version: '3'

tasks:
build-image-1:
cmds:
- task: build-image
vars:
DOCKER_IMAGE: image-1

build-image:
internal: true
cmds:
- docker build -t {{.DOCKER_IMAGE}} .

Task 目录

默认情况下,tasks 将在 Taskfile 所在的目录中执行。 但是您可以轻松地让 task 在另一个目录中运行,指定 dir

version: '3'

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

如果该目录不存在,task 会创建它。

Task 依赖

依赖项并行运行,因此一项 task 的依赖项不应相互依赖。 如果您想强制任务顺序运行,请查看下面的 调用另一个 task 部分。

您可能有依赖于其它的 task。 将它们指向 deps 将使它们在运行父 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

在上面的示例中,如果您运行 task buildassets 将始终在 build 之前运行。

一个 task 只能有依赖关系,没有命令来将 task 组合在一起:

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

如果有多个依赖项,它们总是并行运行以获得更好的性能。

提示

您还可以使用 --parallel 标志(别名 -p)使命令行给出的 task 并行运行。 例如: task --parallel js css

如果你想将信息传递给依赖项,你可以像 调用另一个 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}}

平台特定的 tasks 和 cmds

如果您想将 task 的运行限制在明确的平台上,可以使用 platforms: 键来实现。 Task 可以限制在特定的操作系统、架构或两者的组合中。 如果不匹配,任务或命令将被跳过,并且不会抛出任何错误。

允许作为 OS 或 Arch 的值是有效的 GOOSGOARCH 值,正如 此处 的 Go 语言所定义的那样。

下面的 build-windows task 将仅在 Windows 所有架构上运行:

version: '3'

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

这可以限制为特定的架构,如下所示:

version: '3'

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

也可以将 task 限制在特定的架构中:

version: '3'

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

可以指定多个平台,如下所示:

version: '3'

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

个别命令也可以限制在特定平台上:

version: '3'

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

调用另一个 task

当一个 task 有很多依赖时,它们是并发执行的。 这通常会导致更快的构建管道。 但是,在某些情况下,您可能需要串行调用其他 task。 在这种情况下,请使用以下语法:

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"

在被调用 task 中覆盖变量就像通知 vars 属性一样简单:

version: '3'

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

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

deps 也支持上述语法。

提示

注意:如果您想从 包含的 Taskfile 中调用在根 Taskfile 中声明的 task,请像这样添加 : 前缀:task: :task-name

减少不必要的工作

通过指纹识别本地生成的文件及其来源

如果一个 task 生成了一些东西,你可以通知 task 源和生成的文件,这样 task 就会在不需要的时候阻止运行它们。

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

sourcesgenerates 可以配置具体文件或者使用匹配模式。 设置后, Task 会根据源文件的 checksum 来确定是否需要执行当前任务。 如果不需要执行, 则会输出像 Task "js" is up to date 这样的信息。

如果您希望通过文件的修改 timestamp 而不是其 checksum(内容)来进行此检查,只需将 method 属性设置为 timestamp 即可。

version: '3'

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

在需要更大灵活性的情况下,可以使用 status 关键字。 您甚至可以将两者结合起来。 有关示例,请参阅 状态 文档。

信息

默认情况,task 在本地项目的 .task 目录保存 checksums 值。 一般都会在 .gitignore(或类似配置)中忽略掉这个目录,这样它就不会被提交。 (如果您有一个已提交的代码生成任务,那么提交该任务的校验和也是有意义的)。

如果你想要将这些文件存储在另一个目录中,你可以在你的机器中设置一个 TASK_TEMP_DIR 环境变量。 可以使用相对路径,比如 tmp/task,相对项目根目录,也可以用绝对路径、用户目录路径,比如 /tmp/.task~/.task(每个项目单独创建子目录)。

export TASK_TEMP_DIR='~/.task'
信息

每个 task 只为其 sources 存储一个 checksum。 如果您想通过任何输入变量来区分 task,您可以将这些变量添加为 task 标签的一部分,它将被视为不同的 task。

如果您想为每个不同的输入集运行一次 task,直到 sources 实际发生变化,这将很有用。 例如,如果 sources 依赖于变量的值,或者您希望在某些参数发生变化时重新运行 task,即使 sources 没有发生变化也是如此。

提示

将 method 设置为 none 会跳过任何验证并始终运行任务。

信息

要使 checksum(默认)或 timestamp 方法起作用,只需要通知 source 文件即可。 当使用 timestamp 方法时,最后一次运行 task 被认为是一次生成。

使用程序检查来表示任务是最新的

或者,您可以通知一系列测试作为 status。 如果没有错误返回(退出状态 0),task 被认为是最新的:

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

通常,您会将 sourcesgenerates 结合使用 - 但对于生成远程工件(Docker 映像、部署、CD 版本)的 task,checksum source 和 timestamps 需要访问工件或 .checksum 指纹文件。

两个特殊变量 {{.CHECKSUM}}{{.TIMESTAMP}} 可用于 status 命令中的插值,具体取决于分配给 sources 的指纹方法。 只有 source 块才能生成指纹。

请注意,{{.TIMESTAMP}} 变量是一个“实时”Go time.Time 结构,可以使用 time.Time 响应的任何方法进行格式化。

有关详细信息,请参阅 Go Time 文档

如果你想强制任务运行,即使是最新的,你也可以使用 --force-f

此外,如果任何 task 不是最新的,task --status [tasks]... 将以非零退出代码退出。

如果 source/generated 的工件发生变化,或者程序检查失败,status 可以与 指纹 结合以运行任务:

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

使用程序检查取消任务及其依赖项的执行

除了 status 检查之外,preconditions 检查是 status 检查的逻辑逆过程。 也就是说,如果您需要一组特定的条件为 true,您可以使用 preconditionspreconditions 类似于 status 行,除了它们支持 sh 扩展,并且它们应该全部返回 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"

先决条件可以设置特定的失败消息,这些消息可以使用 msg 字段告诉用户要采取什么步骤。

如果一个 task 依赖于一个具有前提条件的子 task,并且不满足该前提条件 - 调用 task 将失败。 请注意,除非给出 --force ,否则以失败的前提条件执行的 task 将不会运行。

status 判断 task 是最新状态时会跳过并继续执行不同, precondition 失败会导致 task 失败,以及所有依赖它的 task 都会失败。

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"

在任务运行时限制

如果 task 由多个 cmd 或多个 deps 执行,您可以使用 run 控制何时执行。 run 也可以设置在 Taskfile 的根目录以更改所有任务的行为,除非被明确覆盖。

run 支持的值:

  • always (默认)总是尝试调用 task,无论先前执行的次数如何
  • once 只调用一次这个任务,不管引用的数量
  • when_changed 只为传递给 task 的每个唯一变量集调用一次 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

变量

在进行变量插值时,Task 将查找以下内容。 它们按权重顺序列在下面(即最重要的第一位):

使用环境变量传输参数的示例:

$ TASK_VARIABLE=a-value task do-something
提示

包含任务名称的特殊变量 .TASK 始终可用。

由于某些 shell 不支持上述语法来设置环境变量 (Windows),task 在不在命令开头时也接受类似的样式。

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

本地声明的变量示例:

version: '3'

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

Taskfile.yml 中的全局变量示例:

version: '3'

vars:
GREETING: Hello from Taskfile!

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

动态变量

以下语法 (sh: prop in a variable) 被认为是动态变量。 该值将被视为命令并产生输出结果用于赋值。 如果有一个或多个尾随换行符,最后一个换行符将被修剪。

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

这适用于所有类型的变量。

将 CLI 参数转发到 cmds

如果 -- 在 CLI 中给出,则所有以下参数都将添加到特殊的 .CLI_ARGS 变量中。 这对于将参数转发给另一个命令很有用。

下面的示例将运行 yarn install

$ task yarn -- install
version: '3'

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

使用 defer 做 task 清理

使用 defer 关键字,可以安排在 task 完成后运行清理。 与仅将其作为最后一个命令的不同之处在于,即使 task 失败,该命令也会运行。

在下面的示例中,即使第三个命令失败,rm -rf tmpdir/ 也会运行:

version: '3'

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

使用其它 task 作为清理任务的命令时,可以这样:

version: '3'

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

cleanup: rm -rf tmpdir/
信息

由于 Go 自身的 defer 工作方式 的性质,如果您安排多个 defer命令,则 defer 命令将以相反的顺序执行。

Go 的模板引擎

Task 在执行命令之前将命令解析为 Go 的模板引擎。 可以通过点语法 (.VARNAME) 访问变量。

Go 的 slim-sprig 库 的所有功能都可用。 以下示例按照给定格式获取当前日期:

version: '3'

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

Task 还增加了以下功能:

  • OS:返回操作系统。 可能的值为“windows”、“linux”、“darwin”(macOS) 和“freebsd”。
  • ARCH:返回 Task 的编译架构为:“386”、“amd64”、“arm”或“s390x”。
  • splitLines:拆分 Unix (\n) 和 Windows (\r\n) 样式的换行符。
  • catLines:用空格替换 Unix (\n) 和 Windows (\r\n) 样式的换行符。
  • toSlash:在 Unix 上不执行任何操作,但在 Windows 上将字符串从 \ 路径格式转换为 /
  • fromSlash:与 toSlash 相反。 在 Unix 上不执行任何操作,但在 Windows 上将字符串从 / 路径格式转换为 \
  • exeExt:返回当前操作系统的正确可执行文件扩展名(Windows 为“.exe”,其他操作系统为“”)。
  • shellQuote:引用一个字符串以使其在 shell 脚本中安全使用。 Task 为此使用了 这个 Go 函数。 假定使用 Bash 语法。
  • splitArgs:将字符串作为命令的参数进行拆分。 Task 使用 这个 Go 函数

示例:

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

帮助

运行 task --list(或 task -l)列出所有带有描述的任务。 以下 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

将打印以下输出:

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

如果您想查看所有任务,还有一个 --list-all(别名 -a)标志。

显示任务摘要

运行 task --summary task-name 将显示任务的摘要。 以下 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

运行 task --summary release 将打印以下输出:

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

如果缺少摘要,将打印描述。 如果任务没有摘要或描述,则会打印一条警告。

请注意:显示摘要不会执行命令

Task 别名

Aliases 是 task 的替代名称。 它们可以使运行具有长名称或难以键入名称的 task 变得更加容易和快速。 您可以在命令行上使用它们,在您的 Taskfile 中 调用子任务 时以及在 包含来自另一个 Taskfile 的别名 task 时。 它们也可以与 命名空间别名 一起使用。

version: '3'

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

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

覆盖 Task 名称

有时你可能想覆盖打印在摘要上的 task 名称,最新消息到 STDOUT 等。 在这种情况下,你可以只设置 label:,也可以用变量进行插值:

version: '3'

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

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

静默模式

静默模式在 Task 运行命令之前禁用命令回显。 对于以下 Taskfile:

version: '3'

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

通常这将打印:

echo "Print something"
Print something

开启静默模式后,将打印以下内容:

Print something

开启静默模式有四种方式:

  • 在 cmds 级别:
version: '3'

tasks:
echo:
cmds:
- cmd: echo "Print something"
silent: true
  • 在 task 级别:
version: '3'

tasks:
echo:
cmds:
- echo "Print something"
silent: true
  • 在 Taskfile 全局级别:
version: '3'

silent: true

tasks:
echo:
cmds:
- echo "Print something"
  • 或者全局使用 --silent-s 标志

如果您想改为禁止 STDOUT,只需将命令重定向到 /dev/null

version: '3'

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

试运行模式

试运行模式 (--dry) 编译并逐步完成每个 task,打印将运行但不执行它们的命令。 这对于调试您的 Taskfile 很有用。

忽略错误

您可以选择在命令执行期间忽略错误。 给定以下 Taskfile:

version: '3'

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

Task 将在运行 exit 1 后中止执行,因为状态代码 1 代表 EXIT_FAILURE。 但是,可以使用 ignore_error 继续执行:

version: '3'

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

也可以为 task 设置 ignore_error,这意味着所有命令的错误都将被忽略。 不过,请记住,此选项不会传播到由 deps 或 cmds 调用的其他 task!

输出语法

默认情况下,Task 只是将正在运行的命令的 STDOUT 和 STDERR 实时重定向到 shell。 这有利于通过命令打印日志记录的实时反馈,但如果同时运行多个命令并打印大量内容,输出可能会变得混乱。

为了使其更具可定制性,目前您可以选择三种不同的输出选项:

  • interleaved (默认)
  • group
  • prefixed

要选择另一个,只需在 Taskfile 根目录中设置即可:

version: '3'

output: 'group'

tasks:
# ...

group 输出将在命令完成后打印一次命令的全部输出,因此您不会对需要很长时间运行的命令有实时反馈。

使用 group 输出时,您可以选择提供模板化消息以在组的开始和结束处打印。 这对于指示 CI 系统对给定任务的所有输出进行分组非常有用,例如使用 GitHub Actions 的 ::group:: 命令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::

使用 group 输出时,如果没有失败(零退出代码),您可以在标准输出和标准错误上执行命令的输出。

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

prefix 输出将为命令打印的每一行添加前缀 [task-name] 作为前缀,但您可以使用 prefix: 属性自定义命令的前缀:

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
提示

output 选项也可以由 --output-o 标志指定。

交互式 CLI 应用

Task 执行包含交互式的命令时有时会出现奇怪的结果, 尤其当 输出模式 设置的不是 interleaved (默认), 或者当交互式应用与其它 task 并发执行时。

interactive: true 告诉 Task 这是一个交互式应用程序,Task 将尝试针对它进行优化:

version: '3'

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

如果您在通过 Task 运行交互式应用程序时仍然遇到问题,请打开一个关于它的 Issue。

短 Task 语法

从 Task v3 开始,如果 task 具有默认设置(例如:没有自定义 env:vars:desc:silent: 等),您现在可以使用更短的语法编写task:

version: '3'

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

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

setshopt

可以为 setshopt 内置函数指定选项。 这可以在全局、task 或命令级别添加。

version: '3'

set: [pipefail]
shopt: [globstar]

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

请记住,并非所有选项在 Task 使用的 shell 解释器库 中都可用。

观察 task

使用 --watch-w 参数可以观察文件变化,然后重新执行 task。 这需要配置 sources 属性,task 才知道观察哪些文件。

默认监控的时间间隔是 5 秒,但可以通过 Taskfile 中根属性 interval: '500ms' 设置,也可以通过命令行 参数 --interval=500ms 设置。

- +

使用指南

快速入门

在项目的根目录中创建一个名为 Taskfile.yml 的文件。 cmds 属性应包含 task 的命令。 下面的示例允许编译 Go 应用程序并使用 esbuild 将多个 CSS 文件合并并缩小为一个文件。

version: '3'

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

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

运行 task 就这样简单:

task assets build

Task 使用 mvdan.cc/sh,一个原生的 Go sh 解释器。 因此,您可以编写 sh/bash 命令,它甚至可以在 Windows 上运行,而 shbash 通常不可用。 请记住,任何被调用的可执行文件都必须在操作系统或 PATH 中可用。

如果不传 task 的名字,默认会调用 "default"。

支持的文件名称

Task 会按以下顺序查找配置文件:

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

使用 .dist 变体的目的是允许项目有一个提交版本 (.dist),同时仍然允许个人用户通过添加额外的 Taskfile.yml(将在 .gitignore 上)来覆盖 Taskfile。

从子目录运行 Taskfile

如果在当前工作目录中找不到 Taskfile,它将沿着文件树向上查找,直到找到一个(类似于 git 的工作方式)。 当从这样的子目录运行 Task 时,它的行为就像从包含 Taskfile 的目录运行它一样。

您可以将此功能与特殊的 {{.USER_WORKING_DIR}} 变量一起使用来创建一些非常有用的可重用 task。 例如,如果你有一个包含每个微服务目录的 monorepo,你可以 cd 进入一个微服务目录并运行一个 task 命令来启动它,而不必创建多个 task 或具有相同内容的 Taskfile。 例如:

version: '3'

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

在此示例中,我们可以运行 cd <service>task up,只要 <service> 目录包含 docker-compose.yml,就会启动 Docker Compose。

运行全局 Taskfile

如果您使用 --global(别名 -g)标志调用 Task,它将查找您的 home 目录而不是您的工作目录。 简而言之,Task 将在 $HOME/Taskfile.yml$HOME/Taskfile.yaml 路径上寻找 Taskfile。

这对于您可以在系统的任何地方运行的自动化很有用!

信息

当使用 -g 运行全局 Taskfile 时,task 将默认在 $HOME 上运行,而不是在您的工作目录上!

如前一节所述,{{.USER_WORKING_DIR}} 特殊变量在这里可以非常方便地在您从中调用 task -g 的目录中运行内容。

version: '3'

tasks:
from-home:
cmds:
- pwd

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

环境变量

Task

你可以使用 env 给每个 task 设置自定义环境变量:

version: '3'

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

此外,您可以设置可用于所有 task 的全局环境变量:

version: '3'

env:
GREETING: Hey, there!

tasks:
greet:
cmds:
- echo $GREETING
信息

env 支持扩展和检索 shell 命令的输出,就像变量一样,如您在 变量 部分中看到的那样。

.env 文件

您还可以使用 dotenv: 设置要求 tasks 包含 .env 之类的文件

.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"

也可以在 task 级别指定 .env 文件:

version: '3'

env:
ENV: testing

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

在 task 级别明确指定的环境变量将覆盖点文件中定义的变量:

version: '3'

env:
ENV: testing

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

请注意,您目前无法在包含的 Taskfile 中使用 dotenv 键。

包含其他 Taskfile

如果要在不同项目(Taskfile)之间共享任务,可以使用导入机制使用 includes 关键字包含其他任务文件:

version: '3'

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

给定的 Taskfile 中描述的任务将在指定的命名空间中提供。 因此,您可以调用 task docs:servedocumentation/Taskfile.yml 运行 serve task,或者调用 task docker:buildDockerTasks.yml 文件运行 build task。

相对路径是相对于包含包含 Taskfile 的目录解析的。

操作系统特定 Taskfile

version: '2' 中,task 会自动尝试引入 Taskfile_{{OS}}.yml 文件 (例如Taskfile_windows.yml, Taskfile_linux.ymlTaskfile_darwin.yml)。 但是因为过于隐晦,在版本 3 中被移除了, 在版本 3 可以通过明确的引用来实现类似功能:

version: '3'

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

包含 Taskfile 的目录

默认情况下,包含的 Taskfile 的 task 在当前目录中运行,即使 Taskfile 在另一个目录中,但您可以使用以下替代语法强制其 task 在另一个目录中运行:

version: '3'

includes:
docs:
taskfile: ./docs/Taskfile.yml
dir: ./docs
信息

包含的 Taskfile 必须使用与主 Taskfile 使用的相同规则版本。

可选 includes

如果包含文件丢失,标记为可选的包含将允许 task 继续正常执行。

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"

内部 includes

标记为 internal 的包含会将包含文件的所有 task 也设置为内部 task(请参阅下面的 内部-tasks 部分)。 这在包含不打算由用户直接使用的实用程序任务时很有用。

version: '3'

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

包含 Taskfile 的变量

您还可以在包含 Taskfile 时指定变量。 这对于拥有可以调整甚至多次包含的可重用 Taskfile 可能很有用:

version: '3'

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

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

命名空间别名

包含 Taskfile 时,您可以为命名空间提供一个 aliases 列表。 这与 task 别名 的工作方式相同,可以一起使用来创建更短且更易于键入的命令。

version: '3'

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

在包含的 Taskfile 中声明的变量优先于包含 Taskfile 中的变量! 如果您希望包含的 Taskfile 中的变量可被覆盖,请使用 默认方法MY_VAR: '{{.MY_VAR | default "my-default-value"}}'

内部 tasks

内部 task 是用户不能直接调用的 task。 运行 task --list|--list-all 时,它们不会出现在输出中。 其他 task 可以照常调用内部 task。 这对于创建在命令行上没有用处的可重用、类似函数的 task 很有用。

version: '3'

tasks:
build-image-1:
cmds:
- task: build-image
vars:
DOCKER_IMAGE: image-1

build-image:
internal: true
cmds:
- docker build -t {{.DOCKER_IMAGE}} .

Task 目录

默认情况下,tasks 将在 Taskfile 所在的目录中执行。 但是您可以轻松地让 task 在另一个目录中运行,指定 dir

version: '3'

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

如果该目录不存在,task 会创建它。

Task 依赖

依赖项并行运行,因此一项 task 的依赖项不应相互依赖。 如果您想强制任务顺序运行,请查看下面的 调用另一个 task 部分。

您可能有依赖于其它的 task。 将它们指向 deps 将使它们在运行父 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

在上面的示例中,如果您运行 task buildassets 将始终在 build 之前运行。

一个 task 只能有依赖关系,没有命令来将 task 组合在一起:

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

如果有多个依赖项,它们总是并行运行以获得更好的性能。

提示

您还可以使用 --parallel 标志(别名 -p)使命令行给出的 task 并行运行。 例如: task --parallel js css

如果你想将信息传递给依赖项,你可以像 调用另一个 task 一样以相同的方式进行:

version: '3'

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

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

平台特定的 tasks 和 cmds

如果您想将 task 的运行限制在明确的平台上,可以使用 platforms: 键来实现。 Task 可以限制在特定的操作系统、架构或两者的组合中。 如果不匹配,任务或命令将被跳过,并且不会抛出任何错误。

允许作为 OS 或 Arch 的值是有效的 GOOSGOARCH 值,正如 此处 的 Go 语言所定义的那样。

下面的 build-windows task 将仅在 Windows 所有架构上运行:

version: '3'

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

这可以限制为特定的架构,如下所示:

version: '3'

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

也可以将 task 限制在特定的架构中:

version: '3'

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

可以指定多个平台,如下所示:

version: '3'

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

个别命令也可以限制在特定平台上:

version: '3'

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

调用另一个 task

当一个 task 有很多依赖时,它们是并发执行的。 这通常会导致更快的构建管道。 但是,在某些情况下,您可能需要串行调用其他 task。 在这种情况下,请使用以下语法:

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"

使用 varssilent 属性,您可以选择在逐个调用的基础上传递变量和切换 静默模式

version: '3'

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

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

deps 也支持上述语法。

提示

注意:如果您想从 包含的 Taskfile 中调用在根 Taskfile 中声明的 task,请像这样添加 : 前缀:task: :task-name

减少不必要的工作

通过指纹识别本地生成的文件及其来源

如果一个 task 生成了一些东西,你可以通知 task 源和生成的文件,这样 task 就会在不需要的时候阻止运行它们。

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

sourcesgenerates 可以配置具体文件或者使用匹配模式。 设置后, Task 会根据源文件的 checksum 来确定是否需要执行当前任务。 如果不需要执行, 则会输出像 Task "js" is up to date 这样的信息。

如果您希望通过文件的修改 timestamp 而不是其 checksum(内容)来进行此检查,只需将 method 属性设置为 timestamp 即可。

version: '3'

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

在需要更大灵活性的情况下,可以使用 status 关键字。 您甚至可以将两者结合起来。 有关示例,请参阅 状态 文档。

信息

默认情况,task 在本地项目的 .task 目录保存 checksums 值。 一般都会在 .gitignore(或类似配置)中忽略掉这个目录,这样它就不会被提交。 (如果您有一个已提交的代码生成任务,那么提交该任务的校验和也是有意义的)。

如果你想要将这些文件存储在另一个目录中,你可以在你的机器中设置一个 TASK_TEMP_DIR 环境变量。 可以使用相对路径,比如 tmp/task,相对项目根目录,也可以用绝对路径、用户目录路径,比如 /tmp/.task~/.task(每个项目单独创建子目录)。

export TASK_TEMP_DIR='~/.task'
信息

每个 task 只为其 sources 存储一个 checksum。 如果您想通过任何输入变量来区分 task,您可以将这些变量添加为 task 标签的一部分,它将被视为不同的 task。

如果您想为每个不同的输入集运行一次 task,直到 sources 实际发生变化,这将很有用。 例如,如果 sources 依赖于变量的值,或者您希望在某些参数发生变化时重新运行 task,即使 sources 没有发生变化也是如此。

提示

将 method 设置为 none 会跳过任何验证并始终运行任务。

信息

要使 checksum(默认)或 timestamp 方法起作用,只需要通知 source 文件即可。 当使用 timestamp 方法时,最后一次运行 task 被认为是一次生成。

使用程序检查来表示任务是最新的

或者,您可以通知一系列测试作为 status。 如果没有错误返回(退出状态 0),task 被认为是最新的:

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

通常,您会将 sourcesgenerates 结合使用 - 但对于生成远程工件(Docker 映像、部署、CD 版本)的 task,checksum source 和 timestamps 需要访问工件或 .checksum 指纹文件。

两个特殊变量 {{.CHECKSUM}}{{.TIMESTAMP}} 可用于 status 命令中的插值,具体取决于分配给 sources 的指纹方法。 只有 source 块才能生成指纹。

请注意,{{.TIMESTAMP}} 变量是一个“实时”Go time.Time 结构,可以使用 time.Time 响应的任何方法进行格式化。

有关详细信息,请参阅 Go Time 文档

如果你想强制任务运行,即使是最新的,你也可以使用 --force-f

此外,如果任何 task 不是最新的,task --status [tasks]... 将以非零退出代码退出。

如果 source/generated 的工件发生变化,或者程序检查失败,status 可以与 指纹 结合以运行任务:

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

使用程序检查取消任务及其依赖项的执行

除了 status 检查之外,preconditions 检查是 status 检查的逻辑逆过程。 也就是说,如果您需要一组特定的条件为 true,您可以使用 preconditionspreconditions 类似于 status 行,除了它们支持 sh 扩展,并且它们应该全部返回 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"

先决条件可以设置特定的失败消息,这些消息可以使用 msg 字段告诉用户要采取什么步骤。

如果一个 task 依赖于一个具有前提条件的子 task,并且不满足该前提条件 - 调用 task 将失败。 请注意,除非给出 --force ,否则以失败的前提条件执行的 task 将不会运行。

status 判断 task 是最新状态时会跳过并继续执行不同, precondition 失败会导致 task 失败,以及所有依赖它的 task 都会失败。

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"

在任务运行时限制

如果 task 由多个 cmd 或多个 deps 执行,您可以使用 run 控制何时执行。 run 也可以设置在 Taskfile 的根目录以更改所有任务的行为,除非被明确覆盖。

run 支持的值:

  • always (默认)总是尝试调用 task,无论先前执行的次数如何
  • once 只调用一次这个任务,不管引用的数量
  • when_changed 只为传递给 task 的每个唯一变量集调用一次 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

变量

在进行变量插值时,Task 将查找以下内容。 它们按权重顺序列在下面(即最重要的第一位):

使用环境变量传输参数的示例:

$ TASK_VARIABLE=a-value task do-something
提示

包含任务名称的特殊变量 .TASK 始终可用。

由于某些 shell 不支持上述语法来设置环境变量 (Windows),task 在不在命令开头时也接受类似的样式。

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

本地声明的变量示例:

version: '3'

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

Taskfile.yml 中的全局变量示例:

version: '3'

vars:
GREETING: Hello from Taskfile!

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

动态变量

以下语法 (sh: prop in a variable) 被认为是动态变量。 该值将被视为命令并产生输出结果用于赋值。 如果有一个或多个尾随换行符,最后一个换行符将被修剪。

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

这适用于所有类型的变量。

将 CLI 参数转发到 cmds

如果 -- 在 CLI 中给出,则所有以下参数都将添加到特殊的 .CLI_ARGS 变量中。 这对于将参数转发给另一个命令很有用。

下面的示例将运行 yarn install

$ task yarn -- install
version: '3'

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

使用 defer 做 task 清理

使用 defer 关键字,可以安排在 task 完成后运行清理。 与仅将其作为最后一个命令的不同之处在于,即使 task 失败,该命令也会运行。

在下面的示例中,即使第三个命令失败,rm -rf tmpdir/ 也会运行:

version: '3'

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

使用其它 task 作为清理任务的命令时,可以这样:

version: '3'

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

cleanup: rm -rf tmpdir/
信息

由于 Go 自身的 defer 工作方式 的性质,如果您安排多个 defer命令,则 defer 命令将以相反的顺序执行。

Go 的模板引擎

Task 在执行命令之前将命令解析为 Go 的模板引擎。 可以通过点语法 (.VARNAME) 访问变量。

Go 的 slim-sprig 库 的所有功能都可用。 以下示例按照给定格式获取当前日期:

version: '3'

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

Task 还增加了以下功能:

  • OS:返回操作系统。 可能的值为“windows”、“linux”、“darwin”(macOS) 和“freebsd”。
  • ARCH:返回 Task 的编译架构为:“386”、“amd64”、“arm”或“s390x”。
  • splitLines:拆分 Unix (\n) 和 Windows (\r\n) 样式的换行符。
  • catLines:用空格替换 Unix (\n) 和 Windows (\r\n) 样式的换行符。
  • toSlash:在 Unix 上不执行任何操作,但在 Windows 上将字符串从 \ 路径格式转换为 /
  • fromSlash:与 toSlash 相反。 在 Unix 上不执行任何操作,但在 Windows 上将字符串从 / 路径格式转换为 \
  • exeExt:返回当前操作系统的正确可执行文件扩展名(Windows 为“.exe”,其他操作系统为“”)。
  • shellQuote:引用一个字符串以使其在 shell 脚本中安全使用。 Task 为此使用了 这个 Go 函数。 假定使用 Bash 语法。
  • splitArgs:将字符串作为命令的参数进行拆分。 Task 使用 这个 Go 函数

示例:

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

帮助

运行 task --list(或 task -l)列出所有带有描述的任务。 以下 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

将打印以下输出:

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

如果您想查看所有任务,还有一个 --list-all(别名 -a)标志。

显示任务摘要

运行 task --summary task-name 将显示任务的摘要。 以下 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

运行 task --summary release 将打印以下输出:

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

如果缺少摘要,将打印描述。 如果任务没有摘要或描述,则会打印一条警告。

请注意:显示摘要不会执行命令

Task 别名

Aliases 是 task 的替代名称。 它们可以使运行具有长名称或难以键入名称的 task 变得更加容易和快速。 您可以在命令行上使用它们,在您的 Taskfile 中 调用子任务 时以及在 包含来自另一个 Taskfile 的别名 task 时。 它们也可以与 命名空间别名 一起使用。

version: '3'

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

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

覆盖 Task 名称

有时你可能想覆盖打印在摘要上的 task 名称,最新消息到 STDOUT 等。 在这种情况下,你可以只设置 label:,也可以用变量进行插值:

version: '3'

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

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

静默模式

静默模式在 Task 运行命令之前禁用命令回显。 对于以下 Taskfile:

version: '3'

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

通常这将打印:

echo "Print something"
Print something

开启静默模式后,将打印以下内容:

Print something

开启静默模式有四种方式:

  • 在 cmds 级别:
version: '3'

tasks:
echo:
cmds:
- cmd: echo "Print something"
silent: true
  • 在 task 级别:
version: '3'

tasks:
echo:
cmds:
- echo "Print something"
silent: true
  • 在 Taskfile 全局级别:
version: '3'

silent: true

tasks:
echo:
cmds:
- echo "Print something"
  • 或者全局使用 --silent-s 标志

如果您想改为禁止 STDOUT,只需将命令重定向到 /dev/null

version: '3'

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

试运行模式

试运行模式 (--dry) 编译并逐步完成每个 task,打印将运行但不执行它们的命令。 这对于调试您的 Taskfile 很有用。

忽略错误

您可以选择在命令执行期间忽略错误。 给定以下 Taskfile:

version: '3'

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

Task 将在运行 exit 1 后中止执行,因为状态代码 1 代表 EXIT_FAILURE。 但是,可以使用 ignore_error 继续执行:

version: '3'

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

也可以为 task 设置 ignore_error,这意味着所有命令的错误都将被忽略。 不过,请记住,此选项不会传播到由 deps 或 cmds 调用的其他 task!

输出语法

默认情况下,Task 只是将正在运行的命令的 STDOUT 和 STDERR 实时重定向到 shell。 这有利于通过命令打印日志记录的实时反馈,但如果同时运行多个命令并打印大量内容,输出可能会变得混乱。

为了使其更具可定制性,目前您可以选择三种不同的输出选项:

  • interleaved (默认)
  • group
  • prefixed

要选择另一个,只需在 Taskfile 根目录中设置即可:

version: '3'

output: 'group'

tasks:
# ...

group 输出将在命令完成后打印一次命令的全部输出,因此您不会对需要很长时间运行的命令有实时反馈。

使用 group 输出时,您可以选择提供模板化消息以在组的开始和结束处打印。 这对于指示 CI 系统对给定任务的所有输出进行分组非常有用,例如使用 GitHub Actions 的 ::group:: 命令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::

使用 group 输出时,如果没有失败(零退出代码),您可以在标准输出和标准错误上执行命令的输出。

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

prefix 输出将为命令打印的每一行添加前缀 [task-name] 作为前缀,但您可以使用 prefix: 属性自定义命令的前缀:

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
提示

output 选项也可以由 --output-o 标志指定。

交互式 CLI 应用

Task 执行包含交互式的命令时有时会出现奇怪的结果, 尤其当 输出模式 设置的不是 interleaved (默认), 或者当交互式应用与其它 task 并发执行时。

interactive: true 告诉 Task 这是一个交互式应用程序,Task 将尝试针对它进行优化:

version: '3'

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

如果您在通过 Task 运行交互式应用程序时仍然遇到问题,请打开一个关于它的 Issue。

短 Task 语法

从 Task v3 开始,如果 task 具有默认设置(例如:没有自定义 env:vars:desc:silent: 等),您现在可以使用更短的语法编写task:

version: '3'

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

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

setshopt

可以为 setshopt 内置函数指定选项。 这可以在全局、task 或命令级别添加。

version: '3'

set: [pipefail]
shopt: [globstar]

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

请记住,并非所有选项在 Task 使用的 shell 解释器库 中都可用。

观察 task

使用 --watch-w 参数可以观察文件变化,然后重新执行 task。 这需要配置 sources 属性,task 才知道观察哪些文件。

默认监控的时间间隔是 5 秒,但可以通过 Taskfile 中根属性 interval: '500ms' 设置,也可以通过命令行 参数 --interval=500ms 设置。

+ \ No newline at end of file