forked from mirrors/jj
cli: load [template-aliases] section and pass around aliases table
This commit is contained in:
parent
9d356b8094
commit
d0715a0935
5 changed files with 74 additions and 4 deletions
|
@ -59,7 +59,7 @@ use tracing_subscriber::prelude::*;
|
||||||
use crate::config::{AnnotatedValue, CommandNameAndArgs, LayeredConfigs};
|
use crate::config::{AnnotatedValue, CommandNameAndArgs, LayeredConfigs};
|
||||||
use crate::formatter::{Formatter, PlainTextFormatter};
|
use crate::formatter::{Formatter, PlainTextFormatter};
|
||||||
use crate::merge_tools::{ConflictResolveError, DiffEditError};
|
use crate::merge_tools::{ConflictResolveError, DiffEditError};
|
||||||
use crate::template_parser::{self, TemplateParseError};
|
use crate::template_parser::{self, TemplateAliasesMap, TemplateParseError};
|
||||||
use crate::templater::Template;
|
use crate::templater::Template;
|
||||||
use crate::ui::{ColorChoice, Ui};
|
use crate::ui::{ColorChoice, Ui};
|
||||||
|
|
||||||
|
@ -464,6 +464,7 @@ pub struct WorkspaceCommandHelper {
|
||||||
workspace: Workspace,
|
workspace: Workspace,
|
||||||
repo: Arc<ReadonlyRepo>,
|
repo: Arc<ReadonlyRepo>,
|
||||||
revset_aliases_map: RevsetAliasesMap,
|
revset_aliases_map: RevsetAliasesMap,
|
||||||
|
template_aliases_map: TemplateAliasesMap,
|
||||||
may_update_working_copy: bool,
|
may_update_working_copy: bool,
|
||||||
working_copy_shared_with_git: bool,
|
working_copy_shared_with_git: bool,
|
||||||
}
|
}
|
||||||
|
@ -479,6 +480,7 @@ impl WorkspaceCommandHelper {
|
||||||
repo: Arc<ReadonlyRepo>,
|
repo: Arc<ReadonlyRepo>,
|
||||||
) -> Result<Self, CommandError> {
|
) -> Result<Self, CommandError> {
|
||||||
let revset_aliases_map = load_revset_aliases(ui, &settings)?;
|
let revset_aliases_map = load_revset_aliases(ui, &settings)?;
|
||||||
|
let template_aliases_map = load_template_aliases(ui, &settings)?;
|
||||||
let loaded_at_head = &global_args.at_operation == "@";
|
let loaded_at_head = &global_args.at_operation == "@";
|
||||||
let may_update_working_copy = loaded_at_head && !global_args.ignore_working_copy;
|
let may_update_working_copy = loaded_at_head && !global_args.ignore_working_copy;
|
||||||
let mut working_copy_shared_with_git = false;
|
let mut working_copy_shared_with_git = false;
|
||||||
|
@ -498,6 +500,7 @@ impl WorkspaceCommandHelper {
|
||||||
workspace,
|
workspace,
|
||||||
repo,
|
repo,
|
||||||
revset_aliases_map,
|
revset_aliases_map,
|
||||||
|
template_aliases_map,
|
||||||
may_update_working_copy,
|
may_update_working_copy,
|
||||||
working_copy_shared_with_git,
|
working_copy_shared_with_git,
|
||||||
})
|
})
|
||||||
|
@ -804,6 +807,7 @@ impl WorkspaceCommandHelper {
|
||||||
self.repo.as_repo_ref(),
|
self.repo.as_repo_ref(),
|
||||||
self.workspace_id(),
|
self.workspace_id(),
|
||||||
template_text,
|
template_text,
|
||||||
|
&self.template_aliases_map,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,6 +829,7 @@ impl WorkspaceCommandHelper {
|
||||||
let template = parse_commit_summary_template(
|
let template = parse_commit_summary_template(
|
||||||
self.repo.as_repo_ref(),
|
self.repo.as_repo_ref(),
|
||||||
self.workspace_id(),
|
self.workspace_id(),
|
||||||
|
&self.template_aliases_map,
|
||||||
&self.settings,
|
&self.settings,
|
||||||
);
|
);
|
||||||
template.format(commit, formatter)
|
template.format(commit, formatter)
|
||||||
|
@ -957,6 +962,7 @@ impl WorkspaceCommandHelper {
|
||||||
let summary_template = parse_commit_summary_template(
|
let summary_template = parse_commit_summary_template(
|
||||||
self.repo.as_repo_ref(),
|
self.repo.as_repo_ref(),
|
||||||
&workspace_id,
|
&workspace_id,
|
||||||
|
&self.template_aliases_map,
|
||||||
&self.settings,
|
&self.settings,
|
||||||
);
|
);
|
||||||
let stats = update_working_copy(
|
let stats = update_working_copy(
|
||||||
|
@ -1106,6 +1112,7 @@ impl WorkspaceCommandTransaction<'_> {
|
||||||
let template = parse_commit_summary_template(
|
let template = parse_commit_summary_template(
|
||||||
self.tx.repo().as_repo_ref(),
|
self.tx.repo().as_repo_ref(),
|
||||||
self.helper.workspace_id(),
|
self.helper.workspace_id(),
|
||||||
|
&self.helper.template_aliases_map,
|
||||||
&self.helper.settings,
|
&self.helper.settings,
|
||||||
);
|
);
|
||||||
template.format(commit, formatter)
|
template.format(commit, formatter)
|
||||||
|
@ -1520,9 +1527,29 @@ pub fn update_working_copy(
|
||||||
pub const DESCRIPTION_PLACEHOLDER_TEMPLATE: &str =
|
pub const DESCRIPTION_PLACEHOLDER_TEMPLATE: &str =
|
||||||
r#"label("description", "(no description set)")"#;
|
r#"label("description", "(no description set)")"#;
|
||||||
|
|
||||||
|
fn load_template_aliases(
|
||||||
|
ui: &mut Ui,
|
||||||
|
settings: &UserSettings,
|
||||||
|
) -> Result<TemplateAliasesMap, CommandError> {
|
||||||
|
const TABLE_KEY: &str = "template-aliases";
|
||||||
|
let mut aliases_map = TemplateAliasesMap::new();
|
||||||
|
let table = settings.config().get_table(TABLE_KEY)?;
|
||||||
|
for (decl, value) in table.into_iter().sorted_by(|a, b| a.0.cmp(&b.0)) {
|
||||||
|
let r = value
|
||||||
|
.into_string()
|
||||||
|
.map_err(|e| e.to_string())
|
||||||
|
.and_then(|v| aliases_map.insert(&decl, v).map_err(|e| e.to_string()));
|
||||||
|
if let Err(s) = r {
|
||||||
|
writeln!(ui.warning(), r#"Failed to load "{TABLE_KEY}.{decl}": {s}"#)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(aliases_map)
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_commit_summary_template<'a>(
|
fn parse_commit_summary_template<'a>(
|
||||||
repo: RepoRef<'a>,
|
repo: RepoRef<'a>,
|
||||||
workspace_id: &WorkspaceId,
|
workspace_id: &WorkspaceId,
|
||||||
|
aliases_map: &TemplateAliasesMap,
|
||||||
settings: &UserSettings,
|
settings: &UserSettings,
|
||||||
) -> Box<dyn Template<Commit> + 'a> {
|
) -> Box<dyn Template<Commit> + 'a> {
|
||||||
// TODO: Better to parse template early (at e.g. WorkspaceCommandHelper::new())
|
// TODO: Better to parse template early (at e.g. WorkspaceCommandHelper::new())
|
||||||
|
@ -1533,7 +1560,9 @@ fn parse_commit_summary_template<'a>(
|
||||||
.config()
|
.config()
|
||||||
.get_string("template.commit_summary")
|
.get_string("template.commit_summary")
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|s| template_parser::parse_commit_template(repo, workspace_id, &s).ok())
|
.and_then(|s| {
|
||||||
|
template_parser::parse_commit_template(repo, workspace_id, &s, aliases_map).ok()
|
||||||
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
let s = format!(
|
let s = format!(
|
||||||
r#"
|
r#"
|
||||||
|
@ -1541,7 +1570,7 @@ fn parse_commit_summary_template<'a>(
|
||||||
if(description, description.first_line(), {DESCRIPTION_PLACEHOLDER_TEMPLATE})
|
if(description, description.first_line(), {DESCRIPTION_PLACEHOLDER_TEMPLATE})
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
template_parser::parse_commit_template(repo, workspace_id, &s).unwrap()
|
template_parser::parse_commit_template(repo, workspace_id, &s, aliases_map).unwrap()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -292,6 +292,13 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"template-aliases": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Custom symbols/function aliases that can used in templates",
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"aliases": {
|
"aliases": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "Custom subcommand aliases to be supported by the jj command",
|
"description": "Custom subcommand aliases to be supported by the jj command",
|
||||||
|
|
|
@ -7,3 +7,6 @@ fetch = "origin"
|
||||||
|
|
||||||
[revset-aliases]
|
[revset-aliases]
|
||||||
# Placeholder: added by user
|
# Placeholder: added by user
|
||||||
|
|
||||||
|
[template-aliases]
|
||||||
|
# Placeholder: added by user
|
||||||
|
|
|
@ -938,6 +938,7 @@ pub fn parse_commit_template<'a>(
|
||||||
repo: RepoRef<'a>,
|
repo: RepoRef<'a>,
|
||||||
workspace_id: &WorkspaceId,
|
workspace_id: &WorkspaceId,
|
||||||
template_text: &str,
|
template_text: &str,
|
||||||
|
_aliases_map: &TemplateAliasesMap,
|
||||||
) -> TemplateParseResult<Box<dyn Template<Commit> + 'a>> {
|
) -> TemplateParseResult<Box<dyn Template<Commit> + 'a>> {
|
||||||
let node = parse_template(template_text)?;
|
let node = parse_template(template_text)?;
|
||||||
let expression = build_expression(&node, &|name, span| {
|
let expression = build_expression(&node, &|name, span| {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::common::TestEnvironment;
|
use crate::common::{get_stderr_string, get_stdout_string, TestEnvironment};
|
||||||
|
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
|
||||||
|
@ -388,6 +388,36 @@ fn test_templater_separate_function() {
|
||||||
render(r#"separate(author, "X", "Y", "Z")"#), @"X <>Y <>Z");
|
render(r#"separate(author, "X", "Y", "Z")"#), @"X <>Y <>Z");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_templater_bad_alias_decl() {
|
||||||
|
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");
|
||||||
|
|
||||||
|
// TODO: test alias substitution of parsable one
|
||||||
|
test_env.add_config(
|
||||||
|
r###"
|
||||||
|
[template-aliases]
|
||||||
|
'badfn(a, a)' = 'a'
|
||||||
|
"###,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Invalid declaration should be warned and ignored.
|
||||||
|
let assert = test_env
|
||||||
|
.jj_cmd(&repo_path, &["log", "--no-graph", "-r@-", "-Tcommit_id"])
|
||||||
|
.assert()
|
||||||
|
.success();
|
||||||
|
insta::assert_snapshot!(get_stdout_string(&assert), @"0000000000000000000000000000000000000000");
|
||||||
|
insta::assert_snapshot!(get_stderr_string(&assert), @r###"
|
||||||
|
Failed to load "template-aliases.badfn(a, a)": --> 1:7
|
||||||
|
|
|
||||||
|
1 | badfn(a, a)
|
||||||
|
| ^--^
|
||||||
|
|
|
||||||
|
= Redefinition of function parameter
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
fn get_template_output(
|
fn get_template_output(
|
||||||
test_env: &TestEnvironment,
|
test_env: &TestEnvironment,
|
||||||
repo_path: &Path,
|
repo_path: &Path,
|
||||||
|
|
Loading…
Reference in a new issue