Variables
A variable holds a value so that later steps can use it. Set one with set:, and read it with {{ .NAME }}:
tasks:
greet:
steps:
- set:
- NAME: Ada
- run: echo "Hello, {{ .NAME }}"$ hobnob greet
run: [greet] echo "Hello, Ada"
[greet] Hello, Ada
✓ [greet] doneThe dot in .NAME means "the variable called NAME". Variable names are written in ALL_CAPS by convention.
Setting variables in a step
One set: step can set several variables. They're set top to bottom, so each one can use the ones above it:
tasks:
setup:
steps:
- set:
- API: https://the-trivia-api.com/v2
- RANDOM_URL: "{{ .API }}/questions?limit=1"A variable set in a step exists from that step onwards, until the task ends.
A value doesn't have to be text. Write a YAML list or map and the variable holds a real list or map, which you can loop over or pick items out of:
tasks:
setup:
steps:
- set:
- CATEGORIES: [history, science]
- LABELS: { history: History buffs, science: Lab coats }Structured data covers what you can do with them.
Variables for the whole file
When several tasks need the same value, set it once at the top of the file instead of in every task. There are two blocks for this:
vars:holds defaults. Whoever runs the task can override them.const:holds fixed values. Nothing can override them.
const:
- API: https://the-trivia-api.com/v2
vars:
- CATEGORY: general_knowledge
tasks:
ask:
steps:
- run: echo "{{ .API }}/questions?categories={{ .CATEGORY }}"Without arguments, the task uses the defaults. Passing CATEGORY=science overrides the vars: default, but passing API=… changes nothing, because API is a constant:
$ hobnob ask CATEGORY=science
run: [ask] echo "https://the-trivia-api.com/v2/questions?categories=science"
[ask] https://the-trivia-api.com/v2/questions?categories=science
✓ [ask] doneEntries in both blocks are written like set: entries, and each can use the ones above it.
Loading variables from a file
env: loads variables from files. It's the place for values that differ between machines or shouldn't be committed, such as API keys:
env:
- .env# .env
API_KEY=abc123Each line of .env becomes a variable, so a task can read {{ .API_KEY }}. Paths are relative to the hobnob file. To hide values like this one in hobnob's output, see Secrets.
Which value wins
The same name can be set in more than one place. Before a task runs, hobnob gathers variables from five places, and the strongest one wins. From weakest to strongest:
- Your shell's environment variables. They're the weakest so that something set in your terminal can't make a task behave differently on your machine.
vars:env:files- Command-line arguments, such as
CATEGORY=science. const:It beats command-line arguments, which is what makes it constant.
Once the task runs, its steps (set:, prompts, captured output, loops and calls) override any of these, and the latest step wins. The one thing a step can't do is set a const: name.
hobnob works them out in the opposite order, strongest first, so each one can use whatever has already been worked out:
const:can use earlier constants and the built-in variables. Nothing else.- Command-line arguments are taken as given.
env:file paths can use constants, command-line arguments, the built-in variables and your shell's environment.vars:can use all of that, plus the variables theenv:files loaded.- Steps run last, in order, and can use any variable set before them.
So a vars: entry can build its default from an env: file:
env:
- .env # API_HOST=staging.example.com
vars:
- API: "https://{{ .API_HOST }}/v1"Variables also come from command-line arguments, prompts, captured output and loops. Each has its own page.
Built-in variables
hobnob sets two variables itself:
HOBNOB_FILE_DIR: the directory containing the hobnob file.HOBNOB_INVOCATION_DIR: the directory you ran hobnob from.
Rules
The rules below cover the edge cases. You won't need most of them day to day.
const:
- A step that sets a
const:name stops the file loading, before any task runs. That coversset:,get:,into:,with:andloop:anywhere in the file, including the names a loop gives its items (see Loops).
vars:
An entry that's overridden isn't evaluated at all.
An entry can't use its own name. This fails to load, even when
CATEGORYis set in your shell:yamlvars: - CATEGORY: '{{ .CATEGORY | default "general_knowledge" }}' # errorA
vars:entry is already a default, so write- CATEGORY: general_knowledge. To let a shell variable set the default, read it under a different name:yamlvars: - CATEGORY: '{{ .TRIVIA_CATEGORY | default "general_knowledge" }}'
env:
- Only
.shfiles are run. Any other file is read asNAME=valuelines. A.shfile is run in a separate shell, and only the variables it sets or changes are loaded. - A missing file prints a warning and is skipped.
- Later files override earlier ones.