From e64c8a6fd7cb8f40b6487fc0acd0a357cc1eaffd Mon Sep 17 00:00:00 2001 From: Clare Liguori Date: Thu, 2 Apr 2020 09:12:09 -0700 Subject: [PATCH] feat: clean empty arrays and objects from the task def file (#52) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- index.js | 33 ++++++++++++++++++++++++++++++--- index.test.js | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index eecf6d853..cf9800d05 100644 --- a/index.js +++ b/index.js @@ -64,8 +64,35 @@ function findAppSpecKey(obj, keyName) { throw new Error(`AppSpec file must include property '${keyName}'`); } -function undefinedOrNullReplacer(_, value) { - if (value === null || value === undefined) { +function isEmptyValue(value) { + if (value === null || value === undefined || value === '') { + return true; + } + + if (Array.isArray(value) && value.length === 0) { + return true; + } + + if (typeof value === 'object' && Object.values(value).length === 0) { + return true; + } + + return false; +} + +function emptyValueReplacer(_, value) { + if (isEmptyValue(value)) { + return undefined; + } + + if (typeof value === 'object') { + for (var childValue of Object.values(value)) { + if (!isEmptyValue(childValue)) { + // the object has at least one non-empty property + return value; + } + } + // the object has no non-empty property return undefined; } @@ -73,7 +100,7 @@ function undefinedOrNullReplacer(_, value) { } function cleanNullKeys(obj) { - return JSON.parse(JSON.stringify(obj, undefinedOrNullReplacer)); + return JSON.parse(JSON.stringify(obj, emptyValueReplacer)); } function removeIgnoredAttributes(taskDef) { diff --git a/index.test.js b/index.test.js index 5fcbc2906..f5e8893dd 100644 --- a/index.test.js +++ b/index.test.js @@ -174,6 +174,44 @@ describe('Deploy to ECS', () => { expect(mockEcsRegisterTaskDef).toHaveBeenNthCalledWith(1, { family: 'task-def-family'}); }); + test('cleans empty arrays out of the task definition contents', async () => { + fs.readFileSync.mockImplementation((pathInput, encoding) => { + if (encoding != 'utf8') { + throw new Error(`Wrong encoding ${encoding}`); + } + + return '{ "tags": [], "family": "task-def-family" }'; + }); + + await run(); + expect(core.setFailed).toHaveBeenCalledTimes(0); + expect(mockEcsRegisterTaskDef).toHaveBeenNthCalledWith(1, { family: 'task-def-family'}); + }); + + test('cleans empty strings and objects out of the task definition contents', async () => { + fs.readFileSync.mockImplementation((pathInput, encoding) => { + if (encoding != 'utf8') { + throw new Error(`Wrong encoding ${encoding}`); + } + + return '{ "memory": "", "containerDefinitions": [ { "name": "sample-container", "logConfiguration": {}, "repositoryCredentials": { "credentialsParameter": "" }, "cpu": 0, "essential": false } ], "requiresCompatibilities": [ "EC2" ], "family": "task-def-family" }'; + }); + + await run(); + expect(core.setFailed).toHaveBeenCalledTimes(0); + expect(mockEcsRegisterTaskDef).toHaveBeenNthCalledWith(1, { + family: 'task-def-family', + containerDefinitions: [ + { + name: 'sample-container', + cpu: 0, + essential: false + } + ], + requiresCompatibilities: [ 'EC2' ] + }); + }); + test('cleans invalid keys out of the task definition contents', async () => { fs.readFileSync.mockImplementation((pathInput, encoding) => { if (encoding != 'utf8') {