templates: add self.trailers().contains_key(key)

as a simpler and more readable alternative to

    self.trailers().filter(|t| t.key() == "Change-Id")
This commit is contained in:
Gaëtan Lehmann 2025-04-27 23:17:50 +02:00 committed by Gaëtan Lehmann
parent b7489aac81
commit 2c4a0328f9
4 changed files with 54 additions and 13 deletions

View File

@ -74,6 +74,7 @@ use crate::diff_util::DiffStats;
use crate::formatter::Formatter; use crate::formatter::Formatter;
use crate::revset_util; use crate::revset_util;
use crate::template_builder; use crate::template_builder;
use crate::template_builder::expect_plain_text_expression;
use crate::template_builder::merge_fn_map; use crate::template_builder::merge_fn_map;
use crate::template_builder::BuildContext; use crate::template_builder::BuildContext;
use crate::template_builder::CoreTemplateBuildFnTable; use crate::template_builder::CoreTemplateBuildFnTable;
@ -341,15 +342,24 @@ impl<'repo> TemplateLanguage<'repo> for CommitTemplateLanguage<'repo> {
} }
CommitTemplatePropertyKind::TrailerList(property) => { CommitTemplatePropertyKind::TrailerList(property) => {
// TODO: migrate to table? // TODO: migrate to table?
template_builder::build_formattable_list_method( if function.name == "contains_key" {
self, let [key_node] = function.expect_exact_arguments()?;
diagnostics, let key_property =
build_ctx, expect_plain_text_expression(self, diagnostics, build_ctx, key_node)?;
property, let out_property = (property, key_property)
function, .map(|(trailers, key)| trailers.iter().any(|t| t.key == key));
Self::wrap_trailer, Ok(Self::wrap_boolean(out_property))
Self::wrap_trailer_list, } else {
) template_builder::build_formattable_list_method(
self,
diagnostics,
build_ctx,
property,
function,
Self::wrap_trailer,
Self::wrap_trailer_list,
)
}
} }
} }
} }

View File

@ -1709,4 +1709,22 @@ fn test_log_format_trailers() {
"-r@", "-r@",
]); ]);
insta::assert_snapshot!(output, @"Test User <test.user@example.com> I6a6a69649a45c67d3e96a7e5007c110ede34dec5[EOF]"); insta::assert_snapshot!(output, @"Test User <test.user@example.com> I6a6a69649a45c67d3e96a7e5007c110ede34dec5[EOF]");
let output = work_dir.run_jj([
"log",
"--no-graph",
"-T",
r#"self.trailers().contains_key("Signed-off-by")"#,
"-r@",
]);
insta::assert_snapshot!(output, @"true[EOF]");
let output = work_dir.run_jj([
"log",
"--no-graph",
"-T",
r#"self.trailers().contains_key("foo")"#,
"-r@",
]);
insta::assert_snapshot!(output, @"false[EOF]");
} }

View File

@ -240,14 +240,15 @@ is ignored.
### Commit trailers ### Commit trailers
Trailers may be automatically added to the commit description with the You can configure automatic addition of trailers to commit descriptions using
`commit_trailers` template. the `commit_trailers` template. Trailers defined in this template will only be
added if they are not already present in the description.
```toml ```toml
[templates] [templates]
commit_trailers = ''' commit_trailers = '''
"Signed-off-by: " ++ committer ++ "\n" format_signed_off_by_trailer(self)
''' ++ if(!trailers.contains_key("Change-Id"), format_gerrit_change_id_trailer(self))'''
``` ```
Some ready-to-use trailer templates are available for frequently used trailers: Some ready-to-use trailer templates are available for frequently used trailers:
@ -256,6 +257,11 @@ Some ready-to-use trailer templates are available for frequently used trailers:
* `format_gerrit_change_id_trailer(commit)` creates a "Change-Id" trailer * `format_gerrit_change_id_trailer(commit)` creates a "Change-Id" trailer
suitable to be used with Gerrit. It is based Jujutsu's change id. suitable to be used with Gerrit. It is based Jujutsu's change id.
The `trailers.contains_key(key)` method can be used within the template to
conditionally add a trailer if no other trailer with the same key exists.
Existing trailers are also accessible via `commit.trailers()`.
### Diff colors and styles ### Diff colors and styles
In color-words and git diffs, word-level hunks are rendered with underline. You In color-words and git diffs, word-level hunks are rendered with underline. You

View File

@ -248,6 +248,13 @@ defined.
* `.map(|item| expression) -> ListTemplate`: Apply template `expression` * `.map(|item| expression) -> ListTemplate`: Apply template `expression`
to each element. Example: `parents.map(|c| c.commit_id().short())` to each element. Example: `parents.map(|c| c.commit_id().short())`
### List<Trailer> type
The following methods are defined. See also the `List` type.
* `.contains_key(key: Template) -> Boolean`: True if the commit description
contains at least one trailer with the key `key`.
### ListTemplate type ### ListTemplate type
The following methods are defined. See also the `List` type. The following methods are defined. See also the `List` type.