From b1bfb09614f58fbb2b2842bf63c098d7f7dff132 Mon Sep 17 00:00:00 2001 From: iliapolo Date: Tue, 8 Apr 2025 10:50:50 +0300 Subject: [PATCH 1/3] mid work --- .../@aws-cdk-testing/cli-integ/lib/process.ts | 6 ++-- .../@aws-cdk-testing/cli-integ/lib/shell.ts | 30 +++++++++++++------ .../cdk-import-interactive.integtest.ts | 10 +++++-- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/lib/process.ts b/packages/@aws-cdk-testing/cli-integ/lib/process.ts index 6dbdeab..d862d7c 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/process.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/process.ts @@ -90,9 +90,9 @@ class PtyProcess implements IProcess { this.process.onData((e) => callback(Buffer.from(e))); } - public onStderr(callback: (chunk: Buffer) => void): void { - // in a pty all streams are the same - return this.onStdout(callback); + public onStderr(_callback: (chunk: Buffer) => void): void { + // https://github.com/microsoft/node-pty/issues/71 + throw new Error('Cannot to register callback for stderr. A tty does not have separate output and error channels'); } public onExit(callback: (exitCode: number) => void): void { diff --git a/packages/@aws-cdk-testing/cli-integ/lib/shell.ts b/packages/@aws-cdk-testing/cli-integ/lib/shell.ts index 5897fe5..ccd3e2d 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/shell.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/shell.ts @@ -60,12 +60,15 @@ export async function shell(command: string[], options: ShellOptions = {}): Prom if (interaction) { if (interaction.prompt.test(lastLine.get())) { + + // shift before writing to ensure the same interaction is not reused + remainingInteractions.shift(); + // subprocess expects a user input now. // we have to write the input AFTER the child has started // reading, so we do this with a small delay. setTimeout(() => { child.writeStdin(interaction.input + (interaction.end ?? os.EOL)); - remainingInteractions.shift(); }, 500); } @@ -73,14 +76,23 @@ export async function shell(command: string[], options: ShellOptions = {}): Prom }); - child.onStderr(chunk => { - if (show === 'always') { - writeToOutputs(chunk.toString('utf-8')); - } - if (options.captureStderr ?? true) { - stderr.push(chunk); - } - }); + if (tty && options.captureStderr === false) { + // in a tty stderr goes to the same fd as stdout + throw new Error(`Cannot disable 'captureStderr' in tty`); + } + + if (!tty) { + // in a tty stderr goes to the same fd as stdout, so onStdout + // is sufficient. + child.onStderr(chunk => { + if (show === 'always') { + writeToOutputs(chunk.toString('utf-8')); + } + if (options.captureStderr ?? true) { + stderr.push(chunk); + } + }); + } child.onError(reject); diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cdk-import-interactive.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cdk-import-interactive.integtest.ts index 6533c9c..499bba5 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cdk-import-interactive.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cdk-import-interactive.integtest.ts @@ -27,14 +27,18 @@ integTest('cdk import prompts the user for sns topic arns', withDefaultFixture(a await fixture.cdk(['import', fullStackName], { interact: [ { - prompt: /\(empty to skip\)/, + prompt: /Topic1.*\(empty to skip\):/, input: topic1Arn, }, { - prompt: /\(empty to skip\)/, + prompt: /Topic2.*\(empty to skip\):/, input: topic2Arn, } - ] + ], + modEnv: { + // disable coloring because it messes up prompt matching. + FORCE_COLOR: '0' + } }); // assert the stack now has the two topics From 4d6d2810e0deb66eead9eb9104dc7eb1a77002ba Mon Sep 17 00:00:00 2001 From: iliapolo Date: Tue, 8 Apr 2025 12:07:53 +0300 Subject: [PATCH 2/3] mid work --- packages/@aws-cdk-testing/cli-integ/lib/shell.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/lib/shell.ts b/packages/@aws-cdk-testing/cli-integ/lib/shell.ts index ccd3e2d..973f110 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/shell.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/shell.ts @@ -61,12 +61,15 @@ export async function shell(command: string[], options: ShellOptions = {}): Prom if (interaction.prompt.test(lastLine.get())) { - // shift before writing to ensure the same interaction is not reused + // subprocess expects a user input now. + // first, shift the interactions to ensure the same interaction is not reused remainingInteractions.shift(); - // subprocess expects a user input now. - // we have to write the input AFTER the child has started - // reading, so we do this with a small delay. + // then, reset the last line to prevent repeated matches caused by tty echoing + lastLine.reset(); + + // now write the input with a slight delay to ensure + // the child process has already started reading. setTimeout(() => { child.writeStdin(interaction.input + (interaction.end ?? os.EOL)); }, 500); @@ -321,4 +324,8 @@ class LastLine { public get(): string { return this.lastLine; } + + public reset() { + this.lastLine = ''; + } } \ No newline at end of file From 0b28a7f74471141e2614db95eb4bea18f8e8076a Mon Sep 17 00:00:00 2001 From: iliapolo Date: Tue, 8 Apr 2025 12:12:36 +0300 Subject: [PATCH 3/3] mid work --- packages/@aws-cdk-testing/cli-integ/lib/process.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk-testing/cli-integ/lib/process.ts b/packages/@aws-cdk-testing/cli-integ/lib/process.ts index d862d7c..fc5226b 100644 --- a/packages/@aws-cdk-testing/cli-integ/lib/process.ts +++ b/packages/@aws-cdk-testing/cli-integ/lib/process.ts @@ -92,7 +92,7 @@ class PtyProcess implements IProcess { public onStderr(_callback: (chunk: Buffer) => void): void { // https://github.com/microsoft/node-pty/issues/71 - throw new Error('Cannot to register callback for stderr. A tty does not have separate output and error channels'); + throw new Error(`Cannot register callback for 'stderr'. A tty does not have separate output and error channels`); } public onExit(callback: (exitCode: number) => void): void {