Skip to content

Commit

Permalink
feat(template): add yamlEncode and yamlDecode template helpers
Browse files Browse the repository at this point in the history
Nice and simple. See the updated reference docs in the commit.
  • Loading branch information
edvald authored and thsig committed Jun 22, 2021
1 parent de1acd8 commit dbaf972
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
51 changes: 50 additions & 1 deletion core/src/template-string/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@

import uuid from "uuid"
import { TemplateStringError } from "../exceptions"
import { keyBy, mapValues, escapeRegExp, trim, isEmpty, camelCase, kebabCase } from "lodash"
import { keyBy, mapValues, escapeRegExp, trim, isEmpty, camelCase, kebabCase, isArrayLike } from "lodash"
import { joi, JoiDescription } from "../config/common"
import Joi from "@hapi/joi"
import { validateSchema } from "../config/validation"
import { safeLoad, safeLoadAll } from "js-yaml"
import { safeDumpYaml } from "../util/util"

interface TemplateHelperFunction {
name: string
Expand Down Expand Up @@ -188,6 +190,53 @@ const helperFunctionSpecs: TemplateHelperFunction[] = [
exampleOutput: "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed",
fn: () => uuid.v4(),
},
{
name: "yamlDecode",
description:
"Decodes the given YAML-encoded string. Note that for multi-document YAML strings, you need to set the 2nd argument to true (see below).",
arguments: {
string: joi.string().required().description("The YAML-encoded string to decode."),
multiDocument: joi.boolean().description("Set to true if you'd like to parse a multi-document YAML string."),
},
outputSchema: joi.any(),
exampleArguments: [["a: 1\nb: 2\n"], ["a: 1\nb: 2\n---\na: 3\nb: 4\n", true]],
fn: (str: string, multi?: boolean) => (multi ? safeLoadAll(str) : safeLoad(str)),
},
{
name: "yamlEncode",
description: "Encodes the given value as YAML.",
arguments: {
value: joi.any().required().description("The value to encode as YAML."),
multiDocument: joi.boolean().description("Set to true if you'd like to output a multi-document YAML string."),
},
outputSchema: joi.string(),
exampleArguments: [
[{ my: "simple document" }],
[
[
{ a: 1, b: 2 },
{ a: 3, b: 4 },
],
true,
],
],
fn: (value: any, multiDocument?: boolean) => {
if (multiDocument) {
if (!isArrayLike(value)) {
throw new TemplateStringError(
`yamlEncode: Set multiDocument=true but value is not an array (got ${typeof value})`,
{
value,
multiDocument,
}
)
}
return "---" + value.map(safeDumpYaml).join("---")
} else {
return safeDumpYaml(value)
}
},
},
]

export const helperFunctions = keyBy(
Expand Down
20 changes: 20 additions & 0 deletions docs/reference/template-strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,26 @@ Usage: `uuidv4()`
Examples:
* `${uuidv4()}` -> `1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed`

### yamlDecode

Decodes the given YAML-encoded string. Note that for multi-document YAML strings, you need to set the 2nd argument to true (see below).

Usage: `yamlDecode(string, [multiDocument])`

Examples:
* `${yamlDecode("a: 1\nb: 2\n")}` -> `{"a":1,"b":2}`
* `${yamlDecode("a: 1\nb: 2\n---\na: 3\nb: 4\n", true)}` -> `[{"a":1,"b":2},{"a":3,"b":4}]`

### yamlEncode

Encodes the given value as YAML.

Usage: `yamlEncode(value, [multiDocument])`

Examples:
* `${yamlEncode({"my":"simple document"})}` -> `"my: simple document\n"`
* `${yamlEncode([{"a":1,"b":2},{"a":3,"b":4}], true)}` -> `"---a: 1\nb: 2\n---a: 3\nb: 4\n"`

## Project configuration context

The following keys are available in any template strings within project definitions in `garden.yml` config files, except the `name` field (which cannot be templated). See the [Environment](#environment-configuration-context) and [Provider](#provider-configuration-context) sections below for additional keys available when configuring `environments` and `providers`, respectively.
Expand Down

0 comments on commit dbaf972

Please sign in to comment.