Skip to content

Commit 5ddc3c1

Browse files
committed
Stream CLI server command stderr instead of buffering
1 parent d2f4cd1 commit 5ddc3c1

File tree

1 file changed

+36
-2
lines changed
  • extensions/ql-vscode/src/codeql-cli

1 file changed

+36
-2
lines changed

extensions/ql-vscode/src/codeql-cli/cli.ts

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ export class CodeQLCliServer implements Disposable {
362362
silent?: boolean,
363363
): Promise<string> {
364364
const stderrBuffers: Buffer[] = [];
365+
// The array of fragments of stderr of this line. To be used for logging.
366+
let currentLineStderrBuffers: Buffer[] = [];
365367
if (this.commandInProcess) {
366368
throw new Error("runCodeQlCliInternal called while cli was running");
367369
}
@@ -419,6 +421,32 @@ export class CodeQLCliServer implements Disposable {
419421
// Listen to stderr
420422
process.stderr.addListener("data", (newData: Buffer) => {
421423
stderrBuffers.push(newData);
424+
425+
if (!silent) {
426+
currentLineStderrBuffers.push(newData);
427+
428+
// Print the stderr to the logger as it comes in. We need to ensure that
429+
// we don't split messages on the same line, so we buffer the stderr and
430+
// split it on EOLs.
431+
let currentLineBuffer = Buffer.concat(currentLineStderrBuffers);
432+
const eolBuffer = Buffer.from(EOL);
433+
if (currentLineBuffer.includes(eolBuffer)) {
434+
while (currentLineBuffer.includes(eolBuffer)) {
435+
const line = currentLineBuffer.subarray(
436+
0,
437+
currentLineBuffer.indexOf(eolBuffer),
438+
);
439+
440+
void this.logger.log(line.toString("utf-8"));
441+
442+
currentLineBuffer = currentLineBuffer.subarray(
443+
currentLineBuffer.indexOf(eolBuffer) + eolBuffer.length,
444+
);
445+
}
446+
447+
currentLineStderrBuffers = [currentLineBuffer];
448+
}
449+
}
422450
});
423451
// Listen for process exit.
424452
process.addListener("close", (code) =>
@@ -433,6 +461,10 @@ export class CodeQLCliServer implements Disposable {
433461
// Make sure we remove the terminator;
434462
const data = fullBuffer.toString("utf8", 0, fullBuffer.length - 1);
435463
if (!silent) {
464+
void this.logger.log(
465+
Buffer.concat(currentLineStderrBuffers).toString("utf8"),
466+
);
467+
currentLineStderrBuffers = [];
436468
void this.logger.log("CLI command succeeded.");
437469
}
438470
return data;
@@ -452,8 +484,10 @@ export class CodeQLCliServer implements Disposable {
452484
cliError.stack += getErrorStack(err);
453485
throw cliError;
454486
} finally {
455-
if (!silent) {
456-
void this.logger.log(Buffer.concat(stderrBuffers).toString("utf8"));
487+
if (!silent && currentLineStderrBuffers.length > 0) {
488+
void this.logger.log(
489+
Buffer.concat(currentLineStderrBuffers).toString("utf8"),
490+
);
457491
}
458492
// Remove the listeners we set up.
459493
process.stdout.removeAllListeners("data");

0 commit comments

Comments
 (0)