-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
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
utils/tty: handling a TTY stderr #8624
Conversation
Maybe just pass the stream? def color?(stream = $stdout)
…
end |
The issue with that is |
I don't really see how else we can properly detect the output stream. At the point where we are calling either |
We'd need to have some sort of $stderr.puts do
# Tty.color? uses $stderr in here.
end |
Yeah, this would be the simplest of all the implementations (I think), but I wasn't sure overriding |
It can be a Ruby refinement I think. |
Oh thanks, I'll take a look 👍🏼 |
Earlier I tried creating a refinement and added it right at the top of I failed to realise earlier that the String would be interpolated by that time (just as you'd mentioned), so my earlier implementation wasn't correct. I've now created two methods, If this implementation isn't preferred and anyone has comments/suggestions, please do let me know. |
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.
Code seems fine but I wonder if we need to use this everywhere rather than just places using colours?
I think what might be a nicer API for this would be: $stderr.output do
print "No newline yet: "
puts "Formatter.url("https://example.com/")
end This would also work the same way with |
Something like: module Kernel
def output(&block)
Tty.with(self) do |stream|
stream.instance_eval(&block)
end
end
end
module Tty
module_function
def with(stream)
previous_stream = current_stream
self.current_stream = stream
yield stream
ensure
self.current_stream = previous_stream
end
end |
@MikeMcQuaid The main reason I changed all occurrences of |
With the latest push, this PR has been refactored based on the suggestions from @reitermarkus. Unfortunately I wasn't able to implement it in that exact form, here's why: $stderr.output do
puts "Hello"
end
# Works fine
$stderr.output do
call_a_function_to_print("Hello")
end
# Doesn't work – `$stderr` doesn't have a `call_a_function_to_print` method The only solution that came to mind (which would retain the simplicity of the suggestion) was to replace I don't entirely understand why exactly some of these method calls need to be prefixed with If this needs to be changed further or improved, let me know. 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.
Looking good so far. Interested in @reitermarkus' thoughts. #8633 would be good to tackle in here too as it's loosely related?
The changes have been made, all that's left is to include the fix for #8633 here. |
I think everything's done here. Would you mind just checking one last time @reitermarkus? Thanks. |
Looking good so far. I think there are a few more instances where currently |
I also just saw an instance where |
@reitermarkus I believe I've fixed all It's important to note that I have not used
would be modifed to
without The only thing that I was unsure about was |
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.
Let's strip this back to the cases where it's needed and use $stderr.puts
otherwise
The more I think about this PR the more it seems like solving some problems that don't really exist. We've never had any user complaints about e.g. exceptions being outputted incorrectly when redirected |
The problem doesn't exist just for While I believe the change to the |
Thanks ❤️ |
@MikeMcQuaid the PR has been reduced to do just 2 things:
Let me know if any other changes are required. 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.
LGTM, thanks again, nice work!
brew style
with your changes locally?brew tests
with your changes locally?In the current implementation of the
Tty
module, the result of$stdout.tty?
is used to decide whether the output can contain special TTY codes (colours, formatting and so on).However there are some problems with this, as discussed in #8577:
stderr
to a file: if there are coloured outputs in stderr (such as inonoe
), the special characters feature in the file. For example, without a Livecheck Watchlist,brew livecheck 2> test.txt
results intext.txt
containing colour-code characters.stdout
: stderr loses colour output.This PR aims to fix these, and I think using an
@output
variable (which is$stdout
by default and can be changed to$stderr
) makes sense. Here are the options I've considered, though I'm not sure all of these would make sense:$stderr.puts
– set@output
to$stderr
, carry out the normalputs
logic, reset@output
– maybe not a great idea.Tty::Error
module (current implementation) – only difference is that@output
is set to$stderr
– I'm not satisfied with it, doesn't seem like a good fix.Tty
to a class and using an$stdout
instance and an$stderr
instance as required.I'm not sure anything else that's crossed my mind is either possible or worth considering. I'd love to hear your comments and suggestions on how we can proceed with this. Thanks!
Redirection examples
$stderr
to a fileoutput.json
$stdout
to a file Note: `Error` was not coloured red.