From 9a5e7e9b609b5be35d59459d71bf0e80f8acc684 Mon Sep 17 00:00:00 2001 From: Tobias Ollmann Date: Mon, 18 Mar 2024 13:06:14 +0100 Subject: [PATCH] fix: output multifile if input was multifile --- __tests__/action.test.ts | 53 ++++++++++++++++++++++++++++++++++++++++ src/parser.ts | 32 +++++++++++++++++++++--- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/__tests__/action.test.ts b/__tests__/action.test.ts index b0f8f80..0cb6728 100644 --- a/__tests__/action.test.ts +++ b/__tests__/action.test.ts @@ -203,6 +203,27 @@ test('change in multi file', async () => { console.info(json) }) +test('multiple changes in a multifile', async () => { + process.env['VALUE_FILE'] = 'fixtures/multivalue.yaml' + process.env['CHANGES'] = + '{"[0].backend.version": "v1.1.0", "[1].containers[1].image": "node:alpine"}' + + type Result = { + backend: { version: string } + containers: { name: string; image: string }[] + } + + const [{ json, content }] = await runTest(new EnvOptions()) + + const jsonArray = json as unknown as Result[] + + expect(jsonArray[0].backend.version).toEqual('v1.1.0') + expect(jsonArray[1].backend.version).toEqual('v1.2.0') + expect(jsonArray[0].containers[1].image).toEqual('node:latest') + expect(jsonArray[1].containers[1].image).toEqual('node:alpine') + console.info(content) +}) + test('multiple changes in multiple files', async () => { process.env['CHANGES'] = `{ "fixtures/values.yaml": {"backend.version": "v1.1.0", "containers[1].image": "node:alpine"}, @@ -224,6 +245,38 @@ test('multiple changes in multiple files', async () => { console.info(results[1].content) }) +test('multiple changes in multiple files, including multifiles', async () => { + process.env['CHANGES'] = `{ + "fixtures/values.yaml": {"backend.version": "v1.1.0", "containers[1].image": "node:alpine"}, + "fixtures/multivalue.yaml": {"[0].backend.version": "v1.1.0", "[1].containers[1].image": "node:alpine"}, + "fixtures/values.prod.yaml": {"backend.version": "v1.3.0", "frontend": true} + }` + + type Result = { + backend: { version: string } + fronted: boolean + containers: { name: string; image: string }[] + } + + const results = await runTest(new EnvOptions()) + + expect(results[0].json.backend.version).toEqual('v1.1.0') + expect(results[0].json.containers[1].image).toEqual('node:alpine') + console.info(results[0].content) + + const jsonArray = results[1].json as unknown as Result[] + + expect(jsonArray[0].backend.version).toEqual('v1.1.0') + expect(jsonArray[1].backend.version).toEqual('v1.2.0') + expect(jsonArray[0].containers[1].image).toEqual('node:latest') + expect(jsonArray[1].containers[1].image).toEqual('node:alpine') + console.info(results[1].content) + + expect(results[2].json.backend.version).toEqual('v1.3.0') + expect(results[2].json.frontend).toEqual(true) + console.info(results[2].content) + +}) test('append array node', async () => { process.env['CHANGES'] = `{ "fixtures/values.yaml": { diff --git a/src/parser.ts b/src/parser.ts index f0b387d..cfd4413 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -29,20 +29,44 @@ const validateContent = (content: T | undefined, format: Format): T => { return content } -const YAMLParser = { +class YAMLMultiFileParser { + private isMultifile: boolean = false; + convert(filePath: string): T { const content = YAML.loadAll(readFile(filePath)) as ContentNode[] if (content.length <= 1) { + this.isMultifile = false; return validateContent(content[0] as T, Format.YAML) } + this.isMultifile = true; for (const entry of content) { validateContent(entry, Format.YAML) } return content as unknown as T - }, + } + dump( content: T, - options?: { noCompatMode: boolean; quotingType?: QuotingType } + options?: { + noCompatMode: boolean; quotingType?: QuotingType + } + ): string { + if (this.isMultifile) { + const entries = content as unknown as T[]; + const fileContents = entries.map((v) => + this.internal_dump(v, options) + ); + return fileContents.join('\n\n---\n\n') + } else { + return this.internal_dump(content, options) + } + } + + private internal_dump( + content: T, + options?: { + noCompatMode: boolean; quotingType?: QuotingType + } ): string { return YAML.dump(content, { lineWidth: -1, @@ -72,5 +96,5 @@ export const formatParser: { [key in Exclude]: FormatParser } = { [Format.JSON]: JSONParser, - [Format.YAML]: YAMLParser + [Format.YAML]: new YAMLMultiFileParser(), }