Skip to content

Commit c46b9a7

Browse files
estebankdavidtwco
andcommitted
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 <[email protected]> Signed-off-by: David Wood <[email protected]>
1 parent 729e567 commit c46b9a7

File tree

4 files changed

+67
-2
lines changed

4 files changed

+67
-2
lines changed

src/cargo/core/compiler/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub use self::lto::Lto;
4747
use self::output_depinfo::output_depinfo;
4848
use self::unit_graph::UnitDep;
4949
pub use crate::core::compiler::unit::{Unit, UnitInterner};
50+
use crate::core::features::nightly_features_allowed;
5051
use crate::core::manifest::TargetSourcePath;
5152
use crate::core::profiles::{PanicStrategy, Profile, Strip};
5253
use crate::core::{Edition, Feature, PackageId, Target};
@@ -709,13 +710,24 @@ fn add_error_format_and_color(
709710
// to emit a message that cargo will intercept.
710711
json.push_str(",artifacts");
711712
}
713+
712714
match cx.bcx.build_config.message_format {
713715
MessageFormat::Short | MessageFormat::Json { short: true, .. } => {
714716
json.push_str(",diagnostic-short");
715717
}
716718
_ => {}
717719
}
718720
cmd.arg(json);
721+
722+
if nightly_features_allowed() {
723+
if let (Some(width), _) | (_, Some(width)) = (
724+
cx.bcx.config.cli_unstable().terminal_width,
725+
cx.bcx.config.shell().accurate_err_width(),
726+
) {
727+
cmd.arg(format!("-Zterminal-width={}", width));
728+
}
729+
}
730+
719731
Ok(())
720732
}
721733

src/cargo/core/features.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ pub struct CliUnstable {
357357
pub separate_nightlies: bool,
358358
pub multitarget: bool,
359359
pub rustdoc_map: bool,
360+
pub terminal_width: Option<usize>,
360361
}
361362

362363
impl CliUnstable {
@@ -411,6 +412,16 @@ impl CliUnstable {
411412
Ok(true)
412413
};
413414

415+
fn parse_usize_opt(value: Option<&str>) -> CargoResult<Option<usize>> {
416+
Ok(match value {
417+
Some(value) => match value.parse::<usize>() {
418+
Ok(value) => Some(value),
419+
Err(e) => bail!("expected a number, found: {}", e),
420+
},
421+
None => None,
422+
})
423+
}
424+
414425
match k {
415426
"print-im-a-teapot" => self.print_im_a_teapot = parse_bool(k, v)?,
416427
"unstable-options" => self.unstable_options = parse_empty(k, v)?,
@@ -437,6 +448,7 @@ impl CliUnstable {
437448
"separate-nightlies" => self.separate_nightlies = parse_empty(k, v)?,
438449
"multitarget" => self.multitarget = parse_empty(k, v)?,
439450
"rustdoc-map" => self.rustdoc_map = parse_empty(k, v)?,
451+
"terminal-width" => self.terminal_width = parse_usize_opt(v)?,
440452
_ => bail!("unknown `-Z` flag specified: {}", k),
441453
}
442454

src/cargo/core/shell.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,15 @@ impl Shell {
134134
}
135135
}
136136

137+
/// Returns the width of the terminal in spaces, if any. Always `None` in Windows.
138+
pub fn accurate_err_width(&self) -> Option<usize> {
139+
if self.is_err_tty() {
140+
imp::accurate_stderr_width()
141+
} else {
142+
None
143+
}
144+
}
145+
137146
/// Returns `true` if stderr is a tty.
138147
pub fn is_err_tty(&self) -> bool {
139148
match self.output {
@@ -411,6 +420,10 @@ mod imp {
411420
use super::Shell;
412421
use std::mem;
413422

423+
pub fn accurate_stderr_width() -> Option<usize> {
424+
stderr_width()
425+
}
426+
414427
pub fn stderr_width() -> Option<usize> {
415428
unsafe {
416429
let mut winsize: libc::winsize = mem::zeroed();
@@ -447,6 +460,10 @@ mod imp {
447460

448461
pub(super) use super::default_err_erase_line as err_erase_line;
449462

463+
pub fn accurate_stderr_width() -> Option<usize> {
464+
None
465+
}
466+
450467
pub fn stderr_width() -> Option<usize> {
451468
unsafe {
452469
let stdout = GetStdHandle(STD_ERROR_HANDLE);

tests/testsuite/build.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use cargo::{
77
use cargo_test_support::paths::{root, CargoPathExt};
88
use cargo_test_support::registry::Package;
99
use cargo_test_support::{
10-
basic_bin_manifest, basic_lib_manifest, basic_manifest, lines_match, main_file, project,
11-
rustc_host, sleep_ms, symlink_supported, t, Execs, ProjectBuilder,
10+
basic_bin_manifest, basic_lib_manifest, basic_manifest, is_nightly, lines_match, main_file,
11+
project, rustc_host, sleep_ms, symlink_supported, t, Execs, ProjectBuilder,
1212
};
1313
use std::env;
1414
use std::fs;
@@ -5103,3 +5103,27 @@ fn target_directory_backup_exclusion() {
51035103
p.cargo("build").run();
51045104
assert!(!&cachedir_tag.is_file());
51055105
}
5106+
5107+
#[cargo_test]
5108+
fn simple_terminal_width() {
5109+
if !is_nightly() {
5110+
// --terminal-width is unstable
5111+
return;
5112+
}
5113+
let p = project()
5114+
.file(
5115+
"src/lib.rs",
5116+
r#"
5117+
fn main() {
5118+
let _: () = 42;
5119+
}
5120+
"#,
5121+
)
5122+
.build();
5123+
5124+
p.cargo("build -Zterminal-width=20")
5125+
.masquerade_as_nightly_cargo()
5126+
.with_status(101)
5127+
.with_stderr_contains("3 | ..._: () = 42;")
5128+
.run();
5129+
}

0 commit comments

Comments
 (0)