Add support for rustc's -Z terminal-width.

This commit adds support for rustc's `-Z terminal-width` flag, which is
used to trim diagnostic output to fit within the current terminal.

Co-authored-by: David Wood <david@davidtw.co>
Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
Esteban Küber 2019-08-30 19:51:55 -07:00 committed by David Wood
parent 729e5676a0
commit c46b9a70bd
No known key found for this signature in database
GPG Key ID: 2592E76C87381FD9
4 changed files with 67 additions and 2 deletions

View File

@ -47,6 +47,7 @@ pub use self::lto::Lto;
use self::output_depinfo::output_depinfo;
use self::unit_graph::UnitDep;
pub use crate::core::compiler::unit::{Unit, UnitInterner};
use crate::core::features::nightly_features_allowed;
use crate::core::manifest::TargetSourcePath;
use crate::core::profiles::{PanicStrategy, Profile, Strip};
use crate::core::{Edition, Feature, PackageId, Target};
@ -709,6 +710,7 @@ fn add_error_format_and_color(
// to emit a message that cargo will intercept.
json.push_str(",artifacts");
}
match cx.bcx.build_config.message_format {
MessageFormat::Short | MessageFormat::Json { short: true, .. } => {
json.push_str(",diagnostic-short");
@ -716,6 +718,16 @@ fn add_error_format_and_color(
_ => {}
}
cmd.arg(json);
if nightly_features_allowed() {
if let (Some(width), _) | (_, Some(width)) = (
cx.bcx.config.cli_unstable().terminal_width,
cx.bcx.config.shell().accurate_err_width(),
) {
cmd.arg(format!("-Zterminal-width={}", width));
}
}
Ok(())
}

View File

@ -357,6 +357,7 @@ pub struct CliUnstable {
pub separate_nightlies: bool,
pub multitarget: bool,
pub rustdoc_map: bool,
pub terminal_width: Option<usize>,
}
impl CliUnstable {
@ -411,6 +412,16 @@ impl CliUnstable {
Ok(true)
};
fn parse_usize_opt(value: Option<&str>) -> CargoResult<Option<usize>> {
Ok(match value {
Some(value) => match value.parse::<usize>() {
Ok(value) => Some(value),
Err(e) => bail!("expected a number, found: {}", e),
},
None => None,
})
}
match k {
"print-im-a-teapot" => self.print_im_a_teapot = parse_bool(k, v)?,
"unstable-options" => self.unstable_options = parse_empty(k, v)?,
@ -437,6 +448,7 @@ impl CliUnstable {
"separate-nightlies" => self.separate_nightlies = parse_empty(k, v)?,
"multitarget" => self.multitarget = parse_empty(k, v)?,
"rustdoc-map" => self.rustdoc_map = parse_empty(k, v)?,
"terminal-width" => self.terminal_width = parse_usize_opt(v)?,
_ => bail!("unknown `-Z` flag specified: {}", k),
}

View File

@ -134,6 +134,15 @@ impl Shell {
}
}
/// Returns the width of the terminal in spaces, if any. Always `None` in Windows.
pub fn accurate_err_width(&self) -> Option<usize> {
if self.is_err_tty() {
imp::accurate_stderr_width()
} else {
None
}
}
/// Returns `true` if stderr is a tty.
pub fn is_err_tty(&self) -> bool {
match self.output {
@ -411,6 +420,10 @@ mod imp {
use super::Shell;
use std::mem;
pub fn accurate_stderr_width() -> Option<usize> {
stderr_width()
}
pub fn stderr_width() -> Option<usize> {
unsafe {
let mut winsize: libc::winsize = mem::zeroed();
@ -447,6 +460,10 @@ mod imp {
pub(super) use super::default_err_erase_line as err_erase_line;
pub fn accurate_stderr_width() -> Option<usize> {
None
}
pub fn stderr_width() -> Option<usize> {
unsafe {
let stdout = GetStdHandle(STD_ERROR_HANDLE);

View File

@ -7,8 +7,8 @@ use cargo::{
use cargo_test_support::paths::{root, CargoPathExt};
use cargo_test_support::registry::Package;
use cargo_test_support::{
basic_bin_manifest, basic_lib_manifest, basic_manifest, lines_match, main_file, project,
rustc_host, sleep_ms, symlink_supported, t, Execs, ProjectBuilder,
basic_bin_manifest, basic_lib_manifest, basic_manifest, is_nightly, lines_match, main_file,
project, rustc_host, sleep_ms, symlink_supported, t, Execs, ProjectBuilder,
};
use std::env;
use std::fs;
@ -5103,3 +5103,27 @@ fn target_directory_backup_exclusion() {
p.cargo("build").run();
assert!(!&cachedir_tag.is_file());
}
#[cargo_test]
fn simple_terminal_width() {
if !is_nightly() {
// --terminal-width is unstable
return;
}
let p = project()
.file(
"src/lib.rs",
r#"
fn main() {
let _: () = 42;
}
"#,
)
.build();
p.cargo("build -Zterminal-width=20")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr_contains("3 | ..._: () = 42;")
.run();
}