-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
io/os: Implement IsTerminal trait on Stdio #81807
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Mark-Simulacrum (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
This comment has been minimized.
This comment has been minimized.
atty needs to be built after core, not before. You may want to see how this is done for other crates like |
Hey @jyn514! Thanks for the help. I've just made a PR to the atty repo: softprops/atty#45 to add the 'rustc-dep-of-std' feature to 'atty', using the same setup as 'cfg-if': https://github.com/alexcrichton/cfg-if/blob/main/Cargo.toml. Once this is added then it should compile just fine, seems to be working locally for me. |
Hm, so I actually am not sure we want to do this, or at least, I'm a bit worried about adding a dependency to libtest which seems to have significantly more complicated logic without a better understanding of that logic and the reasons it exists (probably good ones!); I would also prefer to keep std/test dependencies to ones controlled by rust-lang so that we don't need to fork things or otherwise have trouble editing them. It is also my recollection that there are a number of different crates which do this, in which case it seems reasonable to ask why this one was chosen :) cc @rust-lang/libs - can you give your opinion here? |
I'd prefer to not add dependencies to the std/alloc/core/test/.. crates from outside the |
I'm the one who wrote most of that more complicated logic and contributed it to the
I don't have any strong opinions on this, but would tend to agree with you. Certainly, I employ this strategy in some cases with my own crates, so it makes sense to me.
The Other thoughts:
|
I feel that this logic should probably be moved into libstd since we want rust/library/std/src/io/stdio.rs Lines 491 to 494 in a118ee2
|
Coming back to this after getting some more Rust experience. So basically we'd want to just take the logic that is currently in the Would appreciate any help on this! |
I feel that the best place for the logic is in This then needs to be exported as an unstable feature in |
Hey @Amanieu , Had a first go at implementing the methods on all of the platforms that the I marked it all with an unstable feature Let me know what you think, I'm sure I did something wrong, lol. |
library/std/src/lib.rs
Outdated
@@ -516,6 +516,9 @@ pub mod task { | |||
mod sys_common; | |||
mod sys; | |||
|
|||
#[unstable(feature = "is_atty", issue = "80937")] | |||
pub use sys::stdio::{Stderr, Stdin, Stdout}; |
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.
None of the items inside sys
should be exported. This is solely an implementation detail. Instead is_atty
should be on the Std*
types inside std::io
. You could add an IsAtty
trait to each of the relevant platform modules inside the os
module and implement it there. This should likely forward to a method on sys::stdio::Std*
though. The os
module is where platform specific extensions should be.
library/test/src/lib.rs
Outdated
next_timeout - now | ||
} else { | ||
Duration::new(0, 0) | ||
} |
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 you have been formatting with a stable rustfmt that doesn't support some of the options specified in rustfmt.toml
. Please use ./x.py fmt
instead.
library/test/src/cli.rs
Outdated
@@ -30,7 +31,7 @@ pub struct TestOpts { | |||
impl TestOpts { | |||
pub fn use_color(&self) -> bool { | |||
match self.color { | |||
ColorConfig::AutoColor => !self.nocapture && isatty::stdout_isatty(), | |||
ColorConfig::AutoColor => !self.nocapture && Stdout::is_atty(), |
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.
As written this will break all platforms for which there is no IsAtty
implementation yet.
@mattwilkinsonn did you mean to close this? |
No was reverting my commits so I can get back on the latest version of the repo. Will reopen once i have another revision |
@bjorn3 |
Ah, yes. I looked at the linux specific mod which isn't a re-export of |
Ok, I implemented the trait inside the |
library/std/src/io/stdio.rs
Outdated
|
||
/// Trait to determine if stdio stream (Stdin, Stdout, Stderr) is a tty. | ||
#[unstable(feature = "is_atty", issue = "80937")] | ||
pub trait IsAtty { |
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.
Slight nit: this is actually 3 words: is a TTY
So the proper name for the trait should be IsATty
. But that looks pretty ugly so perhaps IsTerminal
might be a better name.
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.
Renamed to IsTerminal and renamed the function and feature accordingly
☔ The latest upstream changes (presumably #84200) made this pull request unmergeable. Please resolve the merge conflicts. |
I see this is still marked as draft. What work is there left to do before this is ready for review? |
There are compile error it seems. |
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 would really like to see this move forward. I think it'd be great to have this in the std
.
|
||
if unsafe { console_on_any(&[fd]) } { | ||
// False positives aren't possible. If we got a console then | ||
// we definitely have a tty on stdin. |
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.
// we definitely have a tty on stdin. | |
// we definitely have a tty on stdout. |
|
||
if unsafe { console_on_any(&[fd]) } { | ||
// False positives aren't possible. If we got a console then | ||
// we definitely have a tty on stdin. |
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.
// we definitely have a tty on stdin. | |
// we definitely have a tty on stderr. |
use c::{ | ||
STD_ERROR_HANDLE as STD_ERROR, STD_INPUT_HANDLE as STD_INPUT, | ||
STD_OUTPUT_HANDLE as STD_OUTPUT, | ||
}; |
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.
Is it a possibility to just remove these 3 use
s and use them directly like c::STD_ERROR_HANDLE
etc. like it's done in other parts of this file? See e.g.
unsafe { c::GetStdHandle(c::STD_INPUT_HANDLE) as RawHandle } |
Sorry, got distracted with other stuff for the past few months. I'll take a look at this again this week/next week. Thanks for the feedback! |
Considering the changes aren't too big (only ~250 lines changed) it's reasonable to attempt a manual rewrite if you can't get rebasing to work. |
Closing as I've reimplemented the changes in #91121. |
Simple change to use the 'atty' crate in the cli.rs file instead of a custom function. Fixes #80937
However, I couldn't get this to build locally while running
./x.py build --stage 0
and I don't know why. It gives me this error (edited out unrelated parts):I think this is all that needs to be done here but I'm fairly new to Rust and completely new to contributing to the actual compiler so I'm not sure. Would appreciate any help!