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
Piping shortcut notation #525
Comments
Done in #531 |
I cannot think of anything better than these. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Problem
Redirecting a process's output to two different targets is a common pattern. For example, a user might want to
inherit
stdout/stderr for debugging reasons, while still usingpipe
to get a process's return value.This is currently possible, but requires 3 statements, which trips up users who are less familiar with process execution. This required us to explicitly add those in our Tips documentation.
This also makes chaining processes rather verbose. For example, we just got an issue #521 which was mostly related to that problem. The solution is not as simple as it could be.
Having a simple syntax for chaining processes is especially important with the new
$
API because users might expect the convenience of the|
shell syntax. For example,zx
provides 2 ways of doing this:Solution
This problem could be solved by introducing a shortcut notation. For example, the above examples above could be written as:
It would do the same thing, just in a shorter way, so it would be rather minimal to implement and document.
Return value
When piping to a stream (like
process.stdout
), the return value would be thechildProcessResult
, not the stream, since users would most likely want to retrieve the process's result.However, when piping to another
childProcessResult
(i.e. to itsstdin
), that otherchildProcessResult
would be returned. This allows command chaining. Also, this mimics how piping works in shells. For example, in Bash,$(cat package.json | grep name)
returns the result aftergrep
has been applied. Overall, this is what users would expect.Stderr
pipeStderr()
andpipeAll()
could be available to redirect stderr, or stdout+stderr.Synchronous methods
Those methods only make sense with the async
execa()
methods, since they would otherwise be called once the process has already completed.Alternative solution
We could also implement this using the new
$
API with a special pipe symbol, likezx
does.However, I think this solution might not be as good for the following reasons:
execa()
andexecaCommand()
calls$`...`
syntax. At the moment, the string argument only has command and arguments, with no shell-like syntax, which is much simpler to document and understand. It would also create some confusion for users expecting the command to be run in a shell by default (which is not the case) due to the usage of the pipe symbol.pipeStdout()
can use.bind()
or be assigned to a variable or parameter. Using a string makes this kind of manipulation harder.Naming
If you have other naming ideas for
pipeStdout()
,pipeStderr()
andpipeAll()
, please let me know!stdout()
, etc. does not work becausechildProcess.stdout
is already assigned as a streamstdoutTo()
, etc. could work, but users might understand the work "pipe" betterpipe()
could work forpipeStdout()
, but users might not understand it is a different method thanStream.prototype.pipe()
.What do you think @sindresorhus?
The text was updated successfully, but these errors were encountered: