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

cli: highlight error source headers as well #3371

Merged
merged 1 commit into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions cli/src/command_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,15 +543,20 @@ fn print_error_sources(ui: &Ui, source: Option<&dyn error::Error>) -> io::Result
let Some(err) = source else {
return Ok(());
};
if err.source().is_none() {
writeln!(ui.stderr(), "Caused by: {err}")?;
} else {
writeln!(ui.stderr(), "Caused by:")?;
for (i, err) in iter::successors(Some(err), |err| err.source()).enumerate() {
writeln!(ui.stderr(), "{n}: {err}", n = i + 1)?;
}
}
Ok(())
ui.stderr_formatter()
.with_label("error_source", |formatter| {
if err.source().is_none() {
write!(formatter.labeled("heading"), "Caused by: ")?;
writeln!(formatter, "{err}")?;
} else {
writeln!(formatter.labeled("heading"), "Caused by:")?;
for (i, err) in iter::successors(Some(err), |err| err.source()).enumerate() {
write!(formatter.labeled("heading"), "{}: ", i + 1)?;
writeln!(formatter, "{err}")?;
}
}
Ok(())
})
}

fn handle_clap_error(ui: &mut Ui, err: &clap::Error, hints: &[String]) -> io::Result<ExitCode> {
Expand Down
2 changes: 2 additions & 0 deletions cli/src/config/colors.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
[colors]
"error" = { fg = "default", bold = true }
"error_source" = { fg = "default" }
"warning" = { fg = "default", bold = true }
"hint" = { fg = "default" }
"error heading" = { fg = "red", bold = true }
"error_source heading" = { bold = true }
"warning heading" = { fg = "yellow", bold = true }
"hint heading" = { fg = "cyan", bold = true }

Expand Down
9 changes: 8 additions & 1 deletion cli/tests/test_global_opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,13 @@ fn test_color_ui_messages() {
Error: There is no jj repo in "."
"###);

// error source
let stderr = test_env.jj_cmd_failure(&repo_path, &["log", ".."]);
insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"
Error: Path ".." is not in the repo "."
Caused by: Invalid component ".." in repo-relative path "../"
"###);

// warning
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["log", "@"]);
insta::assert_snapshot!(stderr, @r###"
Expand All @@ -418,7 +425,7 @@ fn test_color_ui_messages() {
],
);
insta::assert_snapshot!(stdout, @r###"
8bb159bc30a9859930e567eb9238a7c43ee6744d
167f90e7600a50f85c4f909b53eaf546faa82879
<Error: No commit available> (elided revisions)
0000000000000000000000000000000000000000
"###);
Expand Down