Skip to content

Commit 017d6eb

Browse files
committed
[cargo-nextest] add an option to disable indentation of output
Some use cases for this include copy/pasting output without block selection, and simple personal preference. Also enable markdown parsing in clap help messages so bold text can be used.
1 parent a4fd948 commit 017d6eb

File tree

6 files changed

+97
-16
lines changed

6 files changed

+97
-16
lines changed

Cargo.lock

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ config = { version = "0.15.11", default-features = false, features = [
4343
"preserve_order",
4444
] }
4545
chrono = "0.4.41"
46-
clap = { version = "4.5.37", features = ["derive"] }
46+
clap = { version = "4.5.37", features = ["derive", "unstable-markdown"] }
4747
console-subscriber = "0.4.1"
4848
cp_r = "0.5.2"
4949
crossterm = { version = "0.29.0", features = ["event-stream"] }

cargo-nextest/src/dispatch.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,17 @@ struct ReporterOpts {
996996
#[arg(long, env = "NEXTEST_HIDE_PROGRESS_BAR", value_parser = BoolishValueParser::new())]
997997
hide_progress_bar: bool,
998998

999+
/// Do not indent captured test output.
1000+
///
1001+
/// By default, test output produced by **--failure-output** and
1002+
/// **--success-output** is indented for visual clarity. This flag disables
1003+
/// that behavior.
1004+
///
1005+
/// This option has no effect with **--no-capture**, since that passes
1006+
/// through standard output and standard error.
1007+
#[arg(long, env = "NEXTEST_NO_INDENT_OUTPUT", value_parser = BoolishValueParser::new())]
1008+
no_indent_output: bool,
1009+
9991010
/// Disable handling of input keys from the terminal.
10001011
///
10011012
/// By default, when running a terminal, nextest accepts the `t` key to dump
@@ -1079,6 +1090,7 @@ impl ReporterOpts {
10791090
builder.set_final_status_level(final_status_level.into());
10801091
}
10811092
builder.set_hide_progress_bar(self.hide_progress_bar);
1093+
builder.set_no_indent_output(self.no_indent_output);
10821094
builder
10831095
}
10841096
}

nextest-runner/src/reporter/displayer/imp.rs

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub(crate) struct DisplayReporterBuilder {
4242
pub(crate) should_colorize: bool,
4343
pub(crate) no_capture: bool,
4444
pub(crate) hide_progress_bar: bool,
45+
pub(crate) no_indent_output: bool,
4546
}
4647

4748
impl DisplayReporterBuilder {
@@ -117,6 +118,7 @@ impl DisplayReporterBuilder {
117118
final_status_level: self.status_levels.final_status_level,
118119
},
119120
no_capture: self.no_capture,
121+
no_indent_output: self.no_indent_output,
120122
styles,
121123
theme_characters,
122124
cancel_status: None,
@@ -218,6 +220,7 @@ struct DisplayReporterImpl<'a> {
218220
default_filter: CompiledDefaultFilter,
219221
status_levels: StatusLevels,
220222
no_capture: bool,
223+
no_indent_output: bool,
221224
styles: Box<Styles>,
222225
theme_characters: ThemeCharacters,
223226
cancel_status: Option<CancelReason>,
@@ -1492,29 +1495,68 @@ impl<'a> DisplayReporterImpl<'a> {
14921495
self.styles.fail
14931496
};
14941497

1495-
// Adding this hbar at the end gives the text a bit of visual weight
1496-
// that makes it look more balanced.
1497-
let hbar = self.theme_characters.hbar(3);
1498+
// Adding an hbar at the end gives the text a bit of visual weight that
1499+
// makes it look more balanced. Align it with the end of the header to
1500+
// provide a visual transition from status lines (PASS/FAIL etc) to
1501+
// indented output.
1502+
//
1503+
// With indentation, the output looks like:
1504+
//
1505+
// FAIL [ .... ]
1506+
// stdout ───
1507+
// <test stdout>
1508+
// stderr ───
1509+
// <test stderr>
1510+
//
1511+
// Without indentation:
1512+
//
1513+
// FAIL [ .... ]
1514+
// ── stdout ──
1515+
// <test stdout>
1516+
// ── stderr ──
1517+
// <test stderr>
1518+
let (six_char_start, six_char_end, eight_char_start, eight_char_end, output_indent) =
1519+
if self.no_indent_output {
1520+
(
1521+
self.theme_characters.hbar(2),
1522+
self.theme_characters.hbar(2),
1523+
self.theme_characters.hbar(1),
1524+
self.theme_characters.hbar(1),
1525+
"",
1526+
)
1527+
} else {
1528+
(
1529+
" ".to_owned(),
1530+
self.theme_characters.hbar(3),
1531+
" ".to_owned(),
1532+
self.theme_characters.hbar(1),
1533+
" ",
1534+
)
1535+
};
14981536

14991537
let stdout_header = format!(
1500-
" {} {}",
1538+
"{} {} {}",
1539+
six_char_start.style(header_style),
15011540
"stdout".style(header_style),
1502-
hbar.style(header_style),
1541+
six_char_end.style(header_style),
15031542
);
15041543
let stderr_header = format!(
1505-
" {} {}",
1544+
"{} {} {}",
1545+
six_char_start.style(header_style),
15061546
"stderr".style(header_style),
1507-
hbar.style(header_style),
1547+
six_char_end.style(header_style),
15081548
);
15091549
let combined_header = format!(
1510-
" {} {}",
1550+
"{} {} {}",
1551+
six_char_start.style(header_style),
15111552
"output".style(header_style),
1512-
hbar.style(header_style),
1553+
six_char_end.style(header_style),
15131554
);
15141555
let exec_fail_header = format!(
1515-
" {} {}",
1516-
"exec fail".style(header_style),
1517-
hbar.style(header_style),
1556+
"{} {} {}",
1557+
eight_char_start.style(header_style),
1558+
"execfail".style(header_style),
1559+
eight_char_end.style(header_style),
15181560
);
15191561

15201562
ChildOutputSpec {
@@ -1523,8 +1565,7 @@ impl<'a> DisplayReporterImpl<'a> {
15231565
stderr_header,
15241566
combined_header,
15251567
exec_fail_header,
1526-
// 4 spaces align with 2 beyond the start of "stdout" and "stderr".
1527-
output_indent: " ",
1568+
output_indent,
15281569
}
15291570
}
15301571

@@ -1775,6 +1816,7 @@ mod tests {
17751816
should_colorize: false,
17761817
no_capture: true,
17771818
hide_progress_bar: false,
1819+
no_indent_output: false,
17781820
};
17791821
let output = ReporterStderr::Buffer(out);
17801822
let reporter = builder.build(output);

nextest-runner/src/reporter/imp.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ pub struct ReporterBuilder {
4141

4242
verbose: bool,
4343
hide_progress_bar: bool,
44+
no_indent_output: bool,
4445
}
4546

4647
impl ReporterBuilder {
@@ -95,6 +96,12 @@ impl ReporterBuilder {
9596
self.hide_progress_bar = hide_progress_bar;
9697
self
9798
}
99+
100+
/// Set to true to disable indentation of captured test output.
101+
pub fn set_no_indent_output(&mut self, no_indent_output: bool) -> &mut Self {
102+
self.no_indent_output = no_indent_output;
103+
self
104+
}
98105
}
99106

100107
impl ReporterBuilder {
@@ -125,6 +132,7 @@ impl ReporterBuilder {
125132
should_colorize: self.should_colorize,
126133
no_capture: self.no_capture,
127134
hide_progress_bar: self.hide_progress_bar,
135+
no_indent_output: self.no_indent_output,
128136
}
129137
.build(output);
130138

workspace-hack/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ backtrace = { version = "0.3.71", features = ["gimli-symbolize"] }
2020
bit-set = { version = "0.8.0" }
2121
bit-vec = { version = "0.8.0" }
2222
camino = { version = "1.1.9", default-features = false, features = ["serde1"] }
23-
clap = { version = "4.5.37", features = ["derive", "env", "unicode", "wrap_help"] }
23+
clap = { version = "4.5.37", features = ["derive", "env", "unicode", "unstable-markdown", "wrap_help"] }
2424
clap_builder = { version = "4.5.37", default-features = false, features = ["color", "env", "std", "suggestions", "unicode", "usage", "wrap_help"] }
2525
console = { version = "0.15.10" }
2626
either = { version = "1.13.0" }
@@ -47,12 +47,14 @@ zerocopy = { version = "0.7.35", features = ["derive", "simd"] }
4747
[build-dependencies]
4848
camino = { version = "1.1.9", default-features = false, features = ["serde1"] }
4949
cc = { version = "1.2.15", default-features = false, features = ["parallel"] }
50+
memchr = { version = "2.7.4" }
5051
proc-macro2 = { version = "1.0.93" }
5152
quote = { version = "1.0.38" }
5253
serde = { version = "1.0.219", features = ["alloc", "derive"] }
5354
syn = { version = "2.0.98", features = ["extra-traits", "full", "visit", "visit-mut"] }
5455

5556
[target.x86_64-unknown-linux-gnu.dependencies]
57+
bitflags = { version = "2.9.0", default-features = false, features = ["std"] }
5658
futures-channel = { version = "0.3.31", features = ["sink"] }
5759
futures-core = { version = "0.3.31" }
5860
futures-sink = { version = "0.3.31" }
@@ -65,9 +67,11 @@ smallvec = { version = "1.15.0", default-features = false, features = ["const_ne
6567
tokio = { version = "1.44.2", default-features = false, features = ["net"] }
6668

6769
[target.x86_64-unknown-linux-gnu.build-dependencies]
70+
bitflags = { version = "2.9.0", default-features = false, features = ["std"] }
6871
libc = { version = "0.2.172", features = ["extra_traits"] }
6972

7073
[target.x86_64-apple-darwin.dependencies]
74+
bitflags = { version = "2.9.0", default-features = false, features = ["std"] }
7175
futures-channel = { version = "0.3.31", features = ["sink"] }
7276
futures-core = { version = "0.3.31" }
7377
futures-sink = { version = "0.3.31" }
@@ -79,6 +83,7 @@ smallvec = { version = "1.15.0", default-features = false, features = ["const_ne
7983
tokio = { version = "1.44.2", default-features = false, features = ["net"] }
8084

8185
[target.x86_64-apple-darwin.build-dependencies]
86+
bitflags = { version = "2.9.0", default-features = false, features = ["std"] }
8287
libc = { version = "0.2.172", features = ["extra_traits"] }
8388

8489
[target.x86_64-pc-windows-msvc.dependencies]

0 commit comments

Comments
 (0)