Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stdout/stderr-specific options #930

Closed
ehmicky opened this issue Mar 25, 2024 · 0 comments · Fixed by #974
Closed

Stdout/stderr-specific options #930

ehmicky opened this issue Mar 25, 2024 · 0 comments · Fixed by #974

Comments

@ehmicky
Copy link
Collaborator

ehmicky commented Mar 25, 2024

Some options currently apply to both stdout and stderr, but could be useful to apply to only stdout or only stderr. The options are: verbose, lines, buffer, maxBuffer, encoding, stripFinalNewline.

Some examples where this could be useful:

  • verbose option: reduce verbosity by only logging stderr for debugging, not stdout
  • lines option: if stdout is line-wise output (e.g. ndjson/jsonlines), but stderr is not interesting to split into lines (e.g. error messages wrapped into multiple lines)
  • buffer option: if stdout is big and manually streamed, but stderr is retrieved using result.stderr
  • maxBuffer option: if stdout uses lines: true option, but not stderr, i.e. maxBuffer is measured in lines with stdout and in characters with stderr, which means the maxBuffer value should be different
  • encoding option: if stdout uses binary format, but stderr prints error messages as text.
    • Edit: I am giving up on this specific option because it is much more complicated to implement that the others, and is less useful.

Overall, being able to apply those options to only stdout or stderr seems quite useful. The problem is: how to design this in a way that does not bloat the API? One possible solution:

await execa(..., {verbose: 'full'}) // By default, applies to both stdout and stderr
await execa(..., {verbose: {stdout: 'full', stderr: 'none'}}) // Apply separate values

To not complicate the documentation too much, we could skip documenting it in each of the above options. Instead, we would just add a small section after the "Options" section that would mention something like: "By default, the following options apply to both stdout and stderr. To apply those options to only stdout or only stderr, please use the following syntax: [code example]".

The implementation is not a problem, since those options are already "file descriptor-wise" in the code. So it'd be quite simple to implement.

Alternative syntaxes:

  • Re-using the stdout/stderr/stdio options. However, those are already quite complex. Besides re-using the same values as child_process.spawn(), those can now include transforms and additional targets (file paths/URLs, web streams). Also, they can optionally be an array of those values. Adding to those options might be too much.
  • Using an array instead of a plain object: execa(..., {verbose: ['full', 'none']}). While more concise, this might be less explicit/clear since it does not mention stdout/stderr as keys. Also, this would start with file descriptor 1 (stdout) instead of 0 (stdin), unlike the stdio option, which might create some errors. Finally, this would require passing undefined (or a sparse array) when stdout should keep its default value.

We also have the option to not do this at all, although I do think it'd be useful and solve some limitations with the above options.

What are your thoughts on this @sindresorhus?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant