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

exit watch process on EOF / Ctrl-D #358

Merged
merged 4 commits into from
Nov 17, 2020

Conversation

tverlaan
Copy link
Contributor

@tverlaan tverlaan commented Nov 4, 2020

It's quite common to be able to exit from a running process with Ctrl-D. This also makes it possible to integrate postcss-cli in external applications as is also mentioned in this webpack PR: webpack/webpack#1311.

I could also make it an additional flag if that is preferred.

@RyanZim
Copy link
Collaborator

RyanZim commented Nov 4, 2020

What's the use-case for this?

@tverlaan
Copy link
Contributor Author

tverlaan commented Nov 5, 2020

I embed the postcss-cli watcher in my own application (more info can be found in the webpack-pr I linked). When my application exits it closes stdin for the postcss-cli watcher, however postcss-cli keeps running in the background. On exiting/starting my application multiple times I create multiple orphaned opencss-cli watcher processes. I have to manually kill them.

@tverlaan tverlaan force-pushed the tv_exit_on_stdin_eof branch from 3d28270 to d79bb8d Compare November 9, 2020 14:36
@coveralls

This comment has been minimized.

@coveralls

This comment has been minimized.

@RyanZim
Copy link
Collaborator

RyanZim commented Nov 9, 2020

Why can't your application just send SIGINT/Ctrl+C to the postcss-cli process when it closes?

@tverlaan
Copy link
Contributor Author

I think it potentially could, but then it would only be for postcss-cli. An external application that starts postcss-cli usually controls stdin & stdout, therefor it makes most sense to use mechanisms that are already available. Non-daemon applications usually bind to stdin&stdout and therefor it would make sense if it responds to this. The external application is not sending signals, it's just closing and opening stdin/stdout for the child process.
Webpack, Brunch & create-react-app all implement it like this and I'd rather stick to the same solution here.

@RyanZim
Copy link
Collaborator

RyanZim commented Nov 11, 2020

OK, fair enough. I still think it's a bit of an odd pattern, but if the ecosystem has it, I guess we can do it. This will need an automated test written, though, before I can merge this.

@tverlaan
Copy link
Contributor Author

It's quite common for UNIX cli tools to behave like this, shells for example: https://unix.stackexchange.com/questions/110240/why-does-ctrl-d-eof-exit-the-shell

I hope the test is ok like this :-)

test/watch.js Outdated Show resolved Hide resolved
@RyanZim
Copy link
Collaborator

RyanZim commented Nov 12, 2020

It's quite common for UNIX cli tools to behave like this, shells for example: https://unix.stackexchange.com/questions/110240/why-does-ctrl-d-eof-exit-the-shell

This behavior is indeed standard for interactive programs, like shells or REPLs, that are controlled by user input on stdin, I find it odd for a program that does not read stdin for anything else in watch mode, that's all.

@tverlaan tverlaan force-pushed the tv_exit_on_stdin_eof branch from 8f98838 to 8d6edda Compare November 12, 2020 15:41
@RyanZim
Copy link
Collaborator

RyanZim commented Nov 12, 2020

Looks great, only one problem; I tested applying the commit with the test to master, and the new test passes even without your original patch, so something with the test isn't working correctly. 🙁

@tverlaan
Copy link
Contributor Author

Nice catch! I changed the implementation a bit, the test works properly now. I think the catch(err) was actually preventing a clean exit which was actually pointing to a flawed implementation from my side. Should be fixed now.

@RyanZim
Copy link
Collaborator

RyanZim commented Nov 12, 2020

I messed around a bit, the test was sort of failing for the wrong reason earlier; here's a patch to make it better:

diff --git a/test/watch.js b/test/watch.js
index a6cf2e4..4a51a11 100644
--- a/test/watch.js
+++ b/test/watch.js
@@ -8,6 +8,7 @@ const chokidar = require('chokidar')
 
 const ENV = require('./helpers/env.js')
 const read = require('./helpers/read.js')
+const tmp = require('./helpers/tmp.js')
 
 // XXX: All the tests in this file are skipped on the CI; too flacky there
 const testCb = process.env.CI ? test.cb.skip : test.cb
@@ -287,13 +288,17 @@ testCb("--watch doesn't exit on CssSyntaxError", (t) => {
 })
 
 testCb('--watch does exit on closing stdin (Ctrl-D/EOF)', (t) => {
-  t.plan(0)
+  t.plan(1)
 
   const cp = spawn(
-    `node ${path.resolve('bin/postcss')} -o output.css -w --no-map`,
+    `./bin/postcss test/fixtures/a.css -o ${tmp()} -w --no-map`,
     { shell: true }
   )
+
   cp.on('error', t.end)
-  cp.on('exit', t.end)
+  cp.on('exit', (code) => {
+    t.is(code, 0)
+    t.end()
+  })
   cp.stdin.end()
 })

Copy that text into a file, then run git apply <file> from the working directory on your branch, commit & push, and this should be good to merge.

@tverlaan
Copy link
Contributor Author

Thanks a lot! I'm not familiar enough with the testing framework and checking if the code = 0 explicitly looks a lot better than just passing it along.
Also, git apply - allows for reading from stdin, no need for the tempfile :-)

@RyanZim RyanZim merged commit b19fbdc into postcss:master Nov 17, 2020
@tverlaan tverlaan deleted the tv_exit_on_stdin_eof branch November 17, 2020 09:19
@RyanZim
Copy link
Collaborator

RyanZim commented Nov 17, 2020

Published v8.3.0 🎉

@bug-tape
Copy link

It would have been nice to have this new behaviour only with a new command line argument. This change effectively stopped my docker containers. Luckily this was not a big problem, only surprising. Docker has a simple solution for that: stdin_open: true.

@RyanZim
Copy link
Collaborator

RyanZim commented Nov 30, 2020

@bug-tape Ah, sorry about that. I didn't think it would affect any existing use-cases, but apparently it did yours. I'll try to be more cautious in the future.

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

Successfully merging this pull request may close these issues.

4 participants