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

Add pager support for rustc --explain EXXXX #42732

Merged
merged 7 commits into from
Jul 5, 2017
Merged

Add pager support for rustc --explain EXXXX #42732

merged 7 commits into from
Jul 5, 2017

Conversation

cengiz-io
Copy link
Contributor

@cengiz-io cengiz-io commented Jun 18, 2017

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

@rust-highfive
Copy link
Collaborator

r? @arielb1

(rust_highfive has picked a reviewer for you, use r? to override)

@cengiz-io
Copy link
Contributor Author

Oh and I had problems during switching stdout to another process other than rustc. That's why my implementation is using a temporary file. (Unwillingly). Maybe I'm missing something obvious.

use std::os::unix::io::FromRawFd;
let raw_file_descriptor_id = 2; // stdout

let pager = env::var("PAGER").unwrap_or(String::from("less"));
Copy link
Member

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)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing

.expect("unable to write pager content to temporary file");

if spawn_pager_with_file(&file_path).is_err() {
println!("unable to spawn pager process");
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

@carols10cents
Copy link
Member

Looks like this isn't compiling? https://travis-ci.org/rust-lang/rust/jobs/244227954#L1476

[00:14:23] error[E0433]: failed to resolve. Use of undeclared type or module `Stdio`
[00:14:23]    --> /checkout/src/librustc_driver/lib.rs:391:21
[00:14:23]     |
[00:14:23] 391 |             .stdout(Stdio::from_raw_fd(raw_file_descriptor_id))
[00:14:23]     |                     ^^^^^^^^^^^^^^^^^^ Use of undeclared type or module `Stdio`
[00:14:23] 
[00:14:23] error: aborting due to previous error

@carols10cents carols10cents added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jun 19, 2017

Command::new(pager)
.arg(file_path)
.output()
Copy link
Member

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()

Copy link
Contributor Author

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

@cengiz-io
Copy link
Contributor Author

@carols10cents thanks for the heads up

@cengiz-io
Copy link
Contributor Author

It's been a very busy week. Sorry for the delay.

A revision will be ready next morning

@bors
Copy link
Contributor

bors commented Jun 23, 2017

☔ The latest upstream changes (presumably #42856) made this pull request unmergeable. Please resolve the merge conflicts.

@kennytm
Copy link
Member

kennytm commented Jun 28, 2017

LLVM and Cargo updated by mistake? Also, tidy error.

[00:03:00] tidy error: /checkout/src/librustc_driver/lib.rs:389: trailing whitespace
[00:03:00] tidy error: /checkout/src/librustc_driver/lib.rs:391: trailing whitespace
[00:03:00] tidy error: /checkout/src/librustc_driver/lib.rs:393: trailing whitespace

@cengiz-io
Copy link
Contributor Author

@kennytm sorry. I was trying to update my fork only. thanks for notifying. fix is coming

@kennytm
Copy link
Member

kennytm commented Jun 29, 2017

@cengizio Thanks. LLVM and Cargo submodules are still modified in 14b28d0af5c970414f8a8bb681da13b36d5fb658 though.

@cengiz-io
Copy link
Contributor Author

@kennytm now it should be clear 😌

}
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")
Copy link
Contributor Author

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 OsStrings

Copy link
Member

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.

Copy link
Contributor Author

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?

Copy link
Member

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.

Copy link
Contributor Author

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
Copy link
Contributor Author

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.

// 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');
Copy link
Contributor Author

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?

Copy link

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.

// If pager fails for whatever reason, we should still print the content
// to standard output
if fallback_to_println {
println!("{}", content);
Copy link
Member

@kennytm kennytm Jun 29, 2017

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kennytm thanks again.

@afiune
Copy link

afiune commented Jun 29, 2017

}
text.push('\n');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@afiune 👍

@cengiz-io
Copy link
Contributor Author

@carols10cents I think we can remove the waiting tag and proceed to reviewing

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 29, 2017
@Mark-Simulacrum
Copy link
Member

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Jun 29, 2017

📌 Commit d2a0ead has been approved by Mark-Simulacrum

@Mark-Simulacrum Mark-Simulacrum added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 29, 2017
frewsxcv added a commit to frewsxcv/rust that referenced this pull request Jun 30, 2017
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
@kennytm
Copy link
Member

kennytm commented Jun 30, 2017

If this cannot be easily solved, I'd suggest // ignore-windows for this test, and later amend the UI test comparer to ignore difference of trailing whitespaces. This is not something that impacts UI too much.

GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jun 30, 2017
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
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jun 30, 2017
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
@Mark-Simulacrum
Copy link
Member

ahh @bors r-

@ollie27
Copy link
Member

ollie27 commented Jun 30, 2017

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.

@cengiz-io
Copy link
Contributor Author

@ollie27 @Mark-Simulacrum @kennytm I'll modify the test as soon as possible. Thanks

@shepmaster shepmaster added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jun 30, 2017
@@ -35,3 +35,4 @@ serialize = { path = "../libserialize" }
syntax = { path = "../libsyntax" }
syntax_ext = { path = "../libsyntax_ext" }
syntax_pos = { path = "../libsyntax_pos" }
isatty = "0.1"
Copy link
Contributor Author

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?

Copy link
Member

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.

@cengiz-io
Copy link
Contributor Author

@kennytm @ollie27 @Mark-Simulacrum I've added istty crate and used its stdout check.

I've only tried it with Windows. *nix part needs to be tested.

Please feel free to comment on anything.

Thank you

* These are duplicated in
* - bootstrap/compile.rs#L478
* - librustc_errors/emitter.rs#L1253
*/
Copy link
Member

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.

@cengiz-io
Copy link
Contributor Author

Ok, tty check is done with an embedded logic.

@cengiz-io
Copy link
Contributor Author

@Mark-Simulacrum I've tested with *nix and it behaves correctly. We can review and proceed accordingly.

@Mark-Simulacrum
Copy link
Member

Looks good to me. Thanks!

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Jul 4, 2017

📌 Commit 06de114 has been approved by Mark-Simulacrum

@bors
Copy link
Contributor

bors commented Jul 4, 2017

⌛ Testing commit 06de114 with merge 1421bed...

bors added a commit that referenced this pull request Jul 4, 2017
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
@bors
Copy link
Contributor

bors commented Jul 5, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: Mark-Simulacrum
Pushing 1421bed to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants