Skip to content

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.

v6.0.0 #651

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 #670

You 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
ts
import { Listr, ListrLogger, ProcessOutput, delay } from 'listr2'
import { EOL } from 'os'

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()