scaffolder-backend: switch template action to use SecureTemplater
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -21,22 +21,9 @@ import { ScmIntegrations } from '@backstage/integration';
|
||||
import { fetchContents } from './helpers';
|
||||
import { createTemplateAction } from '../../createTemplateAction';
|
||||
import globby from 'globby';
|
||||
import nunjucks from 'nunjucks';
|
||||
import fs from 'fs-extra';
|
||||
import { isBinaryFile } from 'isbinaryfile';
|
||||
|
||||
/*
|
||||
* Maximise compatibility with Jinja (and therefore cookiecutter)
|
||||
* using nunjucks jinja compat mode. Since this method mutates
|
||||
* the global nunjucks instance, we can't enable this per-template,
|
||||
* or only for templates with cookiecutter compat enabled, so the
|
||||
* next best option is to explicitly enable it globally and allow
|
||||
* folks to rely on jinja compatibility behaviour in fetch:template
|
||||
* templates if they wish.
|
||||
*
|
||||
* cf. https://mozilla.github.io/nunjucks/api.html#installjinjacompat
|
||||
*/
|
||||
nunjucks.installJinjaCompat();
|
||||
import { SecureTemplater } from '../../../../lib/templating/SecureTemplater';
|
||||
|
||||
type CookieCompatInput = {
|
||||
copyWithoutRender?: string[];
|
||||
@@ -60,6 +47,8 @@ export function createFetchTemplateAction(options: {
|
||||
}) {
|
||||
const { reader, integrations } = options;
|
||||
|
||||
const templater = new SecureTemplater();
|
||||
|
||||
return createTemplateAction<FetchTemplateInput>({
|
||||
id: 'fetch:template',
|
||||
description:
|
||||
@@ -113,6 +102,8 @@ export function createFetchTemplateAction(options: {
|
||||
async handler(ctx) {
|
||||
ctx.logger.info('Fetching template content from remote URL');
|
||||
|
||||
await templater.initializeIfNeeded();
|
||||
|
||||
const workDir = await ctx.createTemporaryDirectory();
|
||||
const templateDir = resolvePath(workDir, 'template');
|
||||
|
||||
@@ -179,36 +170,6 @@ export function createFetchTemplateAction(options: {
|
||||
).flat(),
|
||||
);
|
||||
|
||||
// Create a templater
|
||||
const templater = nunjucks.configure({
|
||||
...(ctx.input.cookiecutterCompat
|
||||
? {}
|
||||
: {
|
||||
tags: {
|
||||
// TODO(mtlewis/orkohunter): Document Why we are changing the literals? Not here, but on scaffolder docs. ADR?
|
||||
variableStart: '${{',
|
||||
variableEnd: '}}',
|
||||
},
|
||||
}),
|
||||
// We don't want this builtin auto-escaping, since uses HTML escape sequences
|
||||
// like `"` - the correct way to escape strings in our case depends on
|
||||
// the file type.
|
||||
autoescape: false,
|
||||
});
|
||||
|
||||
if (ctx.input.cookiecutterCompat) {
|
||||
// The "jsonify" filter built into cookiecutter is common
|
||||
// in fetch:cookiecutter templates, so when compat mode
|
||||
// is enabled we alias the "dump" filter from nunjucks as
|
||||
// jsonify. Dump accepts an optional `spaces` parameter
|
||||
// which enables indented output, but when this parameter
|
||||
// is not supplied it works identically to jsonify.
|
||||
//
|
||||
// cf. https://cookiecutter.readthedocs.io/en/latest/advanced/template_extensions.html?highlight=jsonify#jsonify-extension
|
||||
// cf. https://mozilla.github.io/nunjucks/templating.html#dump
|
||||
templater.addFilter('jsonify', templater.getFilter('dump'));
|
||||
}
|
||||
|
||||
// Cookiecutter prefixes all parameters in templates with
|
||||
// `cookiecutter.`. To replicate this, we wrap our parameters
|
||||
// in an object with a `cookiecutter` property when compat
|
||||
@@ -238,7 +199,9 @@ export function createFetchTemplateAction(options: {
|
||||
renderFilename = renderContents = !nonTemplatedEntries.has(location);
|
||||
}
|
||||
if (renderFilename) {
|
||||
localOutputPath = templater.renderString(localOutputPath, context);
|
||||
localOutputPath = templater.render(localOutputPath, context, {
|
||||
cookiecutterCompat: ctx.input.cookiecutterCompat,
|
||||
});
|
||||
}
|
||||
const outputPath = resolvePath(outputDir, localOutputPath);
|
||||
// variables have been expanded to make an empty file name
|
||||
@@ -275,7 +238,9 @@ export function createFetchTemplateAction(options: {
|
||||
await fs.outputFile(
|
||||
outputPath,
|
||||
renderContents
|
||||
? templater.renderString(inputFileContents, context)
|
||||
? templater.render(inputFileContents, context, {
|
||||
cookiecutterCompat: ctx.input.cookiecutterCompat,
|
||||
})
|
||||
: inputFileContents,
|
||||
{ mode: statsObj.mode },
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user