Skip to content

Commit

Permalink
cli: render string pattern suggestion as a hint
Browse files Browse the repository at this point in the history
Templater doesn't have the one yet, but I think it belongs to the same
category.

For clap::Error, we could use clap's own mechanism to render suggestions as
"tip: ...", but I feel "Hint: ..." looks better because our error/hint message
is capitalized.
  • Loading branch information
yuja committed Mar 30, 2024
1 parent d759ba1 commit a6615bf
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 4 deletions.
29 changes: 28 additions & 1 deletion cli/src/command_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use jj_lib::revset::{
RevsetEvaluationError, RevsetParseError, RevsetParseErrorKind, RevsetResolutionError,
};
use jj_lib::signing::SignInitError;
use jj_lib::str_util::StringPatternParseError;
use jj_lib::working_copy::{ResetError, SnapshotError, WorkingCopyStateError};
use jj_lib::workspace::WorkspaceInitError;
use thiserror::Error;
Expand Down Expand Up @@ -423,6 +424,9 @@ impl From<RevsetParseError> for CommandError {
name: _,
candidates,
} => format_similarity_hint(candidates),
RevsetParseErrorKind::InvalidFunctionArguments { .. } => {
find_source_parse_error_hint(bottom_err)
}
_ => None,
};
let mut cmd_err =
Expand Down Expand Up @@ -470,6 +474,8 @@ impl From<TemplateParseError> for CommandError {
| TemplateParseErrorKind::NoSuchMethod { candidates, .. } => {
format_similarity_hint(candidates)
}
TemplateParseErrorKind::InvalidArguments { .. }
| TemplateParseErrorKind::Expression(_) => find_source_parse_error_hint(bottom_err),
_ => None,
};
let mut cmd_err =
Expand All @@ -489,7 +495,10 @@ impl From<FsPathParseError> for CommandError {

impl From<clap::Error> for CommandError {
fn from(err: clap::Error) -> Self {
cli_error(err)
let hint = find_source_parse_error_hint(&err);
let mut cmd_err = cli_error(err);
cmd_err.extend_hints(hint);
cmd_err
}
}

Expand All @@ -511,6 +520,24 @@ impl From<GitIgnoreError> for CommandError {
}
}

fn find_source_parse_error_hint(err: &dyn error::Error) -> Option<String> {
let source = err.source()?;
if let Some(source) = source.downcast_ref() {
string_pattern_parse_error_hint(source)
} else {
None
}
}

fn string_pattern_parse_error_hint(err: &StringPatternParseError) -> Option<String> {
match err {
StringPatternParseError::InvalidKind(_) => {
Some("Try prefixing with one of `exact:`, `glob:` or `substring:`".into())
}
StringPatternParseError::GlobPattern(_) => None,
}
}

const BROKEN_PIPE_EXIT_CODE: u8 = 3;

pub(crate) fn handle_command_result(ui: &mut Ui, result: Result<(), CommandError>) -> ExitCode {
Expand Down
3 changes: 2 additions & 1 deletion cli/tests/test_branch_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,9 +396,10 @@ fn test_branch_delete_glob() {
// Unknown pattern kind
let stderr = test_env.jj_cmd_cli_error(&repo_path, &["branch", "forget", "whatever:branch"]);
insta::assert_snapshot!(stderr, @r###"
error: invalid value 'whatever:branch' for '[NAMES]...': Invalid string pattern kind "whatever:", try prefixing with one of `exact:`, `glob:` or `substring:`
error: invalid value 'whatever:branch' for '[NAMES]...': Invalid string pattern kind "whatever:"
For more information, try '--help'.
Hint: Try prefixing with one of `exact:`, `glob:` or `substring:`
"###);
}

Expand Down
3 changes: 2 additions & 1 deletion cli/tests/test_revset_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ fn test_bad_function_call() {
| ^---------^
|
= Function "branches": Invalid string pattern
2: Invalid string pattern kind "bad:", try prefixing with one of `exact:`, `glob:` or `substring:`
2: Invalid string pattern kind "bad:"
Hint: Try prefixing with one of `exact:`, `glob:` or `substring:`
"###);

let stderr = test_env.jj_cmd_failure(&repo_path, &["log", "-r", "root()::whatever()"]);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/str_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use thiserror::Error;
#[derive(Debug, Error)]
pub enum StringPatternParseError {
/// Unknown pattern kind is specified.
#[error(r#"Invalid string pattern kind "{0}:", try prefixing with one of `exact:`, `glob:` or `substring:`"#)]
#[error(r#"Invalid string pattern kind "{0}:""#)]
InvalidKind(String),
/// Failed to parse glob pattern.
#[error(transparent)]
Expand Down

0 comments on commit a6615bf

Please sign in to comment.