diff --git a/cli/src/commit_templater.rs b/cli/src/commit_templater.rs index 1222f6cfc2..9d9384fc87 100644 --- a/cli/src/commit_templater.rs +++ b/cli/src/commit_templater.rs @@ -14,7 +14,7 @@ use std::any::Any; use std::cmp::max; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::io; use std::rc::Rc; @@ -399,6 +399,7 @@ pub struct CommitKeywordCache<'repo> { // Build index lazily, and Rc to get away from &self lifetime. branches_index: OnceCell>, tags_index: OnceCell>, + topics_index: OnceCell>, git_refs_index: OnceCell>, is_immutable_fn: OnceCell>>, } @@ -414,6 +415,11 @@ impl<'repo> CommitKeywordCache<'repo> { .get_or_init(|| Rc::new(build_ref_names_index(repo.view().tags()))) } + pub fn topics_index(&self, repo: &dyn Repo) -> &Rc { + self.topics_index + .get_or_init(|| Rc::new(build_topic_index(repo.view().topics().iter()))) + } + pub fn git_refs_index(&self, repo: &dyn Repo) -> &Rc { self.git_refs_index .get_or_init(|| Rc::new(build_ref_names_index(repo.view().git_refs()))) @@ -568,6 +574,12 @@ fn builtin_commit_methods<'repo>() -> CommitTemplateBuildMethodFnMap<'repo, Comm let out_property = self_property.map(move |commit| index.get(commit.id()).to_vec()); Ok(L::wrap_ref_name_list(out_property)) }); + map.insert("topics", |language, _build_ctx, self_property, function| { + template_parser::expect_no_arguments(function)?; + let index = language.keyword_cache.topics_index(language.repo).clone(); + let out_property = self_property.map(move |commit| index.get(commit.id()).to_vec()); + Ok(L::wrap_ref_name_list(out_property)) + }); map.insert( "git_refs", |language, _build_ctx, self_property, function| { @@ -918,6 +930,21 @@ fn build_branches_index(repo: &dyn Repo) -> RefNamesIndex { index } +fn build_topic_index<'a, T>(topics: T) -> RefNamesIndex +where + T: Iterator)>, +{ + let mut index = RefNamesIndex::default(); + for (topic, commits) in topics { + // TODO: single refname for all commits + for id in commits { + let ref_name = RefName::local_only(topic, RefTarget::normal(id.clone())); + index.insert([id], ref_name); + } + } + index +} + fn build_ref_names_index<'a>( ref_pairs: impl IntoIterator, ) -> RefNamesIndex {