All examples below have been generated using -x -- or --execute, which allows passing a template as argument rather than reading a file. In either case, whether the template file -- with -f or --file -- or the template argument is used, all functions are available.
Each function includes a set of examples. The lines prepended with a $ are bash commands you can try by running them on your terminal.
tgen includes all functions from Sprig, which are the same functions you could be used to if you have ever used Helm. This includes:
- String Functions:
trim,wrap,randAlpha,plural, etc.- String List Functions:
splitList,sortAlpha, etc.
- String List Functions:
- Integer Math Functions:
add,max,mul, etc.- Integer Slice Functions:
until,untilStep
- Integer Slice Functions:
- Float Math Functions:
addf,maxf,mulf, etc. - Date Functions:
now,date, etc. - Defaults Functions:
default,empty,coalesce,fromJson,toJson,toPrettyJson,toRawJson,ternary - Encoding Functions:
b64enc,b64dec, etc. - Lists and List Functions:
list,first,uniq, etc. - Dictionaries and Dict Functions:
get,set,dict,hasKey,pluck,dig,deepCopy, etc. - Type Conversion Functions:
atoi,int64,toString, etc. - Path and Filepath Functions:
base,dir,ext,clean,isAbs,osBase,osDir,osExt,osClean,osIsAbs - Flow Control Functions:
fail - Advanced Functions
- UUID Functions:
uuidv4 - OS Functions:
env,expandenv - Version Comparison Functions:
semver,semverCompare - Reflection:
typeOf,kindIs,typeIsLike, etc. - Cryptographic and Security Functions:
derivePassword,sha256sum,genPrivateKey, etc. - Network:
getHostByName
- UUID Functions:
These are functions that are not part of Sprig, but are included in tgen for convenience.
Raw returns the value provided as a string. It's kept for backwards compatibility and non-breaking old resources:
$ tgen -x '{{ "hello" | raw }}'
helloConverts the string to a lowercase value:
$ tgen -x '{{ "HELLO" | lowercase }}'
helloConverts the string to a uppercase value:
$ tgen -x '{{ "hello" | uppercase }}'
HELLOFunctions akin to Go's own fmt.Sprintf and fmt.Sprintln. printf is an alias of sprintf:
$ tgen -x '{{ sprintf "Hello, %s!" "World" }}'
Hello, World!Functions to grab environment variable values. For env, the value will be printed out or be empty if the environment variable is not set. For envdefault, the value will be the value retrieved from the environment variable or the default value specified.
Both env and envdefault are case insensitive -- either "home" or "HOME" will work.
When --strict mode is enabled, if env is called with a environment variable name with no value set or set to empty, the application will exit with error. Useful if you must receive a value or fail a CI build, for example.
Consider the following example reading these environment variables:
$ tgen -x '{{ env "user" }}'
patrick
$ tgen -x '{{ env "USER" }}'
patrickThen trying to read a nonexistent environment variable with --strict mode enabled:
$ tgen -x '{{ env "foobar" }}' --strict
Error: evaluating /dev/stdin:1:3: strict mode on: environment variable not found: $FOOBARAnd bypassing strict mode by setting a default value:
$ tgen -x '{{ envdefault "SQL_HOST" "sql.example.com" }}' --strict
sql.example.comFor custom messages, consider using required instead.
Generates a random string of a given length:
$ tgen -x '{{ rndstring 8 }}'
mHNmtrbfFunctions to encode and decode from base64. These are also available from Sprig as b64enc and b64dec.
$ tgen -x '{{ base64encode "hello" }}'
aGVsbG8=$ tgen -x '{{ base64decode "aGVsbG8=" }}'
helloRead a file from a local path -- either relative or absolute -- and print it as a string. Useful to embed files from your local machine or CI environment into your template:
$ tgen -x '{{ readfile "/etc/hostname" }}'
localhost$ tgen -x '{{ readlocalfile "go.mod" }}'
module github.com/patrickdappollonio/tgen
require github.com/spf13/cobra v1.2.1
go 1.16$ tgen -x '{{ readlocalfile "../etc/hosts" }}'
Error: template: tgen:1:3: executing "tgen" at <readlocalfile "../etc/hosts">: error calling readlocalfile: unable to open local file "/etc/hosts": file is not under current working directorySome considerations:
- If a relative path is provided, all paths must be relative to the current working directory.
- If a template is inside a subfolder from the current working directory, the path you must provide in
readfilehas to be starting from the current working directory, not from the location where the template file is.
- If a template is inside a subfolder from the current working directory, the path you must provide in
- For
readfile, the path can be eithe relative or absolute:- Any file can be read through
readfile, and yes, that includes/etc/passwdand other sensitive files. If this level of security is important to you, consider runningtgenin trusted environments. This is by design to allow embedding files from other folders external to the current working directory and its subdirectories. - If reading any file is a problem, consider using
readlocalfile.
- Any file can be read through
- For
readlocalfile, the path can only be relative:- Absolute paths will return in an error.
- The current working directory will be prepended to the path provided.
- Only files within the current working directory and its subdirectories can be read through this function.
For a more complete example, see Template Generation a la Helm.
Read a directory from a local path -- either relative or absolute -- and returns it as an array of strings, which can be used to iterate over the files in the directory.
readdir and readlocaldir do not recurse into subdirectories, while readdirrecursive and readlocaldirrecursive do.
$ tree testdata
testdata
├── file1.txt
└── file2.txt
$ tgen -x '{{ readdir "testdata" }}'
[file1.txt file2.txt]$ tgen -x '{{ readlocaldir "testdata" }}'
[file1.txt file2.txt]Attempting to read a directory that does not exist will return an error:
$ tgen -x '{{ readdir "doesnotexist" }}'
Error: template: tgen:1:3: executing "tgen" at <readdir "doesnotexist">: error calling readdir: open doesnotexist: no such file or directoryAnd attempting to read a directory outside the current working directory with readlocaldir will return an error:
$ tgen -x '{{ readlocaldir "../testdata" }}'
Error: template: tgen:1:3: executing "tgen" at <readlocaldir "../testdata">: error calling readlocaldir: unable to open local directory "../testdata": directory is not under current working directoryWith the recursive functions, the same rules apply but they will also include the files and folders in the subdirectories. Folders will be returned as strings with a trailing /.
$ tree testdata
testdata
├── file1.txt
├── file2.txt
└── subdir
├── subfile1.txt
└── subfile2.txt
$ tgen -x '{{ readdirrecursive "testdata" }}'
[file1.txt file2.txt subdir/ subdir/subfile1.txt subdir/subfile2.txt]$ tgen -x '{{ readlocaldirrecursive "testdata" }}'
[file1.txt file2.txt subdir/ subdir/subfile1.txt subdir/subfile2.txt]Some considerations:
- Symbolic links are not followed.
- If a relative path is provided, all paths must be relative to the current working directory.
- For
readdirandreaddirrecursive, the path can be either relative or absolute:- Any directory can be read through
readdir, and yes, that includes/etcand other sensitive files. If this level of security is important to you, consider runningtgenin trusted environments. This is by design to allow embedding files from other folders external to the current working directory and its subdirectories. - If reading any directory is a problem, consider using
readlocaldirorreadlocaldirrecursive.
- Any directory can be read through
- For
readlocaldirandreadlocaldirrecursive, the path can only be relative:- Absolute paths will return in an error.
- The current working directory will be prepended to the path provided.
- Only directories within the current working directory and its subdirectories can be read through this function.
Parses the input and splits on line breaks. linebyline is a shorcut for split (from the Sprig library) with a split character of \n. lbl is an alias of linebyline:
$ tgen -x '{{ linebyline "foo\nbar" }}'
[foo bar]$ tgen -x '{{ range linebyline "foo\nbar" }}{{ . | nindent 2 }}{{ end }}'
foo
barReturns a Go slice to only the items after the nth item. Negative numbers for after are not supported and will result in an error.
# Creates a sequence from 1 to 5, then
# returns all values after 2
$ tgen -x '{{ after 2 (seq 5) }}'
[3 4 5]
# Alternate way of writing it
$ tgen -x '{{ seq 5 | after 2 }}'
[3 4 5]Returns an error if the value is empty. Useful to ensure a value is provided, and if not, fail the template generation.
$ tgen -x '{{ env "foo" | required "environment variable \"foo\" is required" }}'
Error: evaluating /dev/stdin:1:15: environment variable "foo" is requiredNote that you can also use --strict mode to achieve a similar result. The difference between --strict and required is that required works anywhere: not just on missing YAML value keys or environment variables. Here's another example:
$ tgen -x '{{ "" | required "Value must be set" }}'
Error: evaluating /dev/stdin:1:8: Value must be set