Skip to content

Commit

Permalink
Merge branch 'main' into bugfix/history-inefficient
Browse files Browse the repository at this point in the history
  • Loading branch information
Xantier authored Dec 7, 2023
2 parents a527f60 + ff63486 commit f3c5a89
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/tall-ducks-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@roadiehq/scaffolder-backend-module-utils': minor
---

Add merge array value option
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ describe('roadiehq:utils:json:merge', () => {
it('should append the content to the file if it already exists', async () => {
mock({
'fake-tmp-dir': {
'fake-file.json': '{ "scripts": { "lsltr": "ls -ltr" } }',
'fake-file.json':
'{ "scripts": { "lsltr": "ls -ltr" }, "array": ["first item"] }',
},
});

Expand All @@ -101,6 +102,7 @@ describe('roadiehq:utils:json:merge', () => {
scripts: {
lsltrh: 'ls -ltrh',
},
array: ['second item'],
},
},
});
Expand All @@ -109,6 +111,41 @@ describe('roadiehq:utils:json:merge', () => {
const file = fs.readFileSync('fake-tmp-dir/fake-file.json', 'utf-8');
expect(JSON.parse(file)).toEqual({
scripts: { lsltr: 'ls -ltr', lsltrh: 'ls -ltrh' },
array: ['second item'],
});
});

it('should merge arrays if configured', async () => {
mock({
'fake-tmp-dir': {
'fake-file.json':
'{ "scripts": { "lsltr": "ls -ltr" }, "array": ["first item"] }',
},
});

await action.handler({
...mockContext,
workspacePath: 'fake-tmp-dir',
input: {
path: 'fake-file.json',
mergeArrays: true,
content: {
scripts: {
lsltrh: 'ls -ltrh',
},
array: ['second item'],
},
},
});

expect(fs.existsSync('fake-tmp-dir/fake-file.json')).toBe(true);
const file = fs.readFileSync('fake-tmp-dir/fake-file.json', 'utf-8');
expect(JSON.parse(file)).toEqual({
scripts: {
lsltr: 'ls -ltr',
lsltrh: 'ls -ltrh',
},
array: ['first item', 'second item'],
});
});

Expand Down Expand Up @@ -277,7 +314,7 @@ scripts:
it('can merge content into a yaml file', async () => {
mock({
'fake-tmp-dir': {
'fake-file.yaml': 'scripts:\n lsltr: ls -ltr\n',
'fake-file.yaml': 'array: ["first item"]\nscripts:\n lsltr: ls -ltr\n',
},
});

Expand All @@ -290,6 +327,7 @@ scripts:
scripts: {
lsltrh: 'ls -ltrh',
},
array: ['second item'],
},
},
});
Expand All @@ -298,6 +336,33 @@ scripts:
const file = fs.readFileSync('fake-tmp-dir/fake-file.yaml', 'utf-8');
expect(yaml.load(file)).toEqual({
scripts: { lsltr: 'ls -ltr', lsltrh: 'ls -ltrh' },
array: ['second item'],
});
});

it('can merge arrays if configured', async () => {
mock({
'fake-tmp-dir': {
'fake-file.yaml': "array: ['first item']",
},
});

await action.handler({
...mockContext,
workspacePath: 'fake-tmp-dir',
input: {
path: 'fake-file.yaml',
mergeArrays: true,
content: {
array: ['second item'],
},
},
});

expect(fs.existsSync('fake-tmp-dir/fake-file.yaml')).toBe(true);
const file = fs.readFileSync('fake-tmp-dir/fake-file.yaml', 'utf-8');
expect(yaml.load(file)).toEqual({
array: ['first item', 'second item'],
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,23 @@ import { createTemplateAction } from '@backstage/plugin-scaffolder-node';
import { resolveSafeChildPath } from '@backstage/backend-common';
import fs from 'fs-extra';
import { extname } from 'path';
import { merge } from 'lodash';
import { isArray, isNull, mergeWith } from 'lodash';
import yaml from 'js-yaml';
import { supportedDumpOptions, yamlOptionsSchema } from '../../types';

function mergeArrayCustomiser(objValue: string | any[], srcValue: any) {
if (isArray(objValue) && !isNull(objValue)) {
return Array.from(new Set(objValue.concat(srcValue)));
}
return undefined;
}

export function createMergeJSONAction({ actionId }: { actionId?: string }) {
return createTemplateAction<{ path: string; content: any }>({
return createTemplateAction<{
path: string;
content: any;
mergeArrays?: boolean;
}>({
id: actionId || 'roadiehq:utils:json:merge',
description: 'Merge new data into an existing JSON file.',
supportsDryRun: true,
Expand All @@ -43,6 +54,13 @@ export function createMergeJSONAction({ actionId }: { actionId?: string }) {
title: 'Content',
type: ['string', 'object'],
},
mergeArrays: {
type: 'boolean',
default: false,
title: 'Merge Arrays?',
description:
'Where a value is an array the merge function should concatenate the provided array value with the target array',
},
},
},
output: {
Expand Down Expand Up @@ -80,7 +98,15 @@ export function createMergeJSONAction({ actionId }: { actionId?: string }) {

fs.writeFileSync(
sourceFilepath,
JSON.stringify(merge(existingContent, content), null, 2),
JSON.stringify(
mergeWith(
existingContent,
content,
ctx.input.mergeArrays ? mergeArrayCustomiser : undefined,
),
null,
2,
),
);
ctx.output('path', sourceFilepath);
},
Expand All @@ -91,6 +117,7 @@ export function createMergeAction() {
return createTemplateAction<{
path: string;
content: any;
mergeArrays?: boolean;
options?: supportedDumpOptions;
}>({
id: 'roadiehq:utils:merge',
Expand All @@ -112,6 +139,13 @@ export function createMergeAction() {
title: 'Content',
type: ['string', 'object'],
},
mergeArrays: {
type: 'boolean',
default: false,
title: 'Merge Arrays?',
description:
'Where a value is an array the merge function should concatenate the provided array value with the target array',
},
options: {
...yamlOptionsSchema,
description: `${yamlOptionsSchema.description} (for YAML output only)`,
Expand Down Expand Up @@ -148,7 +182,11 @@ export function createMergeAction() {
? JSON.parse(ctx.input.content)
: ctx.input.content; // This supports the case where dynamic keys are required
mergedContent = JSON.stringify(
merge(JSON.parse(originalContent), newContent),
mergeWith(
yaml.load(originalContent),
newContent,
ctx.input.mergeArrays ? mergeArrayCustomiser : undefined,
),
null,
2,
);
Expand All @@ -161,7 +199,11 @@ export function createMergeAction() {
? yaml.load(ctx.input.content)
: ctx.input.content; // This supports the case where dynamic keys are required
mergedContent = yaml.dump(
merge(yaml.load(originalContent), newContent),
mergeWith(
yaml.load(originalContent),
newContent,
ctx.input.mergeArrays ? mergeArrayCustomiser : undefined,
),
ctx.input.options,
);
break;
Expand Down

0 comments on commit f3c5a89

Please sign in to comment.