From 7fdd1f2affe7ec47e6892a9949bba458667a5b1f Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Fri, 27 Dec 2024 16:23:09 -0800 Subject: [PATCH 1/4] chore(deps): upgrade dependencies (#268) Upgrades project dependencies. See details in [workflow run]. [Workflow Run]: https://github.com/cdklabs/cdk-assets/actions/runs/12522087440 ------ *Automatically created by projen via the "upgrade-main" workflow* Signed-off-by: github-actions Co-authored-by: github-actions --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1f7f113..9ebbcba 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ }, "dependencies": { "@aws-cdk/cloud-assembly-schema": "^38.0.1", - "@aws-cdk/cx-api": "^2.173.3", + "@aws-cdk/cx-api": "^2.173.4", "@aws-sdk/client-ecr": "^3.719.0", "@aws-sdk/client-s3": "^3.717.0", "@aws-sdk/client-secrets-manager": "^3.716.0", diff --git a/yarn.lock b/yarn.lock index f2b8d45..ef422b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,10 +18,10 @@ jsonschema "^1.4.1" semver "^7.6.3" -"@aws-cdk/cx-api@^2.173.3": - version "2.173.3" - resolved "https://registry.yarnpkg.com/@aws-cdk/cx-api/-/cx-api-2.173.3.tgz#e83f1d03067a5cc3ebd2b4b897149fdd555c80ff" - integrity sha512-S5VP3EHVNW9GRySnJ136AOsuWyO1CHarQZVYY0bK4W26rjMukgDlrx0rOXPS98JrRYEt5U3QV2eNpksWFNwnEw== +"@aws-cdk/cx-api@^2.173.4": + version "2.173.4" + resolved "https://registry.yarnpkg.com/@aws-cdk/cx-api/-/cx-api-2.173.4.tgz#6e417a3c8d80cef67ed57b3228a63614f525e4a8" + integrity sha512-TKiqmgKcr/LbM2T8Usp6/zlsygfK5eaZLzoraQwzL7uVAELNMZVGNrFSeJx6EXRf2Ab55WdK94x08g3eW0gyBg== dependencies: semver "^7.6.3" From 01a5255c1be45258d42186166dc8a86487cdf56b Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Sat, 28 Dec 2024 16:26:07 -0800 Subject: [PATCH 2/4] chore(deps): upgrade dependencies (#269) Upgrades project dependencies. See details in [workflow run]. [Workflow Run]: https://github.com/cdklabs/cdk-assets/actions/runs/12530897897 ------ *Automatically created by projen via the "upgrade-main" workflow* Signed-off-by: github-actions Co-authored-by: github-actions --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 9ebbcba..77f5ab5 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "dependencies": { "@aws-cdk/cloud-assembly-schema": "^38.0.1", "@aws-cdk/cx-api": "^2.173.4", - "@aws-sdk/client-ecr": "^3.719.0", + "@aws-sdk/client-ecr": "^3.720.0", "@aws-sdk/client-s3": "^3.717.0", "@aws-sdk/client-secrets-manager": "^3.716.0", "@aws-sdk/client-sts": "^3.716.0", diff --git a/yarn.lock b/yarn.lock index ef422b8..69a43f9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -140,10 +140,10 @@ "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/client-ecr@^3.719.0": - version "3.719.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-ecr/-/client-ecr-3.719.0.tgz#f672536cc499808bb6233668901a14cc757edf16" - integrity sha512-aEo9ZO2DxeHuA/TTwgKSF6r6F9aZMwPmwFHXHjLSyCMplKFWlltXO5+uJdQSHWRDCN0EQjpnpxC5suwpPLK2LQ== +"@aws-sdk/client-ecr@^3.720.0": + version "3.720.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-ecr/-/client-ecr-3.720.0.tgz#45f79b4502b8fdb100549068ec5b02ac45497393" + integrity sha512-8/b92aUQsWpqMdd/V/YLjq0oRcPakB27x5U42NzOUtJ3RYJHhylIG81YbAU3ANwcPNytjPjnYDcPG7mMQBASFw== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" From 72f6307b7fa4adac2adcc4e7c0c76763ab1dd425 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Sun, 29 Dec 2024 16:24:37 -0800 Subject: [PATCH 3/4] chore(deps): upgrade dependencies (#271) Upgrades project dependencies. See details in [workflow run]. [Workflow Run]: https://github.com/cdklabs/cdk-assets/actions/runs/12539912803 ------ *Automatically created by projen via the "upgrade-main" workflow* Signed-off-by: github-actions Co-authored-by: github-actions --- yarn.lock | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 69a43f9..a35e03c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3712,9 +3712,9 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.23.2, es-abstract@^1.23.5, es-abstract@^1.23.6: - version "1.23.7" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.7.tgz#36e3da46fdb0d2ae3b9df4235e3a3167c1605b36" - integrity sha512-OygGC8kIcDhXX+6yAZRGLqwi2CmEXCbLQixeGUgYeR+Qwlppqmo7DIDr8XibtEBZp+fJcoYpoatp5qwLMEdcqQ== + version "1.23.8" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.8.tgz#99754723118355d82fcef9ce4c90ccbcd5d2a285" + integrity sha512-lfab8IzDn6EpI1ibZakcgS6WsfEBiB+43cuJo+wgylx1xKXf+Sp+YR3vFuQwC/u3sxYwV8Cxe3B0DpVUu/WiJQ== dependencies: array-buffer-byte-length "^1.0.2" arraybuffer.prototype.slice "^1.0.4" @@ -3751,8 +3751,10 @@ es-abstract@^1.23.2, es-abstract@^1.23.5, es-abstract@^1.23.6: object-inspect "^1.13.3" object-keys "^1.1.1" object.assign "^4.1.7" + own-keys "^1.0.0" regexp.prototype.flags "^1.5.3" safe-array-concat "^1.1.3" + safe-push-apply "^1.0.0" safe-regex-test "^1.1.0" string.prototype.trim "^1.2.10" string.prototype.trimend "^1.0.9" @@ -6000,6 +6002,15 @@ ora@^5.4.1: strip-ansi "^6.0.0" wcwidth "^1.0.1" +own-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/own-keys/-/own-keys-1.0.1.tgz#e4006910a2bf913585289676eebd6f390cf51358" + integrity sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg== + dependencies: + get-intrinsic "^1.2.6" + object-keys "^1.1.1" + safe-push-apply "^1.0.0" + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -6549,6 +6560,14 @@ safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-push-apply@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz#01850e981c1602d398c85081f360e4e6d03d27f5" + integrity sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA== + dependencies: + es-errors "^1.3.0" + isarray "^2.0.5" + safe-regex-test@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" From b3c1e4f50e4ac494c4d678c9cf3578d3ce77a23d Mon Sep 17 00:00:00 2001 From: Hogan Bobertz Date: Mon, 30 Dec 2024 10:55:04 -0500 Subject: [PATCH 4/4] chore: add some additional shell logging (#272) Adding some additional tests, so I can verify #221 isn't causing any breaking changes These are LLM generated btw --------- Signed-off-by: github-actions Co-authored-by: github-actions --- test/mock-child_process.ts | 4 + test/shell-logging.test.ts | 150 +++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 test/shell-logging.test.ts diff --git a/test/mock-child_process.ts b/test/mock-child_process.ts index 4588650..c0efc6f 100644 --- a/test/mock-child_process.ts +++ b/test/mock-child_process.ts @@ -10,6 +10,7 @@ export interface Invocation { cwd?: string; exitCode?: number; stdout?: string; + stderr?: string; /** * Only match a prefix of the command (don't care about the details of the arguments) @@ -48,6 +49,9 @@ export function mockSpawn(...invocations: Invocation[]): () => void { if (invocation.stdout) { mockEmit(child.stdout, 'data', Buffer.from(invocation.stdout)); } + if (invocation.stderr) { + mockEmit(child.stderr, 'data', Buffer.from(invocation.stderr)); + } mockEmit(child, 'close', invocation.exitCode ?? 0); return child; diff --git a/test/shell-logging.test.ts b/test/shell-logging.test.ts new file mode 100644 index 0000000..8d41734 --- /dev/null +++ b/test/shell-logging.test.ts @@ -0,0 +1,150 @@ +import { mockSpawn } from './mock-child_process'; +import mockfs from './mock-fs'; +import { setLogThreshold } from '../bin/logging'; +import { shell } from '../lib/private/shell'; +jest.mock('child_process'); + +describe('logging', () => { + let consoleSpy: jest.SpyInstance; + + beforeEach(() => { + consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); + mockfs({ + '/path/package.json': JSON.stringify({ version: '1.2.3' }), + }); + }); + + afterEach(() => { + consoleSpy.mockRestore(); + mockfs.restore(); + }); + + test('docker stdout is captured during builds', async () => { + // GIVEN + setLogThreshold('verbose'); + const processOut = new Array(); + const mockStdout = jest.spyOn(process.stdout, 'write').mockImplementation((chunk) => { + processOut.push(Buffer.isBuffer(chunk) ? chunk.toString() : (chunk as string)); + return true; + }); + + const expectAllSpawns = mockSpawn({ + commandLine: ['docker', 'build', '.'], + stdout: 'Step 1/3 : FROM node:14\nStep 2/3 : WORKDIR /app\nStep 3/3 : COPY . .', + }); + + // WHEN + await shell(['docker', 'build', '.']); + + // THEN + expectAllSpawns(); + await new Promise((resolve) => setImmediate(resolve)); + + const hasDockerOutput = processOut.some( + (chunk) => + chunk.includes('Step 1/3') && chunk.includes('Step 2/3') && chunk.includes('Step 3/3') + ); + + expect(hasDockerOutput).toBe(true); + mockStdout.mockRestore(); + }); + + test('stderr is captured and written to process.stderr', async () => { + // GIVEN + const processErr = new Array(); + const mockStderr = jest.spyOn(process.stderr, 'write').mockImplementation((chunk) => { + processErr.push(Buffer.isBuffer(chunk) ? chunk.toString() : (chunk as string)); + return true; + }); + + const expectAllSpawns = mockSpawn({ + commandLine: ['docker', 'build', '.'], + stderr: 'Warning: Something went wrong', + }); + + // WHEN + await shell(['docker', 'build', '.']); + + // THEN + expectAllSpawns(); + await new Promise((resolve) => setImmediate(resolve)); + + expect(processErr.some((chunk) => chunk.includes('Warning: Something went wrong'))).toBe(true); + mockStderr.mockRestore(); + }); + + test('quiet mode suppresses stdout and stderr', async () => { + // GIVEN + const processOut = new Array(); + const processErr = new Array(); + + const mockStdout = jest.spyOn(process.stdout, 'write').mockImplementation((chunk) => { + processOut.push(Buffer.isBuffer(chunk) ? chunk.toString() : (chunk as string)); + return true; + }); + + const mockStderr = jest.spyOn(process.stderr, 'write').mockImplementation((chunk) => { + processErr.push(Buffer.isBuffer(chunk) ? chunk.toString() : (chunk as string)); + return true; + }); + + const expectAllSpawns = mockSpawn({ + commandLine: ['docker', 'build', '.'], + stdout: 'Normal output', + stderr: 'Warning output', + }); + + // WHEN + await shell(['docker', 'build', '.'], { quiet: true }); + + // THEN + expectAllSpawns(); + await new Promise((resolve) => setImmediate(resolve)); + + expect(processOut.length).toBe(0); + expect(processErr.length).toBe(0); + + mockStdout.mockRestore(); + mockStderr.mockRestore(); + }); + + test('handles input option correctly', async () => { + // GIVEN + const expectedInput = 'some input'; + const processOut = new Array(); + + const mockStdout = jest.spyOn(process.stdout, 'write').mockImplementation((chunk) => { + processOut.push(Buffer.isBuffer(chunk) ? chunk.toString() : (chunk as string)); + return true; + }); + + const expectAllSpawns = mockSpawn({ + commandLine: ['cat'], + stdout: expectedInput, // Echo back the input + }); + + // WHEN + await shell(['cat'], { input: expectedInput }); + + // THEN + expectAllSpawns(); + await new Promise((resolve) => setImmediate(resolve)); + + expect(processOut.some((chunk) => chunk.includes(expectedInput))).toBe(true); + mockStdout.mockRestore(); + }); + + test('throws error on non-zero exit code', async () => { + // GIVEN + const expectAllSpawns = mockSpawn({ + commandLine: ['docker', 'build', '.'], + exitCode: 1, + stderr: 'Command failed', + }); + + // WHEN/THEN + await expect(shell(['docker', 'build', '.'])).rejects.toThrow('Command failed'); + + expectAllSpawns(); + }); +});