From d425754cc177e736c6c3e7c92187dbbe43a1a0b2 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 28 Mar 2023 13:19:15 +0200 Subject: [PATCH] chore: simplifying the code a bit by just using lodash under the hood for the pick method Signed-off-by: blam --- .changeset/tough-cameras-beam.md | 2 +- .../src/lib/templating/filters.ts | 15 ++-------- .../actions/builtin/fetch/template.ts | 10 +++---- .../tasks/NunjucksWorkflowRunner.test.ts | 30 +++++++++++++++++++ 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/.changeset/tough-cameras-beam.md b/.changeset/tough-cameras-beam.md index c599f168b0..e1bcc87dc4 100644 --- a/.changeset/tough-cameras-beam.md +++ b/.changeset/tough-cameras-beam.md @@ -7,4 +7,4 @@ Provide some more default filters out of the box and refactoring how the filters - `parseEntityRef` will take an string entity triplet and return a parsed object. - `pick` will allow you to reference a specific property in the piped object. -So you can now combine things like this: `${{ parameters.entity | parseEntityRef | pick('name') }}` to get the name of a specific entity, or `${{ parameters.repoUrl | parseRepoUrl | pick('owner) }}` to get the owner of a repo. +So you can now combine things like this: `${{ parameters.entity | parseEntityRef | pick('name') }}` to get the name of a specific entity, or `${{ parameters.repoUrl | parseRepoUrl | pick('owner') }}` to get the owner of a repo. diff --git a/plugins/scaffolder-backend/src/lib/templating/filters.ts b/plugins/scaffolder-backend/src/lib/templating/filters.ts index a8d7956c3c..204d0015d8 100644 --- a/plugins/scaffolder-backend/src/lib/templating/filters.ts +++ b/plugins/scaffolder-backend/src/lib/templating/filters.ts @@ -18,6 +18,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { JsonValue } from '@backstage/types'; import { TemplateFilter } from '..'; import { parseRepoUrl } from '../../scaffolder/actions/builtin/publish/util'; +import get from 'lodash/get'; export const createDefaultFilters = ({ integrations, @@ -27,19 +28,7 @@ export const createDefaultFilters = ({ return { parseRepoUrl: url => parseRepoUrl(url as string, integrations), parseEntityRef: ref => parseEntityRef(ref as string), - pick: (obj: JsonValue, key: JsonValue) => { - if ( - typeof obj === 'object' && - !Array.isArray(obj) && - typeof key === 'string' - ) { - return obj?.[key]; - } - - throw new Error( - `Invalid arguments to pick filter, expected object and string, got ${typeof obj} and ${typeof key}`, - ); - }, + pick: (obj: JsonValue, key: JsonValue) => get(obj, key as string), projectSlug: repoUrl => { const { owner, repo } = parseRepoUrl(repoUrl as string, integrations); return `${owner}/${repo}`; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts index 5e1e77e0e2..7659cff240 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts @@ -50,10 +50,7 @@ export function createFetchTemplateAction(options: { additionalTemplateGlobals, } = options; - const templateFilters = { - ...createDefaultFilters({ integrations }), - ...additionalTemplateFilters, - }; + const defaultTemplateFilters = createDefaultFilters({ integrations }); return createTemplateAction<{ url: string; @@ -237,7 +234,10 @@ export function createFetchTemplateAction(options: { const renderTemplate = await SecureTemplater.loadRenderer({ cookiecutterCompat: ctx.input.cookiecutterCompat, - templateFilters, + templateFilters: { + ...defaultTemplateFilters, + ...additionalTemplateFilters, + }, templateGlobals: additionalTemplateGlobals, }); diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts index fa012ea04f..e8698b62f5 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts @@ -750,6 +750,36 @@ describe('DefaultWorkflowRunner', () => { expect(output.foo).toEqual('component'); }); + + it('should allow deep nesting of picked objects', async () => { + const task = createMockTaskWithSpec({ + apiVersion: 'scaffolder.backstage.io/v1beta3', + steps: [ + { + id: 'test', + name: 'name', + action: 'output-action', + input: {}, + }, + ], + output: { + foo: '${{ parameters.entity | pick("something.deeply.nested") }}', + }, + parameters: { + entity: { + something: { + deeply: { + nested: 'component', + }, + }, + }, + }, + }); + + const { output } = await runner.execute(task); + + expect(output.foo).toEqual('component'); + }); }); describe('dry run', () => {