-
-
Notifications
You must be signed in to change notification settings - Fork 220
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
Use spawn instead of execFile #27
Use spawn instead of execFile #27
Conversation
childProcess.execFile pays no attention `opts.stdio`. `execa.spawn` allows you to set `opts.stdio` options, but it doesn't return a promise. I think we should forgoe using `childProcess.execFile` and just use spawn. We can reimplement much of `execFile`s utility ourself. Rather than having two separate methods `spawn` and `execFile` - I think we should work towards a single method. What options the user sets for `opts.stdio` or `opts.stdin`, etc; Those should determine whether or not the stream is buffered and made part of the promise result, or if they are just streamed (or sent to an Observable), or ignored. This simplifies the API, and offers potentially far more control. Want to use streams/observables for `stdout` because you know it will contain lots of data and you don't want to buffer, but it would nice to just have `stderr` buffered for you to print in case of an error? That would be doable this way, and really separates it from child_process. childProcess.execFile is really just a wrapper around spawn anyways. It's main utility is that in concats `stdio` and `stdout`. Which is pretty easy for us to achieve on our own using `get-stream` This reimplements nearly all of the functionality of execFile. Remaining items to be feature complete with execFile: - [ ] timeout support (should be easy to add back). - [ ] errname resolution. See TODO note on that. I'm not sure we want to use `process.bind('uv')`. I don't really know what it does. - [ ] some stream cleanup code (see childProces.execFile's internal `kill` method. It calls `stream.destroy()`. I am not sure how that will affect `get-stream`)
Very cool! I like this a lot. Will give a more thorough review and response later today. This will also make it easier to achieve #5. |
Can't figure out why Windows is failing. If someone else could give troubleshooting it a go, it would be appreciated |
Using the technique described here, I'm getting the following output: This Branch(failing):
Master (passing)
|
I just... I can't... I don't get it. 49065ca |
Why does this make the tests pass? Could you possibly make the error output any more cryptic? I don't understand you Windows! We are not friends anymore.
dcb00dc
to
49065ca
Compare
Previous commit did not trigger travis. Force pushed another. |
@sindresorhus - How do you want to proceed with this? Do you want me to keep pushing commits until it's feature complete with My only concern is that it's already a pretty major refactor, and I would like to do it in smaller chunks if possible. We can convert my check list from the OP to issues, and just work to fix them before the next release. |
Super-weird... I tried to debug this on my Windows VM, but still no idea why it happen. Fwiw it doesn't happen with |
|
||
return spawned; | ||
}; | ||
module.exports.spawn = util.deprecate(module.exports, 'execa.spawn: just use execa instead.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
execa.spawn()
is deprecated. Useexeca()
instead.
This looks really good. Let's merge now and open issues for what's remaining. I too prefer work done in smaller chunks. And you've already covered to important parts. Can you update the readme, removing spawn and any other changes? |
The tests pass on Windows for me (even with |
@kevva What Windows & Node.js version? |
@sindresorhus, never mind. Ran it in |
Should we open an issue on the Node repo about the weird process.exit behavior? I haven't tried creating a minimal reproduction yet. That would be a first step. |
Definitely, if you can recreate it. Sounds like a horrible bug if valid. |
I did create a simple script exiting with error code |
@kevva - Can you share the script. I'm not able to reproduce with a simple spawn. |
🙌 🎉 |
👏 |
Make sure when you add links to lines on github you press y to get the current commit - Line 160 in 56a20b1
|
Fixes sindresorhus#34 - Adds some tests for functionality copied from `child_process` in sindresorhus#27. - Normalises the result and error objects further. Each now has `killed`, `signal` and `cmd` properties. - NYC was not ignoring the `fixtures` directory. Fixed that, and configured nyc in package.json instead of via CLI.
@jamestalmage One thing we didn't consider here is that if the user does |
Yeah. Or we could automatically discard the buffer if they pipe. |
Was thinking about that too, but can we detect that? |
childProcess.execFile pays no attention
opts.stdio
. This means users can't setstdio
options when callingexca()
. You can setstdio
options when callingexeca.spawn()
, but that does not return a promise.Rather than having two separate methods
execa()
andexeca.spawn()
- I think we should work towards a single method that allows you to configure how it behaves viastdio
options.opts.stdio
oropts.stdin
, etc; Those should determine whether or not the stream is buffered and made part of the promise result, or if they are just streamed (or sent to an Observable), or ignored.To that end, I've reimplemented much of the functionality of
child_process.execFile
.execFile
is really just a wrapper aroundspawn
anyways. It's main utility is that in concatsstdio
andstdout
. Which is pretty easy for us to achieve on our own usingget-stream
.This simplifies the API as we can pretty much deprecate
execa.spawn()
. And it offers more control over the behavior as well. Want to use streams/observables forstdout
because you know it will contain lots of data and you don't want to waste memory buffering? Would it be nice if it still bufferedstderr
for you though? This makes that doable.Remaining items to be feature complete with execFile:
process.bind('uv')
. I don't really know what it does.kill
method. It callsstream.destroy()
. I am not sure how that will affectget-stream
)message
,killed
,code
, etc).Going forward, we'll still need to bikeshed on a few API details, like instead of just
ignore
,pipe
andinherit
, we should addbuffer
andobservable
.