ok/jj
1
0
Fork 0
forked from mirrors/jj

cli: report error on bad short-prefixes revset

This commit is contained in:
Martin von Zweigbergk 2023-09-30 13:16:14 -07:00 committed by Martin von Zweigbergk
parent d58664d40c
commit 8ec402fc90
3 changed files with 57 additions and 20 deletions

View file

@ -732,7 +732,7 @@ impl WorkspaceCommandHelper {
let loaded_at_head = command.global_args.at_operation == "@";
let may_update_working_copy = loaded_at_head && !command.global_args.ignore_working_copy;
let working_copy_shared_with_git = is_colocated_git_workspace(&workspace, &repo);
Ok(Self {
let helper = Self {
cwd: command.cwd.clone(),
string_args: command.string_args.clone(),
global_args: command.global_args.clone(),
@ -743,7 +743,11 @@ impl WorkspaceCommandHelper {
template_aliases_map,
may_update_working_copy,
working_copy_shared_with_git,
})
};
// Parse short-prefixes revset early to report error before starting mutable
// operation.
helper.id_prefix_context()?;
Ok(helper)
}
pub fn git_backend(&self) -> Option<&GitBackend> {
@ -1161,8 +1165,9 @@ Set which revision the branch points to with `jj branch set {branch_name} -r <RE
&'repo self,
revset_expression: Rc<RevsetExpression>,
) -> Result<Box<dyn Revset<'repo> + 'repo>, CommandError> {
let revset_expression = revset_expression
.resolve_user_expression(self.repo().as_ref(), &self.revset_symbol_resolver())?;
let symbol_resolver = self.revset_symbol_resolver()?;
let revset_expression =
revset_expression.resolve_user_expression(self.repo().as_ref(), &symbol_resolver)?;
Ok(revset_expression.evaluate(self.repo().as_ref())?)
}
@ -1179,19 +1184,20 @@ Set which revision the branch points to with `jj branch set {branch_name} -r <RE
}
}
pub(crate) fn revset_symbol_resolver(&self) -> DefaultSymbolResolver<'_> {
let id_prefix_context = self.id_prefix_context();
pub(crate) fn revset_symbol_resolver(&self) -> Result<DefaultSymbolResolver<'_>, CommandError> {
let id_prefix_context = self.id_prefix_context()?;
let commit_id_resolver: revset::PrefixResolver<CommitId> =
Box::new(|repo, prefix| id_prefix_context.resolve_commit_prefix(repo, prefix));
let change_id_resolver: revset::PrefixResolver<Vec<CommitId>> =
Box::new(|repo, prefix| id_prefix_context.resolve_change_prefix(repo, prefix));
DefaultSymbolResolver::new(self.repo().as_ref())
let symbol_resolver = DefaultSymbolResolver::new(self.repo().as_ref())
.with_commit_id_resolver(commit_id_resolver)
.with_change_id_resolver(change_id_resolver)
.with_change_id_resolver(change_id_resolver);
Ok(symbol_resolver)
}
pub fn id_prefix_context(&self) -> &IdPrefixContext {
self.user_repo.id_prefix_context.get_or_init(|| {
pub fn id_prefix_context(&self) -> Result<&IdPrefixContext, CommandError> {
self.user_repo.id_prefix_context.get_or_try_init(|| {
let mut context: IdPrefixContext = IdPrefixContext::default();
let revset_string: String = self
.settings
@ -1199,10 +1205,15 @@ Set which revision the branch points to with `jj branch set {branch_name} -r <RE
.get_string("revsets.short-prefixes")
.unwrap_or_else(|_| self.settings.default_revset());
if !revset_string.is_empty() {
let disambiguation_revset = self.parse_revset(&revset_string, None).unwrap();
let disambiguation_revset =
self.parse_revset(&revset_string, None).map_err(|err| {
CommandError::ConfigError(format!(
"Invalid `revsets.short-prefixes`: {err}"
))
})?;
context = context.disambiguate_within(disambiguation_revset);
}
context
Ok(context)
})
}
@ -1213,14 +1224,16 @@ Set which revision the branch points to with `jj branch set {branch_name} -r <RE
pub fn parse_commit_template(
&self,
template_text: &str,
) -> Result<Box<dyn Template<Commit> + '_>, TemplateParseError> {
commit_templater::parse(
) -> Result<Box<dyn Template<Commit> + '_>, CommandError> {
let id_prefix_context = self.id_prefix_context()?;
let template = commit_templater::parse(
self.repo().as_ref(),
self.workspace_id(),
self.id_prefix_context(),
id_prefix_context,
template_text,
&self.template_aliases_map,
)
)?;
Ok(template)
}
/// Returns one-line summary of the given `commit`.
@ -1238,15 +1251,19 @@ Set which revision the branch points to with `jj branch set {branch_name} -r <RE
formatter: &mut dyn Formatter,
commit: &Commit,
) -> std::io::Result<()> {
let id_prefix_context = self
.id_prefix_context()
.expect("parse error should be confined by WorkspaceCommandHelper::new()");
let template = parse_commit_summary_template(
self.repo().as_ref(),
self.workspace_id(),
self.id_prefix_context(),
id_prefix_context,
&self.template_aliases_map,
&self.settings,
)
.expect("parse error should be confined by WorkspaceCommandHelper::new()");
template.format(commit, formatter)
template.format(commit, formatter)?;
Ok(())
}
pub fn check_rewritable<'a>(

View file

@ -213,8 +213,8 @@ fn cmd_debug_revset(
writeln!(ui, "{expression:#?}")?;
writeln!(ui)?;
let expression =
expression.resolve_user_expression(repo, &workspace_command.revset_symbol_resolver())?;
let symbol_resolver = workspace_command.revset_symbol_resolver()?;
let expression = expression.resolve_user_expression(repo, &symbol_resolver)?;
writeln!(ui, "-- Resolved:")?;
writeln!(ui, "{expression:#?}")?;
writeln!(ui)?;

View file

@ -458,6 +458,26 @@ fn test_log_shortest_accessors() {
"###);
}
#[test]
fn test_log_bad_short_prefixes() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]);
let repo_path = test_env.env_root().join("repo");
// Error on bad config of short prefixes
test_env.add_config(r#"revsets.short-prefixes = "!nval!d""#);
let stderr = test_env.jj_cmd_failure(&repo_path, &["status"]);
insta::assert_snapshot!(stderr,
@r###"
Config error: Invalid `revsets.short-prefixes`: --> 1:1
|
1 | !nval!d
| ^---
|
= expected <expression>
For help, see https://github.com/martinvonz/jj/blob/main/docs/config.md.
"###);
}
#[test]
fn test_log_prefix_highlight_styled() {
let test_env = TestEnvironment::default();