-
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
Add pager support for rustc --explain EXXXX
#42732
Conversation
r? @arielb1 (rust_highfive has picked a reviewer for you, use r? to override) |
Oh and I had problems during switching |
src/librustc_driver/lib.rs
Outdated
use std::os::unix::io::FromRawFd; | ||
let raw_file_descriptor_id = 2; // stdout | ||
|
||
let pager = env::var("PAGER").unwrap_or(String::from("less")); |
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.
Since it's quite easy, could we use var_os
here (and in the companion windows function)?
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.
Sure thing
src/librustc_driver/lib.rs
Outdated
.expect("unable to write pager content to temporary file"); | ||
|
||
if spawn_pager_with_file(&file_path).is_err() { | ||
println!("unable to spawn pager process"); |
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.
hm, I think ideally we'd send this to stderr and (as in all other cases in this function) send the output to stdout. We shouldn't ever not show the output because a pager is missing.
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.
Good catch!
Looks like this isn't compiling? https://travis-ci.org/rust-lang/rust/jobs/244227954#L1476
|
src/librustc_driver/lib.rs
Outdated
|
||
Command::new(pager) | ||
.arg(file_path) | ||
.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.
I think the reason this is failing on Windows is the use of output()
here. output()
captures stdout which we definitely don't want, it should go to the console so using status()
might be better. However as more.com
and less
accept input over stdin you should be able to do something like the following and avoid creating a file:
let mut child = Command::new(pager).stdin(Stdio::piped()).spawn()?;
child.stdin.as_mut().unwrap().write_all(content.as_bytes())?;
child.wait()
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.
@ollie27 I have tried to use pipes with Command but the 'less' output was corrupted in Linux bash shell. Maybe it was something that I missed. Will try this first thing in the morning.
Thanks a lot
@carols10cents thanks for the heads up |
It's been a very busy week. Sorry for the delay. A revision will be ready next morning |
☔ The latest upstream changes (presumably #42856) made this pull request unmergeable. Please resolve the merge conflicts. |
LLVM and Cargo updated by mistake? Also, tidy error.
|
@kennytm sorry. I was trying to update my fork only. thanks for notifying. fix is coming |
@cengizio Thanks. LLVM and Cargo submodules are still modified in 14b28d0af5c970414f8a8bb681da13b36d5fb658 though. |
@kennytm now it should be clear 😌 |
src/librustc_driver/lib.rs
Outdated
} | ||
None => { | ||
early_error(output, &format!("no extended information for {}", code)); | ||
} | ||
} | ||
} | ||
|
||
fn show_content_with_pager(content: &String) { | ||
let pager_name = env::var_os("PAGER").unwrap_or(if cfg!(windows) { | ||
OsString::from("more.com") |
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.
@Mark-Simulacrum I hope this is the right way of using OsString
s
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, I believe so, but unwrap_or_else
please.
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 do we need a unwrap_or_else
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.
OsString is heap allocated, and with unwrap_or the heap allocation always happens even if not necessary.
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.
Makes sense now. Added!
} | ||
} | ||
|
||
// If pager fails for whatever reason, we should still print the content |
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.
@Mark-Simulacrum as you suggested, now we're falling back to plain printing whenever something goes wrong. And not printing anything to stdout
if there's an error.
src/librustc_driver/lib.rs
Outdated
// Slice off the leading newline and print. | ||
for line in description[1..].lines() { | ||
let indent_level = line.find(|c: char| !c.is_whitespace()) | ||
.unwrap_or_else(|| line.len()); | ||
let dedented_line = &line[indent_level..]; | ||
if dedented_line.starts_with("```") { | ||
is_in_code_block = !is_in_code_block; | ||
println!("{}", &line[..(indent_level+3)]); | ||
text.push_str(&line[..(indent_level+3)]); | ||
text.push('\n'); |
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.
@carols10cents maybe this can be prettier. Suggestions?
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.
IMO It's ok to do that push()
. Though you are doing it here and in like 375
, so you are adding a carriage return regardless of the if
statement, I would just put a single one between lines 376
-377
instead, but that is totally a nitpick.
src/librustc_driver/lib.rs
Outdated
// If pager fails for whatever reason, we should still print the content | ||
// to standard output | ||
if fallback_to_println { | ||
println!("{}", content); |
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.
UI test failure. Please either change this to print!
or update src/test/ui/explain.stdout
to include the new trailing \n
.
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.
@kennytm thanks again.
src/librustc_driver/lib.rs
Outdated
} | ||
text.push('\n'); |
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.
@afiune 👍
@carols10cents I think we can remove the waiting tag and proceed to reviewing |
@bors r+ rollup |
📌 Commit d2a0ead has been approved by |
Add pager support for `rustc --explain EXXXX` Hello! This is my take on rust-lang#32665. Thanks! **EDIT:** _I've limited access to a Windows machine so this is taking longer than I've anticipated_. 🐢 cc @alexcrichton @nikomatsakis @Mark-Simulacrum @retep998 @ollie27 @afiune
If this cannot be easily solved, I'd suggest |
Add pager support for `rustc --explain EXXXX` Hello! This is my take on rust-lang#32665. Thanks! **EDIT:** _I've limited access to a Windows machine so this is taking longer than I've anticipated_. 🐢 cc @alexcrichton @nikomatsakis @Mark-Simulacrum @retep998 @ollie27 @afiune
Add pager support for `rustc --explain EXXXX` Hello! This is my take on rust-lang#32665. Thanks! **EDIT:** _I've limited access to a Windows machine so this is taking longer than I've anticipated_. 🐢 cc @alexcrichton @nikomatsakis @Mark-Simulacrum @retep998 @ollie27 @afiune
ahh @bors r- |
Perhaps if rustc isn't outputting directly to terminal or console (if isatty returns false) then it shouldn't try to use a pager. I think that would fix the test. |
@ollie27 @Mark-Simulacrum @kennytm I'll modify the test as soon as possible. Thanks |
src/librustc_driver/Cargo.toml
Outdated
@@ -35,3 +35,4 @@ serialize = { path = "../libserialize" } | |||
syntax = { path = "../libsyntax" } | |||
syntax_ext = { path = "../libsyntax_ext" } | |||
syntax_pos = { path = "../libsyntax_pos" } | |||
isatty = "0.1" |
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.
@Mark-Simulacrum I'm not 100% sure about the version here. Should I make it strict?
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.
Cargo.lock will handle that for you. I don't know if you need this dependency though, I believe you can find equivalent code in rustbuild (search for cfg(Windows)) and possibly in librustc_errors... I'd prefer not to depend on isatty since that means winapi which currently has long build times.
@kennytm @ollie27 @Mark-Simulacrum I've added I've only tried it with Windows. *nix part needs to be tested. Please feel free to comment on anything. Thank you |
src/librustc_driver/lib.rs
Outdated
* These are duplicated in | ||
* - bootstrap/compile.rs#L478 | ||
* - librustc_errors/emitter.rs#L1253 | ||
*/ |
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.
Could you use a line comments here? Also, you'll need to remove isatty from Cargo.lock/Cargo.toml.
Ok, tty check is done with an embedded logic. |
@Mark-Simulacrum I've tested with *nix and it behaves correctly. We can review and proceed accordingly. |
Looks good to me. Thanks! @bors r+ rollup |
📌 Commit 06de114 has been approved by |
Add pager support for `rustc --explain EXXXX` Hello! Fixes #32665. Thanks! **EDIT:** _I've limited access to a Windows machine so this is taking longer than I've anticipated_. 🐢 cc @alexcrichton @nikomatsakis @Mark-Simulacrum @retep998 @ollie27 @afiune
☀️ Test successful - status-appveyor, status-travis |
Hello!
Fixes #32665.
Thanks!
EDIT: I've limited access to a Windows machine so this is taking longer than I've anticipated. 🐢
cc @alexcrichton @nikomatsakis @Mark-Simulacrum @retep998 @ollie27 @afiune