Skip to content

Commit

Permalink
feat(config): allow skipping source template rendering in generateFiles
Browse files Browse the repository at this point in the history
In many cases, it's not desirable to pass files specified under
`generateFiles[].sourcePath` through template resolution. This adds a
flag to control that behavior explicitly.
  • Loading branch information
edvald authored and thsig committed Sep 29, 2021
1 parent 0bd44ef commit e840669
Show file tree
Hide file tree
Showing 19 changed files with 334 additions and 3 deletions.
8 changes: 8 additions & 0 deletions core/src/config/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export interface BaseBuildSpec {
export interface ModuleFileSpec {
sourcePath?: string
targetPath: string
resolveTemplates: boolean
value?: string
}

Expand Down Expand Up @@ -129,6 +130,13 @@ const generatedFileSchema = () =>
Note that any existing file with the same name will be overwritten. If the path contains one or more directories, they will be automatically created if missing.
`
),
resolveTemplates: joi
.boolean()
// TODO: flip this default in 0.13?
.default(true)
.description(
"By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to skip resolving template strings. Note that this does not apply when setting the `value` field, since that's resolved earlier when parsing the configuration."
),
value: joi.string().description("The desired file contents as a string."),
})
.xor("value", "sourcePath")
Expand Down
17 changes: 15 additions & 2 deletions core/src/resolve-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,10 +429,23 @@ export class ModuleResolver {
if (fileSpec.sourcePath) {
const configDir = resolvedConfig.configPath ? dirname(resolvedConfig.configPath) : resolvedConfig.path
const sourcePath = resolve(configDir, fileSpec.sourcePath)
contents = (await readFile(sourcePath)).toString()

try {
contents = (await readFile(sourcePath)).toString()
} catch (err) {
throw new ConfigurationError(
`Unable to read file at ${sourcePath}, specified under generateFiles in module ${resolvedConfig.name}: ${err}`,
{
sourcePath,
}
)
}
}

const resolvedContents = resolveTemplateString(contents, configContext, { unescape: true })
const resolvedContents = fileSpec.resolveTemplates
? resolveTemplateString(contents, configContext, { unescape: true })
: contents

const targetDir = resolve(resolvedConfig.path, ...posix.dirname(fileSpec.targetPath).split(posix.sep))
const targetPath = resolve(resolvedConfig.path, ...fileSpec.targetPath.split(posix.sep))

Expand Down
2 changes: 1 addition & 1 deletion core/test/unit/src/config/module-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ describe("module templates", () => {
{
type: "test",
name: "foo",
generateFiles: [{ sourcePath: "foo/bar.txt", targetPath: "foo.txt" }],
generateFiles: [{ sourcePath: "foo/bar.txt", targetPath: "foo.txt", resolveTemplates: true }],
},
],
},
Expand Down
85 changes: 85 additions & 0 deletions core/test/unit/src/garden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3102,6 +3102,7 @@ describe("Garden", () => {
{
value: "Project name: ${project.name}, Escaped string: $${var.foo}",
targetPath,
resolveTemplates: true,
},
],
},
Expand All @@ -3114,6 +3115,88 @@ describe("Garden", () => {
expect(contents.toString()).to.equal("Project name: test-project-a, Escaped string: ${var.foo}")
})

it("optionally skips resolving template strings when reading a source file", async () => {
const garden = await makeTestGardenA()

const sourcePath = randomString(8) + ".log"
const sourceFullPath = join(pathFoo, sourcePath)
const value = "Project name: ${project.name}, Escaped string: $${var.foo}"

await writeFile(sourceFullPath, value)

const targetPath = "targetfile.log"

garden.setModuleConfigs([
{
apiVersion: DEFAULT_API_VERSION,
name: "module-a",
type: "test",
allowPublish: false,
build: { dependencies: [] },
disabled: false,
include: [],
path: pathFoo,
serviceConfigs: [],
taskConfigs: [],
testConfigs: [],
spec: {},
generateFiles: [
{
sourcePath,
targetPath,
resolveTemplates: false,
},
],
},
])

const module = await garden.resolveModule("module-a")
const expectedTargetPath = join(module.path, targetPath)
const contents = await readFile(expectedTargetPath)

expect(contents.toString()).to.equal(value)
})

it("throws helpful error is sourcePath doesn't contain globs and can't be found", async () => {
const garden = await makeTestGardenA()

garden.setModuleConfigs([
{
apiVersion: DEFAULT_API_VERSION,
name: "module-a",
type: "test",
allowPublish: false,
build: { dependencies: [] },
disabled: false,
include: [],
path: pathFoo,
serviceConfigs: [],
taskConfigs: [],
testConfigs: [],
spec: {},
generateFiles: [
{
sourcePath: "blorg",
targetPath: "targetfile.log",
resolveTemplates: false,
},
],
},
])

await expectError(
() => garden.resolveModule("module-a"),
(err) =>
expect(stripAnsi(err.message)).to.equal(
dedent`
Failed resolving one or more modules:
module-a: Unable to read file at ${pathFoo}/blorg, specified under generateFiles in module module-a: Error: ENOENT: no such file or directory, open '${pathFoo}/blorg'
`
)
)
})

it("resolves and writes a module file in a remote module", async () => {
const garden = await makeTestGarden(pathFoo, {
config: {
Expand Down Expand Up @@ -3157,6 +3240,7 @@ describe("Garden", () => {
{
sourcePath,
targetPath,
resolveTemplates: true,
},
],
},
Expand Down Expand Up @@ -3220,6 +3304,7 @@ describe("Garden", () => {
{
sourcePath,
targetPath,
resolveTemplates: true,
},
],
},
Expand Down
15 changes: 15 additions & 0 deletions docs/reference/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,11 @@ providers:
# directories, they will be automatically created if missing.
targetPath:

# By default, Garden will attempt to resolve any Garden template strings in source files. Set this to
# false to skip resolving template strings. Note that this does not apply when setting the `value` field,
# since that's resolved earlier when parsing the configuration.
resolveTemplates:

# The desired file contents as a string.
value:

Expand Down Expand Up @@ -1748,6 +1753,11 @@ moduleConfigs:
# directories, they will be automatically created if missing.
targetPath:

# By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to
# skip resolving template strings. Note that this does not apply when setting the `value` field, since that's
# resolved earlier when parsing the configuration.
resolveTemplates:

# The desired file contents as a string.
value:

Expand Down Expand Up @@ -2252,6 +2262,11 @@ modules:
# directories, they will be automatically created if missing.
targetPath:

# By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to
# skip resolving template strings. Note that this does not apply when setting the `value` field, since that's
# resolved earlier when parsing the configuration.
resolveTemplates:

# The desired file contents as a string.
value:

Expand Down
15 changes: 15 additions & 0 deletions docs/reference/module-template-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ modules:
# directories, they will be automatically created if missing.
targetPath:

# By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to
# skip resolving template strings. Note that this does not apply when setting the `value` field, since that's
# resolved earlier when parsing the configuration.
resolveTemplates: true

# The desired file contents as a string.
value:

Expand Down Expand Up @@ -470,6 +475,16 @@ Note that any existing file with the same name will be overwritten. If the path
| ----------- | -------- |
| `posixPath` | Yes |

### `modules[].generateFiles[].resolveTemplates`

[modules](#modules) > [generateFiles](#modulesgeneratefiles) > resolveTemplates

By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to skip resolving template strings. Note that this does not apply when setting the `value` field, since that's resolved earlier when parsing the configuration.

| Type | Default | Required |
| --------- | ------- | -------- |
| `boolean` | `true` | No |

### `modules[].generateFiles[].value`

[modules](#modules) > [generateFiles](#modulesgeneratefiles) > value
Expand Down
15 changes: 15 additions & 0 deletions docs/reference/module-types/configmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ generateFiles:
# directories, they will be automatically created if missing.
targetPath:

# By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to
# skip resolving template strings. Note that this does not apply when setting the `value` field, since that's
# resolved earlier when parsing the configuration.
resolveTemplates: true

# The desired file contents as a string.
value:

Expand Down Expand Up @@ -378,6 +383,16 @@ Note that any existing file with the same name will be overwritten. If the path
| ----------- | -------- |
| `posixPath` | Yes |

### `generateFiles[].resolveTemplates`

[generateFiles](#generatefiles) > resolveTemplates

By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to skip resolving template strings. Note that this does not apply when setting the `value` field, since that's resolved earlier when parsing the configuration.

| Type | Default | Required |
| --------- | ------- | -------- |
| `boolean` | `true` | No |

### `generateFiles[].value`

[generateFiles](#generatefiles) > value
Expand Down
15 changes: 15 additions & 0 deletions docs/reference/module-types/conftest.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ generateFiles:
# directories, they will be automatically created if missing.
targetPath:

# By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to
# skip resolving template strings. Note that this does not apply when setting the `value` field, since that's
# resolved earlier when parsing the configuration.
resolveTemplates: true

# The desired file contents as a string.
value:

Expand Down Expand Up @@ -389,6 +394,16 @@ Note that any existing file with the same name will be overwritten. If the path
| ----------- | -------- |
| `posixPath` | Yes |

### `generateFiles[].resolveTemplates`

[generateFiles](#generatefiles) > resolveTemplates

By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to skip resolving template strings. Note that this does not apply when setting the `value` field, since that's resolved earlier when parsing the configuration.

| Type | Default | Required |
| --------- | ------- | -------- |
| `boolean` | `true` | No |

### `generateFiles[].value`

[generateFiles](#generatefiles) > value
Expand Down
15 changes: 15 additions & 0 deletions docs/reference/module-types/container.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ generateFiles:
# directories, they will be automatically created if missing.
targetPath:

# By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to
# skip resolving template strings. Note that this does not apply when setting the `value` field, since that's
# resolved earlier when parsing the configuration.
resolveTemplates: true

# The desired file contents as a string.
value:

Expand Down Expand Up @@ -904,6 +909,16 @@ Note that any existing file with the same name will be overwritten. If the path
| ----------- | -------- |
| `posixPath` | Yes |

### `generateFiles[].resolveTemplates`

[generateFiles](#generatefiles) > resolveTemplates

By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to skip resolving template strings. Note that this does not apply when setting the `value` field, since that's resolved earlier when parsing the configuration.

| Type | Default | Required |
| --------- | ------- | -------- |
| `boolean` | `true` | No |

### `generateFiles[].value`

[generateFiles](#generatefiles) > value
Expand Down
15 changes: 15 additions & 0 deletions docs/reference/module-types/exec.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ generateFiles:
# directories, they will be automatically created if missing.
targetPath:

# By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to
# skip resolving template strings. Note that this does not apply when setting the `value` field, since that's
# resolved earlier when parsing the configuration.
resolveTemplates: true

# The desired file contents as a string.
value:

Expand Down Expand Up @@ -548,6 +553,16 @@ Note that any existing file with the same name will be overwritten. If the path
| ----------- | -------- |
| `posixPath` | Yes |

### `generateFiles[].resolveTemplates`

[generateFiles](#generatefiles) > resolveTemplates

By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to skip resolving template strings. Note that this does not apply when setting the `value` field, since that's resolved earlier when parsing the configuration.

| Type | Default | Required |
| --------- | ------- | -------- |
| `boolean` | `true` | No |

### `generateFiles[].value`

[generateFiles](#generatefiles) > value
Expand Down
15 changes: 15 additions & 0 deletions docs/reference/module-types/hadolint.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ generateFiles:
# directories, they will be automatically created if missing.
targetPath:

# By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to
# skip resolving template strings. Note that this does not apply when setting the `value` field, since that's
# resolved earlier when parsing the configuration.
resolveTemplates: true

# The desired file contents as a string.
value:

Expand Down Expand Up @@ -377,6 +382,16 @@ Note that any existing file with the same name will be overwritten. If the path
| ----------- | -------- |
| `posixPath` | Yes |

### `generateFiles[].resolveTemplates`

[generateFiles](#generatefiles) > resolveTemplates

By default, Garden will attempt to resolve any Garden template strings in source files. Set this to false to skip resolving template strings. Note that this does not apply when setting the `value` field, since that's resolved earlier when parsing the configuration.

| Type | Default | Required |
| --------- | ------- | -------- |
| `boolean` | `true` | No |

### `generateFiles[].value`

[generateFiles](#generatefiles) > value
Expand Down
Loading

0 comments on commit e840669

Please sign in to comment.