-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
const proggy = require('proggy') | ||
const { log, output, META } = require('proc-log') | ||
const { log, output, input, META } = require('proc-log') | ||
const { explain } = require('./explain-eresolve.js') | ||
const { formatWithOptions } = require('./format') | ||
|
||
|
@@ -137,6 +137,9 @@ class Display { | |
// Handlers are set immediately so they can buffer all events | ||
process.on('log', this.#logHandler) | ||
process.on('output', this.#outputHandler) | ||
process.on('input', this.#inputHandler) | ||
|
||
this.#progress = new Progress({ stream: stderr }) | ||
} | ||
|
||
off () { | ||
|
@@ -146,9 +149,9 @@ class Display { | |
process.off('output', this.#outputHandler) | ||
this.#outputState.buffer.length = 0 | ||
|
||
if (this.#progress) { | ||
this.#progress.stop() | ||
} | ||
process.off('input', this.#inputHandler) | ||
|
||
this.#progress.off() | ||
} | ||
|
||
get chalk () { | ||
|
@@ -171,6 +174,7 @@ class Display { | |
unicode, | ||
}) { | ||
this.#command = command | ||
|
||
// get createSupportsColor from chalk directly if this lands | ||
// https://github.com/chalk/chalk/pull/600 | ||
const [{ Chalk }, { createSupportsColor }] = await Promise.all([ | ||
|
@@ -201,18 +205,18 @@ class Display { | |
// Emit resume event on the logs which will flush output | ||
log.resume() | ||
output.flush() | ||
this.#startProgress({ progress, unicode }) | ||
this.#progress.load({ | ||
unicode, | ||
enabled: !!progress && !this.#silent, | ||
}) | ||
} | ||
|
||
// STREAM WRITES | ||
|
||
// Write formatted and (non-)colorized output to streams | ||
#stdoutWrite (options, ...args) { | ||
this.#stdout.write(formatWithOptions({ colors: this.#stdoutColor, ...options }, ...args)) | ||
} | ||
|
||
#stderrWrite (options, ...args) { | ||
this.#stderr.write(formatWithOptions({ colors: this.#stderrColor, ...options }, ...args)) | ||
#write (stream, options, ...args) { | ||
const colors = stream === this.#stdout ? this.#stdoutColor : this.#stderrColor | ||
this.#progress.write(stream, formatWithOptions({ colors, ...options }, ...args)) | ||
} | ||
|
||
// HANDLERS | ||
|
@@ -289,16 +293,31 @@ class Display { | |
this.#writeOutput(level, meta, ...args) | ||
}) | ||
|
||
#inputHandler = withMeta((level, meta, ...args) => { | ||
if (level === input.KEYS.start) { | ||
log.pause() | ||
this.#outputState.buffering = true | ||
this.#progress.pause() | ||
return | ||
} | ||
|
||
if (level === input.KEYS.end) { | ||
log.resume() | ||
output.flush() | ||
this.#progress.resume() | ||
} | ||
}) | ||
|
||
// OUTPUT | ||
|
||
#writeOutput (level, meta, ...args) { | ||
if (level === output.KEYS.standard) { | ||
this.#stdoutWrite({}, ...args) | ||
this.#write(this.#stdout, {}, ...args) | ||
return | ||
} | ||
|
||
if (level === output.KEYS.error) { | ||
this.#stderrWrite({}, ...args) | ||
this.#write(this.#stderr, {}, ...args) | ||
} | ||
} | ||
|
||
|
@@ -344,22 +363,95 @@ class Display { | |
this.#logColors[level](level), | ||
title ? this.#logColors.title(title) : null, | ||
] | ||
this.#stderrWrite({ prefix }, ...args) | ||
} else if (this.#progress) { | ||
// TODO: make this display a single log line of filtered messages | ||
this.#write(this.#stderr, { prefix }, ...args) | ||
} | ||
} | ||
} | ||
|
||
class Progress { | ||
// Taken from https://github.com/sindresorhus/cli-spinners | ||
// MIT License | ||
// Copyright (c) Sindre Sorhus <[email protected]> (https://sindresorhus.com) | ||
static dots = { duration: 80, frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'] } | ||
static lines = { duration: 130, frames: ['-', '\\', '|', '/'] } | ||
|
||
#stream | ||
#spinner | ||
#client | ||
#enabled = false | ||
|
||
#frameIndex = 0 | ||
#lastUpdate = 0 | ||
#interval | ||
|
||
#initialTimeout | ||
|
||
constructor ({ stream }) { | ||
this.#client = proggy.createClient({ normalize: true }) | ||
this.#stream = stream | ||
} | ||
|
||
// PROGRESS | ||
load ({ enabled, unicode }) { | ||
this.#enabled = enabled | ||
this.#spinner = unicode ? Progress.dots : Progress.lines | ||
this.#initialTimeout = setTimeout(() => this.#render({ initial: true }), 500) | ||
} | ||
|
||
#startProgress ({ progress, unicode }) { | ||
if (!progress || this.#silent) { | ||
off () { | ||
this.#clear() | ||
} | ||
|
||
pause () { | ||
this.#clear() | ||
this.#stream.clearLine(1) | ||
Check failure on line 406 in lib/utils/display.js
|
||
} | ||
|
||
#clear () { | ||
if (!this.#enabled) { | ||
return | ||
} | ||
this.#progress = proggy.createClient({ normalize: true }) | ||
// TODO: implement proggy trackers in arborist/doctor | ||
// TODO: listen to progress events here and build progress UI | ||
// TODO: see deprecated gauge package for what unicode chars were used | ||
this.#frameIndex = 0 | ||
this.#lastUpdate = 0 | ||
this.#stream.cursorTo(0) | ||
Check failure on line 415 in lib/utils/display.js
|
||
clearTimeout(this.#initialTimeout) | ||
clearInterval(this.#interval) | ||
} | ||
|
||
resume () { | ||
this.#render() | ||
} | ||
|
||
write (stream, str) { | ||
if (!this.#enabled) { | ||
return stream.write(str) | ||
} | ||
this.#stream.cursorTo(0) | ||
stream.write(str) | ||
this.#render() | ||
} | ||
|
||
#render ({ initial } = {}) { | ||
if (initial) { | ||
this.#initialTimeout = null | ||
} | ||
if (!this.#enabled || this.#initialTimeout) { | ||
return | ||
} | ||
this.#renderFrame(Date.now() - this.#lastUpdate >= this.#spinner.duration) | ||
clearInterval(this.#interval) | ||
this.#interval = setInterval(() => this.#renderFrame(true), this.#spinner.duration) | ||
} | ||
|
||
#renderFrame (next) { | ||
if (next) { | ||
this.#lastUpdate = Date.now() | ||
this.#frameIndex++ | ||
if (this.#frameIndex >= this.#spinner.frames.length) { | ||
this.#frameIndex = 0 | ||
} | ||
} | ||
this.#stream.cursorTo(0) | ||
Check failure on line 453 in lib/utils/display.js
|
||
this.#stream.write(this.#spinner.frames[this.#frameIndex]) | ||
} | ||
} | ||
|
||
|