From 8172de1a3b67edaadf7a79707643ef809c77983e Mon Sep 17 00:00:00 2001 From: Rhys Arkins <rhys@arkins.net> Date: Sun, 5 Apr 2020 10:09:55 +0200 Subject: [PATCH] refactor: util/template for handlebars (#5878) --- .../__snapshots__/validation.spec.ts.snap | 4 +-- lib/config/validation.spec.ts | 2 +- lib/config/validation.ts | 10 +++--- lib/manager/regex/index.spec.ts | 2 +- lib/manager/regex/index.ts | 6 ++-- lib/util/template/index.ts | 7 ++++ lib/workers/common.ts | 3 ++ lib/workers/pr/body/banner.ts | 6 ++-- lib/workers/pr/body/changelogs.ts | 4 +-- lib/workers/pr/body/footer.ts | 4 +-- lib/workers/pr/body/index.ts | 6 ++-- lib/workers/pr/body/notes.ts | 6 ++-- lib/workers/pr/body/updates-table.ts | 6 ++-- lib/workers/repository/updates/branchify.ts | 19 +++++----- lib/workers/repository/updates/generate.ts | 35 ++++++++++--------- 15 files changed, 63 insertions(+), 57 deletions(-) create mode 100644 lib/util/template/index.ts diff --git a/lib/config/__snapshots__/validation.spec.ts.snap b/lib/config/__snapshots__/validation.spec.ts.snap index 83336f9b5c..3d5612c6c7 100644 --- a/lib/config/__snapshots__/validation.spec.ts.snap +++ b/lib/config/__snapshots__/validation.spec.ts.snap @@ -1,10 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`config/validation validateConfig(config) catches invalid handlebars templates 1`] = ` +exports[`config/validation validateConfig(config) catches invalid templates 1`] = ` Array [ Object { "depName": "Configuration Error", - "message": "Invalid handlebars template in config path: commitMessage", + "message": "Invalid template in config path: commitMessage", }, ] `; diff --git a/lib/config/validation.spec.ts b/lib/config/validation.spec.ts index 18d8363460..b34d761609 100644 --- a/lib/config/validation.spec.ts +++ b/lib/config/validation.spec.ts @@ -11,7 +11,7 @@ describe('config/validation', () => { expect(warnings).toHaveLength(1); expect(warnings).toMatchSnapshot(); }); - it('catches invalid handlebars templates', async () => { + it('catches invalid templates', async () => { const config = { commitMessage: '{{{something}}', }; diff --git a/lib/config/validation.ts b/lib/config/validation.ts index 9813b3ba49..200bb43792 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -1,11 +1,11 @@ import is from '@sindresorhus/is'; -import * as handlebars from 'handlebars'; import { getOptions, RenovateOptions } from './definitions'; import { resolveConfigPresets } from './presets'; import { hasValidSchedule, hasValidTimezone } from '../workers/branch/schedule'; import * as managerValidator from './validation-helpers/managers'; import { RenovateConfig, ValidationMessage } from './common'; import { regEx } from '../util/regex'; +import * as template from '../util/template'; const options = getOptions(); @@ -77,13 +77,13 @@ export async function validateConfig( ]; if ((key.endsWith('Template') || templateKeys.includes(key)) && val) { try { - let res = handlebars.compile(val)(config); - res = handlebars.compile(res)(config); - handlebars.compile(res)(config); + let res = template.compile(val.toString(), config); + res = template.compile(res, config); + template.compile(res, config); } catch (err) { errors.push({ depName: 'Configuration Error', - message: `Invalid handlebars template in config path: ${currentPath}`, + message: `Invalid template in config path: ${currentPath}`, }); } } diff --git a/lib/manager/regex/index.spec.ts b/lib/manager/regex/index.spec.ts index e63a83cd9e..c2810eef81 100644 --- a/lib/manager/regex/index.spec.ts +++ b/lib/manager/regex/index.spec.ts @@ -46,7 +46,7 @@ describe(getName(__filename), () => { const res = await extractPackageFile('', 'Dockerfile', config); expect(res).toBeNull(); }); - it('returns null if invalid handlebars template', async () => { + it('returns null if invalid template', async () => { const config = { matchStrings: [ 'ENV .*?_VERSION=(?<currentValue>.*) # (?<datasource>.*?)/(?<depName>.*?)(\\&versioning=(?<versioning>.*?))?\\s', diff --git a/lib/manager/regex/index.ts b/lib/manager/regex/index.ts index 131645fd78..93dfd2265a 100644 --- a/lib/manager/regex/index.ts +++ b/lib/manager/regex/index.ts @@ -1,4 +1,4 @@ -import * as handlebars from 'handlebars'; +import * as template from '../../util/template'; import { CustomExtractConfig, PackageFile, Result } from '../common'; import { regEx } from '../../util/regex'; import { logger } from '../../logger'; @@ -35,11 +35,11 @@ export function extractPackageFile( const fieldTemplate = `${field}Template`; if (config[fieldTemplate]) { try { - dep[field] = handlebars.compile(config[fieldTemplate])(groups); + dep[field] = template.compile(config[fieldTemplate], groups); } catch (err) { logger.warn( { template: config[fieldTemplate] }, - 'Error compiling handlebars template for custom manager' + 'Error compiling template for custom manager' ); return null; } diff --git a/lib/util/template/index.ts b/lib/util/template/index.ts new file mode 100644 index 0000000000..b77980fbba --- /dev/null +++ b/lib/util/template/index.ts @@ -0,0 +1,7 @@ +import * as handlebars from 'handlebars'; + +handlebars.registerHelper('encodeURIComponent', encodeURIComponent); + +export function compile(template: string, input: any): string { + return handlebars.compile(template)(input); +} diff --git a/lib/workers/common.ts b/lib/workers/common.ts index c19b82953b..9e4cfe28e9 100644 --- a/lib/workers/common.ts +++ b/lib/workers/common.ts @@ -17,7 +17,9 @@ export interface BranchUpgradeConfig RenovateSharedConfig { artifactErrors?: ArtifactError[]; branchName: string; + commitBody?: string; commitMessage?: string; + commitMessageExtra?: string; currentDigest?: string; currentDigestShort?: string; currentValue?: string; @@ -34,6 +36,7 @@ export interface BranchUpgradeConfig parentBranch?: string; prBodyNotes?: string[]; + prBodyTemplate?: string; prPriority?: number; prTitle?: string; releases?: Release[]; diff --git a/lib/workers/pr/body/banner.ts b/lib/workers/pr/body/banner.ts index 57dca7f20c..431c9606ed 100644 --- a/lib/workers/pr/body/banner.ts +++ b/lib/workers/pr/body/banner.ts @@ -1,10 +1,10 @@ -import handlebars from 'handlebars'; +import * as template from '../../../util/template'; import { BranchConfig } from '../../common'; // istanbul ignore next export function getPrBanner(config: BranchConfig): string { if (config.global && config.global.prBanner) { - return handlebars.compile(config.global.prBanner)(config) + '\n\n'; + return template.compile(config.global.prBanner, config) + '\n\n'; } if (config.isGroup) { return ''; // TODO: why? @@ -12,5 +12,5 @@ export function getPrBanner(config: BranchConfig): string { if (!config.prBanner) { return ''; } - return handlebars.compile(config.prBanner)(config) + '\n\n'; + return template.compile(config.prBanner.toString(), config) + '\n\n'; } diff --git a/lib/workers/pr/body/changelogs.ts b/lib/workers/pr/body/changelogs.ts index 62361663f0..ba455defeb 100644 --- a/lib/workers/pr/body/changelogs.ts +++ b/lib/workers/pr/body/changelogs.ts @@ -1,4 +1,4 @@ -import handlebars from 'handlebars'; +import * as template from '../../../util/template'; import releaseNotesHbs from '../changelog/hbs-template'; import { BranchConfig } from '../../common'; @@ -9,7 +9,7 @@ export function getChangelogs(config: BranchConfig): string { return releaseNotes; } releaseNotes += - '\n\n---\n\n' + handlebars.compile(releaseNotesHbs)(config) + '\n\n'; + '\n\n---\n\n' + template.compile(releaseNotesHbs, config) + '\n\n'; releaseNotes = releaseNotes.replace(/### \[`vv/g, '### [`v'); // Generic replacements/link-breakers diff --git a/lib/workers/pr/body/footer.ts b/lib/workers/pr/body/footer.ts index ee49fb0343..9a48c50e91 100644 --- a/lib/workers/pr/body/footer.ts +++ b/lib/workers/pr/body/footer.ts @@ -1,10 +1,10 @@ -import handlebars from 'handlebars'; +import * as template from '../../../util/template'; import { BranchConfig } from '../../common'; // istanbul ignore next export function getPrFooter(config: BranchConfig): string { if (config.global && config.global.prFooter) { - return '\n---\n\n' + handlebars.compile(config.global.prFooter)(config); + return '\n---\n\n' + template.compile(config.global.prFooter, config); } return ''; } diff --git a/lib/workers/pr/body/index.ts b/lib/workers/pr/body/index.ts index 6d36b4bd49..995567b828 100644 --- a/lib/workers/pr/body/index.ts +++ b/lib/workers/pr/body/index.ts @@ -1,4 +1,4 @@ -import handlebars from 'handlebars'; +import * as template from '../../../util/template'; import { platform } from '../../../platform'; import { get } from '../../../versioning'; import { getPrConfigDescription } from './config-description'; @@ -10,8 +10,6 @@ import { getChangelogs } from './changelogs'; import { getControls } from './controls'; import { BranchConfig } from '../../common'; -handlebars.registerHelper('encodeURIComponent', encodeURIComponent); - function massageUpdateMetadata(config: BranchConfig): void { config.upgrades.forEach(upgrade => { /* eslint-disable no-param-reassign */ @@ -80,7 +78,7 @@ export async function getPrBody(config: BranchConfig): Promise<string> { const defaultPrBodyTemplate = '{{{banner}}}{{{table}}}{{{notes}}}{{{changelogs}}}{{{configDescription}}}{{{controls}}}{{{footer}}}'; const prBodyTemplate = config.prBodyTemplate || defaultPrBodyTemplate; - let prBody = handlebars.compile(prBodyTemplate)(content); + let prBody = template.compile(prBodyTemplate, content); prBody = prBody.trim(); prBody = prBody.replace(/\n\n\n+/g, '\n\n'); prBody = platform.getPrBody(prBody); diff --git a/lib/workers/pr/body/notes.ts b/lib/workers/pr/body/notes.ts index 60d8348be9..672bd1d827 100644 --- a/lib/workers/pr/body/notes.ts +++ b/lib/workers/pr/body/notes.ts @@ -1,5 +1,5 @@ import is from '@sindresorhus/is'; -import handlebars from 'handlebars'; +import * as template from '../../../util/template'; import { logger } from '../../../logger'; import { emojify } from '../../../util/emoji'; import { BranchConfig } from '../../common'; @@ -10,9 +10,7 @@ export function getPrNotes(config: BranchConfig): string { if (is.nonEmptyArray(upgrade.prBodyNotes)) { for (const note of upgrade.prBodyNotes) { try { - const res = handlebars - .compile(note)(upgrade) - .trim(); + const res = template.compile(note, upgrade).trim(); if (res && res.length) { notes.push(res); } diff --git a/lib/workers/pr/body/updates-table.ts b/lib/workers/pr/body/updates-table.ts index c35dc3e85c..0f109ccc05 100644 --- a/lib/workers/pr/body/updates-table.ts +++ b/lib/workers/pr/body/updates-table.ts @@ -1,4 +1,4 @@ -import handlebars from 'handlebars'; +import * as template from '../../../util/template'; import { logger } from '../../../logger'; import { BranchConfig } from '../../common'; @@ -43,9 +43,7 @@ export function getPrUpdatesTable(config: BranchConfig): string { try { // istanbul ignore else if (value) { - res[header] = handlebars - .compile(value)(upgrade) - .replace(/^``$/, ''); + res[header] = template.compile(value, upgrade).replace(/^``$/, ''); } else { res[header] = ''; } diff --git a/lib/workers/repository/updates/branchify.ts b/lib/workers/repository/updates/branchify.ts index 1e05ab2306..ef6b4cd741 100644 --- a/lib/workers/repository/updates/branchify.ts +++ b/lib/workers/repository/updates/branchify.ts @@ -1,9 +1,8 @@ import slugify from 'slugify'; -import handlebars from 'handlebars'; import { clean as cleanGitRef } from 'clean-git-ref'; import { Merge } from 'type-fest'; import { logger, addMeta, removeMeta } from '../../../logger'; - +import * as template from '../../../util/template'; import { generateBranchConfig } from './generate'; import { flattenUpdates } from './flatten'; import { RenovateConfig, ValidationMessage } from '../../../config'; @@ -51,7 +50,6 @@ export function branchifyUpgrades( // Massage legacy vars just in case update.currentVersion = update.currentValue; update.newVersion = update.newVersion || update.newValue; - // massage for handlebars const upper = (str: string): string => str.charAt(0).toUpperCase() + str.substr(1); if (update.updateType) { @@ -77,16 +75,17 @@ export function branchifyUpgrades( update.groupSlug = `patch-${update.groupSlug}`; } update.branchTopic = update.group.branchTopic || update.branchTopic; - update.branchName = handlebars.compile( - update.group.branchName || update.branchName - )(update); + update.branchName = template.compile( + update.group.branchName || update.branchName, + update + ); } else { - update.branchName = handlebars.compile(update.branchName)(update); + update.branchName = template.compile(update.branchName, update); } - // Compile extra times in case of nested handlebars templates - update.branchName = handlebars.compile(update.branchName)(update); + // Compile extra times in case of nested templates + update.branchName = template.compile(update.branchName, update); update.branchName = cleanBranchName( - handlebars.compile(update.branchName)(update) + template.compile(update.branchName, update) ); branchUpgrades[update.branchName] = branchUpgrades[update.branchName] || []; diff --git a/lib/workers/repository/updates/generate.ts b/lib/workers/repository/updates/generate.ts index d8848f9b09..23808c5a05 100644 --- a/lib/workers/repository/updates/generate.ts +++ b/lib/workers/repository/updates/generate.ts @@ -1,10 +1,10 @@ -import * as handlebars from 'handlebars'; import { DateTime } from 'luxon'; import semver from 'semver'; import mdTable from 'markdown-table'; import { logger } from '../../../logger'; import { mergeChildConfig } from '../../../config'; import { BranchConfig, BranchUpgradeConfig } from '../../common'; +import * as template from '../../../util/template'; function ifTypesGroup( depNames: string[], @@ -81,7 +81,7 @@ export function generateBranchConfig( toVersions.push(upg.toVersion); } if (upg.commitMessageExtra) { - const extra = handlebars.compile(upg.commitMessageExtra)(upg); + const extra = template.compile(upg.commitMessageExtra, upg); if (!newValue.includes(extra)) { newValue.push(extra); } @@ -191,12 +191,13 @@ export function generateBranchConfig( } // Use templates to generate strings logger.trace('Compiling branchName: ' + upgrade.branchName); - upgrade.branchName = handlebars.compile(upgrade.branchName)(upgrade); + upgrade.branchName = template.compile(upgrade.branchName, upgrade); if (upgrade.semanticCommits && !upgrade.commitMessagePrefix) { logger.trace('Upgrade has semantic commits enabled'); let semanticPrefix = upgrade.semanticCommitType; if (upgrade.semanticCommitScope) { - semanticPrefix += `(${handlebars.compile(upgrade.semanticCommitScope)( + semanticPrefix += `(${template.compile( + upgrade.semanticCommitScope, upgrade )})`; } @@ -208,11 +209,12 @@ export function generateBranchConfig( !upgrade.semanticCommitType.startsWith(':'); } // Compile a few times in case there are nested templates - upgrade.commitMessage = handlebars.compile(upgrade.commitMessage || '')( + upgrade.commitMessage = template.compile( + upgrade.commitMessage || '', upgrade ); - upgrade.commitMessage = handlebars.compile(upgrade.commitMessage)(upgrade); - upgrade.commitMessage = handlebars.compile(upgrade.commitMessage)(upgrade); + upgrade.commitMessage = template.compile(upgrade.commitMessage, upgrade); + upgrade.commitMessage = template.compile(upgrade.commitMessage, upgrade); upgrade.commitMessage = upgrade.commitMessage.trim(); // Trim exterior whitespace upgrade.commitMessage = upgrade.commitMessage.replace(/\s+/g, ' '); // Trim extra whitespace inside string upgrade.commitMessage = upgrade.commitMessage.replace( @@ -226,16 +228,17 @@ export function generateBranchConfig( upgrade.commitMessage = splitMessage.join('\n'); } if (upgrade.commitBody) { - upgrade.commitMessage = `${upgrade.commitMessage}\n\n${handlebars.compile( - upgrade.commitBody - )(upgrade)}`; + upgrade.commitMessage = `${upgrade.commitMessage}\n\n${template.compile( + upgrade.commitBody, + upgrade + )}`; } logger.trace(`commitMessage: ` + JSON.stringify(upgrade.commitMessage)); if (upgrade.prTitle) { - upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade); - upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade); - upgrade.prTitle = handlebars - .compile(upgrade.prTitle)(upgrade) + upgrade.prTitle = template.compile(upgrade.prTitle, upgrade); + upgrade.prTitle = template.compile(upgrade.prTitle, upgrade); + upgrade.prTitle = template + .compile(upgrade.prTitle, upgrade) .trim() .replace(/\s+/g, ' '); if (upgrade.toLowerCase) { @@ -256,8 +259,8 @@ export function generateBranchConfig( : ''; upgrade.prTitle += upgrade.updateType === 'patch' ? ' (patch)' : ''; } - // Compile again to allow for nested handlebars templates - upgrade.prTitle = handlebars.compile(upgrade.prTitle)(upgrade); + // Compile again to allow for nested templates + upgrade.prTitle = template.compile(upgrade.prTitle, upgrade); logger.trace(`prTitle: ` + JSON.stringify(upgrade.prTitle)); config.upgrades.push(upgrade); if (upgrade.releaseTimestamp) { -- GitLab