execa icon indicating copy to clipboard operation
execa copied to clipboard

Improved `verbose` option

Open ehmicky opened this issue 1 year ago • 1 comments

Proposal

When verbose: true is used, we should also print the command's stdout/stderr.

Details

The verbose option prints commands before executing them. The main use case is debugging.

Most of the times, when users want to debug a command, they want to see the output too.

We can do this in a way that does not change the command's behavior thanks to the recent additions to the std* options.

Alternatives

Without this, users would just console.log(result.stdout, result.stderr) instead. However, this has some shortcomings:

  • Requires using result.all instead to get interleaved output
  • Does not work for commands that never complete, which are a prime target for debugging. In other words, this prints output all at once at the end of command, instead of progressively.
  • When 2 commands run in parallel, in sequence with each other, this does not show their interleaved output

Alternatively, users might use stdout: 'inherit'. However, this has the following problems:

  • If the command's output does not end with a newline, the result will be a little messed up (with concatenated lines that should be separate)
  • When multiple commands run in parallel, it is hard to know which is which. Also, lines might not be printed in full, leading to half of a command's output line being mixed with another command's output line.
  • Does not work with stdout/stderr returning objects, due to transforms in objectMode
  • Users doing stdio: 'inherit' instead would change the command's behavior by making stdin interactive

In other words, getting this right is actually trickier than it looks.

In production, developers tend to use complex commands with weird setups, which can take hours to debug. When it comes to making command execution easier, improving debugging is a major way we can help out our users.

ehmicky avatar Jan 28 '24 18:01 ehmicky

👍

sindresorhus avatar Jan 29 '24 07:01 sindresorhus

There is another use case: when running a Node.js script, users might want to see its progress. As opposed to debugging, they would then want to see the commands as they start/complete, but not necessarily their output.

There is an issue on zx with 8 thumbs up that requests this.

Based on this, I think we might want to turn the verbose option from a boolean to an enum:

  • none: disabled (current behavior when false)
  • short: prints commands (current behavior when true), to see progress
  • full prints commands + their output (new behavior), for debugging

One important bit is that printing output should not change the behavior otherwise. So users can turn on/off full verbose mode and their script should behave the same except for the additional debugging output.

ehmicky avatar Mar 03 '24 16:03 ehmicky