Process Output
ProcessOutput, ProcessOutputStream, ProcessOutputBuffer is used to take control of the current stdout
and stderr
for ListrLogger to ensure that nothing else is written to the console and creates an abstraction for accessing process.stdout
and process.stderr
when needed.
Hijack
ProcessOutput for renderers like DefaultRenderer that need updating your vt100
compatible terminal gives the ability to hijack the current process.stdout
and process.stderr
, create a temporary buffer for storing anything that is trying to write to the terminal since it will corrupt the output of Listr. If the renderer does not request to hijack the terminal output, process.stdout
and process.stderr
will be used directly without any trickery.
Release
After the renderer releases the ProcessOutput and marks it ready to use, everything that has been outputted to the hooked streams will be dumped. This intends to solve the most common cause of opening an issue in the repository which is saying that the output is corrupted and not realizing something else is writing to output the terminal.
Extending Process Output
You can override the default ProcessOutput by extending the class with your expected behavior (e.g. writing to a log file) on the ListrLogger since all the renderers, that either use or do not use the hijacking function, use ProcessOutput through ListrLogger itself. For most cases, just creating a new ProcessOutput()
by passing your own WriteStream
for process.stdout
and process.stderr
through the constructor should be good enough.
Changing the Behavior
v6.1.0 #670You can change the behavior of the ProcessOutput through injecting it to the logger. Since every renderer at some level uses the underlying logger, this can effectively be used to change the behavior of the ProcessOutput as well.
If you do not like the behavior of the ProcessOutput, you can always implement and bring your own through this interface as well.
Code Example
import { EOL } from 'os'
import { Listr, ListrLogger, ProcessOutput, delay } from 'listr2'
const tasks = new Listr(
[
{
title: 'This task will execute.',
task: async (): Promise<void> => {
await delay(500)
console.log('i am logging some stuff out')
}
},
{
title: 'This task will execute.',
task: async (): Promise<void> => {
await delay(500)
console.log('i am logging some more stuff out')
}
},
{
title: 'This task will execute.',
task: async (): Promise<void> => {
await delay(500)
process.stdout.write('writing something here' + EOL)
process.stdout.write('writing something here' + EOL)
}
}
],
{
concurrent: true,
rendererOptions: {
logger: new ListrLogger({ processOutput: new ProcessOutput(null, null, { dump: [] }) })
}
}
)
await tasks.run()