From 2b6e24f7cbaf2aaa72ff1da343d888f666d803d3 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Mon, 6 Feb 2023 16:07:48 +0100 Subject: [PATCH 1/3] fix(rosetta): prints colors to log file Rosetta error messages contain colors codes in the errors, which makes the errors produced by Rosetta look like garbage and very hard to parse. Strip the colors if we detect a non-TTY input. (Copied the regex from an MIT-licensed package to avoid adding extra dependencies) --- packages/jsii-rosetta/bin/jsii-rosetta.ts | 6 +++--- .../jsii-rosetta/lib/commands/transliterate.ts | 2 +- packages/jsii-rosetta/lib/rosetta-reader.ts | 4 ++-- packages/jsii-rosetta/lib/util.ts | 16 ++++++++++++++-- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/jsii-rosetta/bin/jsii-rosetta.ts b/packages/jsii-rosetta/bin/jsii-rosetta.ts index 732a77c284..cfc403fbb6 100644 --- a/packages/jsii-rosetta/bin/jsii-rosetta.ts +++ b/packages/jsii-rosetta/bin/jsii-rosetta.ts @@ -514,7 +514,7 @@ function handleDiagnostics(diagnostics: readonly RosettaDiagnostic[], fail: bool if (fail !== false) { // Fail on any diagnostic if (diagnostics.length > 0) { - printDiagnostics(diagnostics, process.stderr); + printDiagnostics(diagnostics, process.stderr, process.stderr.isTTY); logging.error( [ `${diagnostics.length} diagnostics encountered in ${snippetCount} snippets`, @@ -531,7 +531,7 @@ function handleDiagnostics(diagnostics: readonly RosettaDiagnostic[], fail: bool // (so it's very clear what is failing the build), otherwise print everything. const strictDiagnostics = diagnostics.filter((diag) => diag.isFromStrictAssembly); if (strictDiagnostics.length > 0) { - printDiagnostics(strictDiagnostics, process.stderr); + printDiagnostics(strictDiagnostics, process.stderr, process.stderr.isTTY); const remaining = diagnostics.length - strictDiagnostics.length; logging.warn( [ @@ -544,7 +544,7 @@ function handleDiagnostics(diagnostics: readonly RosettaDiagnostic[], fail: bool } if (diagnostics.length > 0) { - printDiagnostics(diagnostics, process.stderr); + printDiagnostics(diagnostics, process.stderr, process.stderr.isTTY); logging.warn(`${diagnostics.length} diagnostics encountered in ${snippetCount} snippets`); } } diff --git a/packages/jsii-rosetta/lib/commands/transliterate.ts b/packages/jsii-rosetta/lib/commands/transliterate.ts index cba52a96e8..853c851f15 100644 --- a/packages/jsii-rosetta/lib/commands/transliterate.ts +++ b/packages/jsii-rosetta/lib/commands/transliterate.ts @@ -126,7 +126,7 @@ export async function transliterateAssembly( } } - rosetta.printDiagnostics(process.stderr); + rosetta.printDiagnostics(process.stderr, process.stderr.isTTY); if (rosetta.hasErrors && options.strict) { throw new Error('Strict mode is enabled and some examples failed compilation!'); } diff --git a/packages/jsii-rosetta/lib/rosetta-reader.ts b/packages/jsii-rosetta/lib/rosetta-reader.ts index 1331bddda8..ba70145d1c 100644 --- a/packages/jsii-rosetta/lib/rosetta-reader.ts +++ b/packages/jsii-rosetta/lib/rosetta-reader.ts @@ -293,8 +293,8 @@ export class RosettaTabletReader { ); } - public printDiagnostics(stream: NodeJS.WritableStream) { - printDiagnostics(this.diagnostics, stream); + public printDiagnostics(stream: NodeJS.WritableStream, colors = true) { + printDiagnostics(this.diagnostics, stream, colors); } public get hasErrors() { diff --git a/packages/jsii-rosetta/lib/util.ts b/packages/jsii-rosetta/lib/util.ts index 2d526b19e2..81aa3b98f6 100644 --- a/packages/jsii-rosetta/lib/util.ts +++ b/packages/jsii-rosetta/lib/util.ts @@ -12,12 +12,12 @@ export interface File { readonly fileName: string; } -export function printDiagnostics(diags: readonly RosettaDiagnostic[], stream: NodeJS.WritableStream) { +export function printDiagnostics(diags: readonly RosettaDiagnostic[], stream: NodeJS.WritableStream, colors: boolean) { // Don't print too much, at some point it just clogs up the log const maxDiags = 50; for (const diag of diags.slice(0, maxDiags)) { - stream.write(diag.formattedMessage); + stream.write(colors ? diag.formattedMessage : stripColorCodes(diag.formattedMessage)); } if (diags.length > maxDiags) { @@ -243,3 +243,15 @@ export async function pathExists(path: string): Promise { throw err; } } + +const ANSI_PATTERN = new RegExp( + [ + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', + '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))', + ].join('|'), + 'g', +); + +function stripColorCodes(x: string) { + return x.replace(ANSI_PATTERN, ''); +} \ No newline at end of file From 2c184c9eaa9922c80450029ba44ab5d526cd6fb1 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Mon, 6 Feb 2023 16:13:10 +0100 Subject: [PATCH 2/3] The linter --- packages/jsii-rosetta/lib/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jsii-rosetta/lib/util.ts b/packages/jsii-rosetta/lib/util.ts index 81aa3b98f6..a39309dd50 100644 --- a/packages/jsii-rosetta/lib/util.ts +++ b/packages/jsii-rosetta/lib/util.ts @@ -254,4 +254,4 @@ const ANSI_PATTERN = new RegExp( function stripColorCodes(x: string) { return x.replace(ANSI_PATTERN, ''); -} \ No newline at end of file +} From 15de676a1cedc797b78660845c2fefda7be006e1 Mon Sep 17 00:00:00 2001 From: Rico Hermans Date: Tue, 28 Feb 2023 10:09:18 +0100 Subject: [PATCH 3/3] Update util.ts --- packages/jsii-rosetta/lib/util.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/jsii-rosetta/lib/util.ts b/packages/jsii-rosetta/lib/util.ts index a39309dd50..55df4cf25d 100644 --- a/packages/jsii-rosetta/lib/util.ts +++ b/packages/jsii-rosetta/lib/util.ts @@ -244,6 +244,7 @@ export async function pathExists(path: string): Promise { } } +// Copy/pasted from the 'ansi-regex' package to avoid taking a dependency for this one line that will never change const ANSI_PATTERN = new RegExp( [ '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',