-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
stderr output using writeError(), closes #1905 #3715
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
Conversation
src/Composer/IO/ConsoleIO.php
Outdated
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.
I think it'd be better to move the write content into a private doWrite or such that is called by write/writeError instead of extending this method's signature as it's part of the public interface.
|
Will take a look ASAP; thanks! |
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.
This should also be writeError() I guess
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.
Ah, alright. Yeah I'll give it a second go-over with the more strict guidelines you mentioned in #1905 (I admit I did not completely read all of them before).
|
What to do with the Commands that use the Symfony ConsoleOutput? Something like the following? becomes |
|
Yup that sounds fine.
|
|
Should we then hint |
|
Hinting sounds fine to me, if it causes issues with anyone we can just
migrate to using the composer IO as output instead.
|
|
The typehint breaks a lot of tests. Not sure if I should clean up the tests, or change the approach. Feedback? |
|
Yeah I guess this has to be reverted.. I think it should work if you just replace |
233255d to
4c5d5b1
Compare
|
I need some more time to review in detail, but here is a preliminary list that I think should output to
A few good rules for figuring out if something should go to
In general, Composer will need quite a bit more Unix love. Run any command through |
|
Also, |
67b9cdf to
36b0d6f
Compare
|
Any idea how to explain this? ^ the response is in green (color codes) but... |
|
BTW "No local changes" should be stderr as far as I understand. As for how color usage is determined by default, AFAIK it is done here: It seems this is always true though here: Not sure what's up on yours. |
f4bfc77 to
f6d775d
Compare
|
@dzuelke this should solve some color issues as well: symfony/symfony#13661 |
|
Correct, "no local changes" from Keep up the great work on this, @alcohol! |
c8c1ef8 to
7d22775
Compare
|
@dzuelke One thing I've come across frequently while doing some reading myself is the following, "stderr is also the place where you print stuff like help docs when an invalid argument is passed to a command" with the exception being "when asking explicitly for help docs they should be printed to stdout". Personally I also feel that makes sense. Do you agree? Edit: I specifically mean the exception here. On a side note, do you use IRC by chance? If so, drop me a line sometime on freenode (ethanol). |
7d22775 to
5fe02d1
Compare
|
Yes, I'd also print to |
|
But then wouldn't that stop you from doing for example |
|
If you do a checkout and run I'm not sure on the following cases:
As for help going to stderr, I'd either have to overload the default command from SF2, or submit a PR and cross fingers that they accept it (which might not be the case). |
|
Sorry I meant stdout of course for explicit help! |
👍
Good question. I was going to say that e.g. the xdebug warning should go to
Well that command is completely quiet (like it should be) when running using
Absolutely! |
5fe02d1 to
b665b26
Compare
|
@josegonzalez assuming this means you are making non-standard assumption, because there is no convention about the way to use output to report failures. Detecting failures is based on the exit code only in CLI conventions (it is even something being common to both Unix and Windows systems). stderr vs stdout is not about error report vs non error report (btw, I don't think that shell scripting calls them stdout and stderr at all). They are about message being part of the command output (i.e. something you would pipe to the next command in the chain) vs message not being part of it (informational messages for the user, and error reports are a specific kind of informational messages: they inform of an error) |
That's a wrong assumption. Try a |
|
I'm not saying that it's the right way to do this, and the example I give is a bad one. This is probably a philosophical issue, but here is a better example. I'm the maintainer of multiple vagrant installs at my company, and we manage things through chef. I have it setup so that if chef executes a command which has error output, that is always output in red. Very useful for debugging, and you or I can easily see that the message above is not an error but status output. I would see that error and silence stderr because it's not actually an error, and is going to be confusing to users. Now imagine I give vm access to someone else on the team, a frontend dev, who has no idea how any of the tooling below vagrant works. All they know is about npm and gulp. They bring up the vm, there is an issue with composer failing, but no error output because I silenced status output earlier. They come to me with their issue and now we have to turn on stderr, which happens to also output debug output. What I'm asking for is a way to still have this output behind a While the above vagrant thing happens all the time, from time to time I get an email from my boss - who is by no means non-technical - as to why our deploy is erroring. Turns out npm likes to output status messages to stderr as well, resulting in hundreds of lines like this: It's not an error, npm is running fine, it's just letting us know that certain packages we depend on could use cleanup. And rather than place that behind a flag that I can control - we write deploy logs to files and selectively write to stdout depending upon verbosity of the deploy - it decided to just write to stderr. The deploy didn't fail - because of course i checked the exit code of the command - but it seems like there was an error to the end-user. I guess what I'm saying is that writing these status messages to stderr by default without some notion of log-levels just isn't friendly for developers. |
|
Then use the |
|
Would that silence actual error output? |
|
Yup -q basically kills all output so that's a bit too much. I agree we
could use a -Q or so that quiets all but errors, but then we need to be
able to flag error output (vs stderr output, which isn't necessarily
errors).
|
|
I'm not familiar with the logger you are using in composer, but if it supports the standard log-levels, would you all be opposed to me adding a |
|
@josegonzalez the console output is not using a logger |
|
Would you be opposed to a change that uses a logger (probably monolog)? |
|
I don't feel a logger would be the right answer here, as tempting as it
|
|
Yeah I think what we need is a way to indicate the minimum verbosity level in the write/writeError call, so we can make more use of it without annoying ifs everywhere. That wouldn't solve the whole issue though, we still need a new VERBOSITY_ERROR level IMO that's used for actual error messages. It would be the same as verbosity normal (i.e. show always by default), but with this -Q flag or so we could suppress NORMAL but not ERROR, so we get quiet-except-errors or full-shut-up mode :) |
|
Would it be an option to consider any stderr output without a verbosity
|
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.
Why are you taking this shortcut here @alcohol? It prevents self-updating progress, for instance, with composer install 2>&1 | somepipethatdecoratesoutput; you get many newlines instead (331425b and #3818 are symptoms of that).
Is there a particular reason why you don't want any overwriting behavior when piping? IMO it should still behave that way. Can/should I fix?
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.
Just for the sake of testing, I removed the entire if block and it seems to all still work fine for a composer install (and now the progress works again as expected when piping), but I'm sure there's some other command where things would be broken now, or else you wouldn't have added that code? :) please advise.
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.
Not sure I follow? Doesn't self updating progress use overwrite? This if block is to differentiate between stdout and stderr? I'm missing a link in the context I think... been gone for two weeks.
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.
doWrite() is only used internally (private method). write() and writeError() pass the $stderr boolean. I merely added an extra check to make sure we do have an output interface that supports stderr. Not sure what you mean by shortcut here?
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.
@alcohol run this to reproduce:
COMPOSER_CACHE_DIR=/dev/null composer install 2>&1 | tee /dev/null
The download progress will be written in many new lines instead of in one. The reason is this if, because it skips the entire overwriting stuff using backspaces.
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.
While I am able to reproduce the new lines, I really don't see how this if statement is related. Could it be you are commenting on the wrong line?
The calls go as:
https://github.com/composer/composer/blob/master/src/Composer/Util/RemoteFilesystem.php#L161
https://github.com/composer/composer/blob/master/src/Composer/Util/RemoteFilesystem.php#L332 (repeated)
https://github.com/composer/composer/blob/master/src/Composer/Util/RemoteFilesystem.php#L231
It seems more likely to be related to this line https://github.com/composer/composer/pull/3715/files#diff-bd1b00b10d2c20047a8732546579ce78R166
Before my change, overwrite only ever checked if stdout was decorated. Now it checks if stderr is decorated instead (if trying to overwrite stderr).
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.
I'm sorry, I'm going to sleep now. Have a flight of nearly 12 hours behind me and need to get back to work tomorrow morning. Will pick this up again then if not resolved/clear yet.
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.
Yes, sorry, @alcohol, I mean lines 166+; picked the wrong spot in the code by accident, sorry!
Recently Composer has moved a lot of status messages from stdout to stderr, thus we need to perform a redirect here to keep pattern matching working. See composer/composer#3715 Fixes #19
Recently Composer has moved a lot of status messages from stdout to stderr, thus we need to perform a redirect here to keep pattern matching working. See composer/composer#3715 Fixes #19
…essages. For example - Composer References: composer/composer#3787 composer/composer#3715
…essages. For example - Composer References: composer/composer#3787 composer/composer#3715
…essages. For example - Composer References: composer/composer#3787 composer/composer#3715
…essages. For example - Composer References: composer/composer#3787 composer/composer#3715
…essages. For example - Composer References: composer/composer#3787 composer/composer#3715

Since it was a low hanging fruit, voila. Some grunt work has been done.
/cc @dzuelke I was told by @Seldaek you might have some good insights into what should or should not go to stderr.
What qualifies as stderr I interpreted solely on feedback from @Seldaek and gut feeling so far. Any input is welcome.
Closes #1905
Also closes heroku/heroku-buildpack-php#100