diff --git a/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts b/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts index 748de9b664610..d67105ed46a88 100644 --- a/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts +++ b/packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts @@ -665,6 +665,7 @@ export class CurrentActivityPrinter extends ActivityPrinterBase { // Display in the same block space, otherwise we're going to have silly empty lines. this.block.displayLines(lines); + this.block.removeEmptyLines(lines); } private progressBar(width: number) { diff --git a/packages/aws-cdk/lib/api/util/display.ts b/packages/aws-cdk/lib/api/util/display.ts index d7b136a36f178..a7071ed6a12a4 100644 --- a/packages/aws-cdk/lib/api/util/display.ts +++ b/packages/aws-cdk/lib/api/util/display.ts @@ -16,8 +16,13 @@ export class RewritableBlock { return this.stream.columns; } + public get height() { + // Might get changed if the user resizes the terminal + return this.stream.rows; + } + public displayLines(lines: string[]) { - lines = terminalWrap(this.width, expandNewlines(lines)); + lines = terminalWrap(this.width, expandNewlines(lines)).slice(0, getMaxBlockHeight(this.height, this.lastHeight, lines)); this.stream.write(cursorUp(this.lastHeight)); for (const line of lines) { @@ -31,6 +36,10 @@ export class RewritableBlock { // The block can only ever get bigger this.lastHeight = Math.max(this.lastHeight, lines.length); } + + public removeEmptyLines(lines: string[]) { + this.stream.write(cursorUp(this.lastHeight - lines.length)); + } } const ESC = '\u001b'; @@ -73,4 +82,9 @@ function expandNewlines(lines: string[]): string[] { ret.push(...line.split('\n')); } return ret; +} + +function getMaxBlockHeight(windowHeight: number | undefined, lastHeight: number, lines: string[]): number { + if (windowHeight === undefined) { return Math.max(lines.length, lastHeight); } + return lines.length < windowHeight ? lines.length : windowHeight - 1; } \ No newline at end of file diff --git a/packages/aws-cdk/test/api/util/display.test.ts b/packages/aws-cdk/test/api/util/display.test.ts new file mode 100644 index 0000000000000..26b54b736b104 --- /dev/null +++ b/packages/aws-cdk/test/api/util/display.test.ts @@ -0,0 +1,39 @@ +import { RewritableBlock } from '../../../lib/api/util/display'; +import { stderr } from '../console-listener'; + + +describe('Rewritable Block Tests', () => { + let block: RewritableBlock; + beforeEach(() => { + block = new RewritableBlock(process.stderr); + process.stderr.rows = 80; + }); + + test('displayLines writes maximum lines based on rows if there are more lines than rows', () => { + const lines = Array.from(Array(100).keys()).map(line => line.toString()); + const output = stderr.inspectSync(() => { + block.displayLines(lines); + }); + + expect(output.length).toEqual(block.height!); + }); + + test('displayLines writes maximum lines based on lines length if there are less lines than rows', () => { + const lines = Array.from(Array(45).keys()).map(line => line.toString()); + const output = stderr.inspectSync(() => { + block.displayLines(lines); + }); + + expect(output.length).toEqual(46); + }); + + test('displayLines writes maximum lines based on lines length if rows is undefined', () => { + const lines = Array.from(Array(5).keys()).map(line => line.toString()); + process.stderr.rows = undefined; + const output = stderr.inspectSync(() => { + block.displayLines(lines); + }); + + expect(output.length).toEqual(6); + }); +}); \ No newline at end of file