diff --git a/packages/compose-as-code/src/compiler/__test__/compostionCompiler.test.ts b/packages/compose-as-code/src/compiler/__test__/compostionCompiler.test.ts index 0423de7..e75a9b1 100644 --- a/packages/compose-as-code/src/compiler/__test__/compostionCompiler.test.ts +++ b/packages/compose-as-code/src/compiler/__test__/compostionCompiler.test.ts @@ -217,6 +217,36 @@ describe('all', () => { await snapshot(app, __dirname, 'service_command_unescaped_string'); }); + it('should compile service.environment on multiple lines without breaking it', async () => { + const app = new App('Service.Command'); + + class TestComposition extends Composition { + constructor(id: string, props: CompositionProps) { + super(app, id, props); + new Service(this, 'Service', { + image: 'redis', + environment: { + CONFIG_FILEPATH: "/tmp/config.yml", + CONSOLE_CONFIG_FILE: `| +kafka: + brokers: ["redpanda-0:9092"] +redpanda: + adminApi: + enabled: true +urls: ["http://redpanda-0:9644"]` + }, + }); + } + } + + new TestComposition('Composition', { + version: '3.8', + name: 'composition', + }); + + await snapshot(app, __dirname, 'service_environment_multi_line'); + }); + it('should compile service.healthcheck properly', async () => { const app = new App('Service.Healthcheck'); diff --git a/packages/compose-as-code/src/compiler/__test__/service_environment_multi_line_snapshot/Service.CommandComposition.yaml b/packages/compose-as-code/src/compiler/__test__/service_environment_multi_line_snapshot/Service.CommandComposition.yaml new file mode 100644 index 0000000..f0a5f81 --- /dev/null +++ b/packages/compose-as-code/src/compiler/__test__/service_environment_multi_line_snapshot/Service.CommandComposition.yaml @@ -0,0 +1,13 @@ +name: "composition" +services: + Service.CommandCompositionService: + image: "redis" + environment: + CONFIG_FILEPATH: /tmp/config.yml + CONSOLE_CONFIG_FILE: | + kafka: + brokers: ["redpanda-0:9092"] + redpanda: + adminApi: + enabled: true + urls: ["http://redpanda-0:9644"] diff --git a/packages/compose-as-code/src/compiler/compilerUtils.ts b/packages/compose-as-code/src/compiler/compilerUtils.ts index b7219d9..95953fc 100644 --- a/packages/compose-as-code/src/compiler/compilerUtils.ts +++ b/packages/compose-as-code/src/compiler/compilerUtils.ts @@ -3,96 +3,109 @@ import fs from 'fs'; const INDENTATION_CHARACTER = ' '; export interface OutputFile { - fileName: string; - outputDir: string; - content: string; + fileName: string; + outputDir: string; + content: string; } export const createDirIfNotExisting = (dirname: string) => { - if (!fs.existsSync(dirname)) { - fs.mkdirSync(dirname); - } + if (!fs.existsSync(dirname)) { + fs.mkdirSync(dirname); + } }; export const compileKeyValuePair = ( - key: string, - value: string | number, - indentationDepth: number, - options?: { noQuotes?: boolean } + key: string, + value: string | number, + indentationDepth: number, + options?: { noQuotes?: boolean } ) => { - let result = ''; - const quote = options?.noQuotes ? '' : '"'; - result += indent(indentationDepth); - result += `${key}: ${value ? `${quote}${value}${quote}` : ''}\n`; - return result; + let result = ''; + const quote = options?.noQuotes ? '' : '"'; + result += indent(indentationDepth); + result += `${key}: ${value ? `${quote}${value}${quote}` : ''}\n`; + return result; }; export const indent = (indentationDepth: number) => { - let indentationResult = ''; - for (let i = 0; i < indentationDepth; i++) { - indentationResult += INDENTATION_CHARACTER; - } - return indentationResult; + let indentationResult = ''; + for (let i = 0; i < indentationDepth; i++) { + indentationResult += INDENTATION_CHARACTER; + } + return indentationResult; }; export const compileObject = (obj: object, baseIndentationDepth: number) => { - let result = ''; - Object.keys(obj).forEach(key => { - const value = obj[key]; - if (typeof value === 'number') { - result += `${indent(baseIndentationDepth)}${key}: ${value}\n`; - } else if (Array.isArray(value)) { - result += `${indent(baseIndentationDepth)}${key}: ${compileList( - value, - baseIndentationDepth + 1, - { asSingleLineList: true } - )}\n`; - } else { - result += `${indent(baseIndentationDepth)}${key}: ${value}\n`; - } - }); - return result; + let result = ''; + Object.keys(obj).forEach(key => { + const value = obj[key]; + if (typeof value === 'number') { + result += `${indent(baseIndentationDepth)}${key}: ${value}\n`; + } else if (Array.isArray(value)) { + result += `${indent(baseIndentationDepth)}${key}: ${compileList( + value, + baseIndentationDepth + 1, + {asSingleLineList: true} + )}\n`; + } else if (typeof value === 'string') { + if (value.includes("\n")) { + const lines = value.split("\n") + lines.forEach((line, index) => { + if(index === 0) { + result += `${indent(baseIndentationDepth)}${key}: ${line}\n`; + } else { + result += ` ${indent(baseIndentationDepth)}${line}\n`; + } + }) + } else { + result += `${indent(baseIndentationDepth)}${key}: ${value}\n`; + } + } else { + result += `${indent(baseIndentationDepth)}${key}: ${value}\n`; + } + }); + return result; }; export const compileObjectListWithId = ( - list: { id: string }[], - baseIndentationDepth: number + list: { id: string }[], + baseIndentationDepth: number ) => { - let result = ''; - list.forEach(entry => { - result += indent(baseIndentationDepth); - result += `- ${entry.id}\n`; - }); - return result; + let result = ''; + list.forEach(entry => { + result += indent(baseIndentationDepth); + result += `- ${entry.id}\n`; + }); + return result; }; export const compileList = ( - list: string[], - baseIndentationDepth: number, - options?: { asSingleLineList?: boolean } + list: string[], + baseIndentationDepth: number, + options?: { asSingleLineList?: boolean } ) => { - let result = ''; + let result = ''; - if (options?.asSingleLineList) { - result += '['; - list.forEach((entry, index) => { - result += `"${entry}"`; - if (index < list.length - 1) { - result += ', '; - } - }); - result += ']'; - } else { - list.forEach(entry => { - result += indent(baseIndentationDepth); - result += `- ${entry}\n`; - }); - } - return result; + if (options?.asSingleLineList) { + result += '['; + list.forEach((entry, index) => { + result += `"${entry}"`; + if (index < list.length - 1) { + result += ', '; + } + }); + result += ']'; + } else { + list.forEach(entry => { + result += indent(baseIndentationDepth); + result += `- ${entry}\n`; + }); + } + return result; }; export const writeFile = (config: OutputFile) => { - createDirIfNotExisting(config.outputDir); - const resultFileName = `${config.outputDir}/${config.fileName}.yaml`; - fs.writeFileSync(resultFileName, config.content); + createDirIfNotExisting(config.outputDir); + const resultFileName = `${config.outputDir}/${config.fileName}.yaml`; + fs.writeFileSync(resultFileName, config.content); };