Templating Reference
Task's templating engine uses Go's text/template package to interpolate values. This reference covers the main features and all available functions for creating dynamic Taskfiles.
Basic Usage
Most string values in Task can be templated using double curly braces {{
and }}
. Anything inside the braces is executed as a Go template.
Simple Variable Interpolation
version: '3'
tasks:
hello:
vars:
MESSAGE: 'Hello, World!'
cmds:
- 'echo {{.MESSAGE}}'
Output:
Hello, World!
Conditional Logic
version: '3'
tasks:
maybe-happy:
vars:
SMILE: ':\)'
FROWN: ':\('
HAPPY: true
cmds:
- 'echo {{if .HAPPY}}{{.SMILE}}{{else}}{{.FROWN}}{{end}}'
Output:
:)
Function Calls and Pipes
version: '3'
tasks:
uniq:
vars:
NUMBERS: '0,1,1,1,2,2,3'
cmds:
- 'echo {{splitList "," .NUMBERS | uniq | join ", "}}'
Output:
0, 1, 2, 3
Control Flow with Loops
version: '3'
tasks:
loop:
vars:
NUMBERS: [0, 1, 1, 1, 2, 2, 3]
cmds:
- |
{{range $index, $num := .NUMBERS}}
{{if gt $num 1}}{{break}}{{end}}
echo {{$index}}: {{$num}}
{{end}}
Output:
0: 0
1: 1
2: 1
3: 1
Special Variables
Task provides special variables that are always available in templates. These override any user-defined variables with the same name.
CLI
CLI_ARGS
- Type:
string
- Description: All extra arguments passed after
--
as a string
tasks:
test:
cmds:
- go test {{.CLI_ARGS}}
task test -- -v -race
# Runs: go test -v -race
CLI_ARGS_LIST
- Type:
[]string
- Description: All extra arguments passed after
--
as a shell parsed list
tasks:
docker-run:
cmds:
- docker run {{range .CLI_ARGS_LIST}}{{.}} {{end}}myapp
CLI_FORCE
- Type:
bool
- Description: Whether
--force
or--force-all
flags were set
tasks:
deploy:
cmds:
- |
{{if .CLI_FORCE}}
echo "Force deployment enabled"
{{end}}
./deploy.sh
CLI_SILENT
- Type:
bool
- Description: Whether
--silent
flag was set
CLI_VERBOSE
- Type:
bool
- Description: Whether
--verbose
flag was set
CLI_OFFLINE
- Type:
bool
- Description: Whether
--offline
flag was set
Task
TASK
- Type:
string
- Description: Name of the current task
tasks:
build:
cmds:
- echo "Running task {{.TASK}}"
ALIAS
- Type:
string
- Description: Alias used for the current task, otherwise matches
TASK
TASK_EXE
- Type:
string
- Description: Task executable name or path
tasks:
self-update:
cmds:
- echo "Updating {{.TASK_EXE}}"
File Paths
ROOT_TASKFILE
- Type:
string
- Description: Absolute path of the root Taskfile
ROOT_DIR
- Type:
string
- Description: Absolute path of the root Taskfile directory
TASKFILE
- Type:
string
- Description: Absolute path of the current (included) Taskfile
TASKFILE_DIR
- Type:
string
- Description: Absolute path of the current Taskfile directory
TASK_DIR
- Type:
string
- Description: Absolute path where the task is executed
USER_WORKING_DIR
- Type:
string
- Description: Absolute path where
task
was called from
tasks:
info:
cmds:
- echo "Root {{.ROOT_DIR}}"
- echo "Current {{.TASKFILE_DIR}}"
- echo "Working {{.USER_WORKING_DIR}}"
Status
CHECKSUM
- Type:
string
- Description: Checksum of files in
sources
(only instatus
withchecksum
method)
TIMESTAMP
- Type:
time.Time
- Description: Greatest timestamp of files in
sources
(only instatus
withtimestamp
method)
tasks:
build:
method: checksum
sources: ['**/*.go']
status:
- test "{{.CHECKSUM}}" = "$(cat .last-checksum)"
cmds:
- go build ./...
- echo "{{.CHECKSUM}}" > .last-checksum
Loop
ITEM
- Type:
any
- Description: Current iteration value when using
for
property
tasks:
greet:
cmds:
- for: [alice, bob, charlie]
cmd: echo "Hello {{.ITEM}}"
Can be renamed using as
:
tasks:
greet:
cmds:
- for:
var: NAMES
as: NAME
cmd: echo "Hello {{.NAME}}"
Defer
EXIT_CODE
- Type:
int
- Description: Failed command exit code (only in
defer
, only when non-zero)
tasks:
deploy:
cmds:
- ./deploy.sh
- defer: |
{{if .EXIT_CODE}}
echo "Deployment failed with code {{.EXIT_CODE}}"
./rollback.sh
{{end}}
System
TASK_VERSION
- Type:
string
- Description: Current version of Task
tasks:
version:
cmds:
- echo "Using Task {{.TASK_VERSION}}"
Available Functions
Task provides a comprehensive set of functions for templating. Functions can be chained using pipes (|
) and combined for powerful templating capabilities.
Logic and Control Flow
and
, or
, not
Boolean operations for conditional logic
tasks:
conditional:
vars:
DEBUG: true
VERBOSE: false
PRODUCTION: false
cmds:
- echo "{{if and .DEBUG .VERBOSE}}Debug mode with verbose{{end}}"
- echo "{{if or .DEBUG .VERBOSE}}Some kind of debug{{end}}"
- echo "{{if not .PRODUCTION}}Development build{{end}}"
eq
, ne
, lt
, le
, gt
, ge
Comparison operations
tasks:
compare:
vars:
VERSION: 3
cmds:
- echo "{{if gt .VERSION 2}}Version 3 or higher{{end}}"
- echo "{{if eq .VERSION 3}}Exactly version 3{{end}}"
Data Access and Manipulation
index
Access array/map elements by index or key
tasks:
access:
vars:
SERVICES: [api, web, worker]
CONFIG:
map:
database: postgres
port: 5432
cmds:
- echo "First service {{index .SERVICES 0}}"
- echo "Database {{index .CONFIG "database"}}"
len
Get length of arrays, maps, or strings
tasks:
length:
vars:
ITEMS: [a, b, c, d]
TEXT: "Hello World"
cmds:
- echo "Found {{len .ITEMS}} items"
- echo "Text has {{len .TEXT}} characters"
slice
Extract a portion of an array or string
tasks:
slice-demo:
vars:
ITEMS: [a, b, c, d, e]
cmds:
- echo "{{slice .ITEMS 1 3}}" # [b c]
String Functions
Basic String Operations
tasks:
string-basic:
vars:
MESSAGE: ' Hello World '
NAME: 'john doe'
TEXT: "Hello World"
cmds:
- echo "{{.MESSAGE | trim}}" # "Hello World"
- echo "{{.NAME | title}}" # "John Doe"
- echo "{{.NAME | upper}}" # "JOHN DOE"
- echo "{{.MESSAGE | lower}}" # "hello world"
- echo "{{.NAME | trunc 4}}" # "john"
- echo "{{"test" | repeat 3}}" # "testtesttest"
- echo "{{substr .TEXT 0 5}}" # "Hello"
String Testing and Searching
tasks:
string-test:
vars:
FILENAME: 'app.tar.gz'
EMAIL: 'user@example.com'
cmds:
- echo "{{.FILENAME | hasPrefix "app"}}" # true
- echo "{{.FILENAME | hasSuffix ".gz"}}" # true
- echo "{{.EMAIL | contains "@"}}" # true
String Replacement and Formatting
tasks:
string-format:
vars:
TEXT: 'Hello, World!'
UNSAFE: 'file with spaces.txt'
cmds:
- echo "{{.TEXT | replace "," ""}}" # "Hello World!"
- echo "{{.TEXT | quote}}" # "\"Hello, World!\""
- echo "{{.UNSAFE | shellQuote}}" # Shell-safe quoting
- echo "{{.UNSAFE | q}}" # Short alias for shellQuote
Regular Expressions
tasks:
regex:
vars:
EMAIL: 'user@example.com'
TEXT: 'abc123def456'
cmds:
- echo "{{regexMatch "@" .EMAIL}}" # true
- echo "{{regexFind "[0-9]+" .TEXT}}" # "123"
- echo "{{regexFindAll "[0-9]+" .TEXT -1}}" # ["123", "456"]
- echo "{{regexReplaceAll "[0-9]+" .TEXT "X"}}" # "abcXdefX"
List Functions
List Access and Basic Operations
tasks:
list-basic:
vars:
ITEMS: ["apple", "banana", "cherry", "date"]
cmds:
- echo "First {{.ITEMS | first}}" # "apple"
- echo "Last {{.ITEMS | last}}" # "date"
- echo "Rest {{.ITEMS | rest}}" # ["banana", "cherry", "date"]
- echo "Initial {{.ITEMS | initial}}" # ["apple", "banana", "cherry"]
- echo "Length {{.ITEMS | len}}" # 4
List Manipulation
tasks:
list-manipulate:
vars:
NUMBERS: [3, 1, 4, 1, 5, 9, 1]
FRUITS: ["apple", "banana"]
cmds:
- echo "{{.NUMBERS | uniq}}" # [3, 1, 4, 5, 9]
- echo "{{.NUMBERS | sortAlpha}}" # [1, 1, 1, 3, 4, 5, 9]
- echo"'{{append .FRUITS "cherry"}}"" # ["apple", "banana", "cherry"]
- echo "{{ without .NUMBERS 1}}" # [3, 4, 5, 9]
- echo "{{.NUMBERS | has 5}}" # true
String Lists
tasks:
string-lists:
vars:
CSV: 'apple,banana,cherry'
WORDS: ['hello', 'world', 'from', 'task']
MULTILINE: |
line1
line2
line3
cmds:
- echo "{{.CSV | splitList ","}}" # ["apple", "banana", "cherry"]
- echo "{{.WORDS | join " "}}" # "hello world from task"
- echo "{{.WORDS | sortAlpha}}" # ["from", "hello", "task", "world"]
- echo "{{.MULTILINE | splitLines}}" # Split on newlines (Unix/Windows)
- echo "{{.MULTILINE | catLines}}" # Replace newlines with spaces
Shell Argument Parsing
tasks:
shell-args:
vars:
ARGS: 'file1.txt -v --output="result file.txt"'
cmds:
- |
{{range .ARGS | splitArgs}}
echo "Arg: {{.}}"
{{end}}
Math Functions
tasks:
math:
vars:
A: 10
B: 3
NUMBERS: [1, 5, 3, 9, 2]
cmds:
- echo "Addition {{add .A .B}}" # 13
- echo "Subtraction {{sub .A .B}}" # 7
- echo "Multiplication {{mul .A .B}}" # 30
- echo "Division {{div .A .B}}" # 3
- echo "Modulo {{mod .A .B}}" # 1
- echo "Maximum {{.NUMBERS | max}}" # 9
- echo "Minimum {{.NUMBERS | min}}" # 1
- echo "Random 1-99 {{randInt 1 100}}" # Random number
- echo "Random 0-999 {{randIntN 1000}}" # Random number 0-999
Date and Time Functions
tasks:
date-time:
vars:
BUILD_DATE: "2023-12-25"
cmds:
- echo "Now {{now | date "2006-01-02 15:04:05"}}"
- echo {{ toDate "2006-01-02" .BUILD_DATE }}
- echo "Build {{.BUILD_DATE | toDate "2006-01-02" | date "Jan 2, 2006"}}"
- echo "Unix timestamp {{now | unixEpoch}}"
- echo "Duration ago {{now | ago}}"
System Functions
Platform Information
tasks:
platform:
cmds:
- echo "OS {{OS}}" # linux, darwin, windows, etc.
- echo "Architecture {{ARCH}}" # amd64, arm64, etc.
- echo "CPU cores {{numCPU}}" # Number of CPU cores
- echo "Building for {{OS}}/{{ARCH}}"
Path Functions
tasks:
paths:
vars:
WIN_PATH: 'C:\Users\name\file.txt'
OUTPUT_DIR: 'dist'
BINARY_NAME: 'myapp'
cmds:
- echo "{{.WIN_PATH | toSlash}}" # Convert to forward slashes
- echo "{{.WIN_PATH | fromSlash}}" # Convert to OS-specific slashes
- echo "{{joinPath .OUTPUT_DIR .BINARY_NAME}}" # Join path elements
- echo "Relative {{relPath .ROOT_DIR .TASKFILE_DIR}}" # Get relative path
Data Structure Functions
Dictionary Operations
tasks:
dict:
vars:
CONFIG:
map:
database: postgres
port: 5432
ssl: true
cmds:
- echo "Database {{.CONFIG | get "database"}}"
- echo "Keys {{.CONFIG | keys}}"
- echo "Has SSL {{.CONFIG | hasKey "ssl"}}"
- echo "{{dict "env" "prod" "debug" false}}"
Merging and Combining
tasks:
merge:
vars:
BASE_CONFIG:
map:
timeout: 30
retries: 3
USER_CONFIG:
map:
timeout: 60
debug: true
cmds:
- echo "{{merge .BASE_CONFIG .USER_CONFIG | toJson}}"
Default Values and Coalescing
tasks:
defaults:
vars:
API_URL: ""
DEBUG: false
ITEMS: []
cmds:
- echo "{{.API_URL | default "http://localhost:8080"}}"
- echo "{{.DEBUG | default true}}"
- echo "{{.MISSING_VAR | default "fallback"}}"
- echo "{{coalesce .API_URL .FALLBACK_URL "default"}}"
- echo "Is empty {{empty .ITEMS}}" # true
Encoding and Serialization
JSON
tasks:
json:
vars:
DATA:
map:
name: 'Task'
version: '3.0'
JSON_STRING: '{"key": "value", "number": 42}'
cmds:
- echo "{{.DATA | toJson}}"
- echo "{{.DATA | toPrettyJson}}"
- echo "{{.JSON_STRING | fromJson }}"
YAML
tasks:
yaml:
vars:
CONFIG:
map:
database:
host: localhost
port: 5432
YAML_STRING: |
key: value
items:
- one
- two
cmds:
- echo "{{.CONFIG | toYaml}}"
- echo "{{.YAML_STRING | fromYaml}}"
Base64
tasks:
base64:
vars:
SECRET: 'my-secret-key'
cmds:
- echo "{{.SECRET | b64enc}}" # Encode to base64
- echo "{{"bXktc2VjcmV0LWtleQ==" | b64dec}}" # Decode from base64
Type Conversion
tasks:
convert:
vars:
NUM_STR: '42'
FLOAT_STR: '3.14'
BOOL_STR: 'true'
ITEMS: [1, 2, 3]
cmds:
- echo "{{.NUM_STR | atoi | add 8}}" # String to int: 50
- echo "{{.FLOAT_STR | float64}}" # String to float: 3.14
- echo "{{.ITEMS | toStrings}}" # Convert to strings: ["1", "2", "3"]
Utility Functions
UUID Generation
tasks:
generate:
vars:
DEPLOYMENT_ID: "{{uuid}}"
cmds:
- echo "Deployment ID {{.DEPLOYMENT_ID}}"
Debugging
tasks:
debug:
vars:
COMPLEX_VAR:
map:
items: [1, 2, 3]
nested:
key: value
cmds:
- echo "{{spew .COMPLEX_VAR}}" # Pretty-print for debugging
Output Functions
Formatted Output
tasks:
output:
vars:
VERSION: "1.2.3"
BUILD: 42
cmds:
- echo '{{print "Simple output"}}'
- echo '{{printf "Version %s.%d" .VERSION .BUILD}}'
- echo '{{println "With newline"}}'