forked from mirrors/jj
templater: migrate trivial commit keywords to closure wrapper
Perhaps, non-trivial keywords can be extracted to free functions, and both parsing and property functions can be eventually moved to a commit templater module?
This commit is contained in:
parent
846be15132
commit
6da43734cb
2 changed files with 32 additions and 113 deletions
|
@ -17,20 +17,19 @@ use jujutsu_lib::backend::{Signature, Timestamp};
|
|||
use jujutsu_lib::commit::Commit;
|
||||
use jujutsu_lib::op_store::WorkspaceId;
|
||||
use jujutsu_lib::repo::RepoRef;
|
||||
use jujutsu_lib::rewrite;
|
||||
use pest::iterators::{Pair, Pairs};
|
||||
use pest::Parser;
|
||||
use pest_derive::Parser;
|
||||
|
||||
use crate::formatter::PlainTextFormatter;
|
||||
use crate::templater::{
|
||||
AuthorProperty, BranchProperty, ChangeIdProperty, CommitIdProperty, CommitOrChangeId,
|
||||
CommitterProperty, ConditionalTemplate, ConflictProperty, DescriptionProperty,
|
||||
DivergentProperty, DynamicLabelTemplate, EmptyProperty, FormattablePropertyTemplate,
|
||||
GitHeadProperty, GitRefsProperty, IdWithHighlightedPrefix, IsWorkingCopyProperty,
|
||||
LabelTemplate, ListTemplate, Literal, TagProperty, Template, TemplateFunction,
|
||||
TemplateProperty, TemplatePropertyFn, WorkingCopiesProperty,
|
||||
BranchProperty, CommitOrChangeId, ConditionalTemplate, DynamicLabelTemplate,
|
||||
FormattablePropertyTemplate, GitHeadProperty, GitRefsProperty, IdWithHighlightedPrefix,
|
||||
IsWorkingCopyProperty, LabelTemplate, ListTemplate, Literal, TagProperty, Template,
|
||||
TemplateFunction, TemplateProperty, TemplatePropertyFn, WorkingCopiesProperty,
|
||||
};
|
||||
use crate::time_util;
|
||||
use crate::{cli_util, time_util};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "template.pest"]
|
||||
|
@ -258,13 +257,24 @@ fn parse_commit_keyword<'a>(
|
|||
workspace_id: &WorkspaceId,
|
||||
pair: Pair<Rule>,
|
||||
) -> PropertyAndLabels<'a, Commit> {
|
||||
fn wrap_fn<'a, O>(
|
||||
f: impl Fn(&Commit) -> O + 'a,
|
||||
) -> Box<dyn TemplateProperty<Commit, Output = O> + 'a> {
|
||||
Box::new(TemplatePropertyFn(f))
|
||||
}
|
||||
assert_eq!(pair.as_rule(), Rule::identifier);
|
||||
let property = match pair.as_str() {
|
||||
"description" => Property::String(Box::new(DescriptionProperty)),
|
||||
"change_id" => Property::CommitOrChangeId(Box::new(ChangeIdProperty { repo })),
|
||||
"commit_id" => Property::CommitOrChangeId(Box::new(CommitIdProperty { repo })),
|
||||
"author" => Property::Signature(Box::new(AuthorProperty)),
|
||||
"committer" => Property::Signature(Box::new(CommitterProperty)),
|
||||
"description" => Property::String(wrap_fn(|commit| {
|
||||
cli_util::complete_newline(commit.description())
|
||||
})),
|
||||
"change_id" => Property::CommitOrChangeId(wrap_fn(move |commit| {
|
||||
CommitOrChangeId::new(repo, commit.change_id())
|
||||
})),
|
||||
"commit_id" => Property::CommitOrChangeId(wrap_fn(move |commit| {
|
||||
CommitOrChangeId::new(repo, commit.id())
|
||||
})),
|
||||
"author" => Property::Signature(wrap_fn(|commit| commit.author().clone())),
|
||||
"committer" => Property::Signature(wrap_fn(|commit| commit.committer().clone())),
|
||||
"working_copies" => Property::String(Box::new(WorkingCopiesProperty { repo })),
|
||||
"current_working_copy" => Property::Boolean(Box::new(IsWorkingCopyProperty {
|
||||
repo,
|
||||
|
@ -274,9 +284,15 @@ fn parse_commit_keyword<'a>(
|
|||
"tags" => Property::String(Box::new(TagProperty { repo })),
|
||||
"git_refs" => Property::String(Box::new(GitRefsProperty { repo })),
|
||||
"git_head" => Property::String(Box::new(GitHeadProperty::new(repo))),
|
||||
"divergent" => Property::Boolean(Box::new(DivergentProperty::new(repo))),
|
||||
"conflict" => Property::Boolean(Box::new(ConflictProperty)),
|
||||
"empty" => Property::Boolean(Box::new(EmptyProperty { repo })),
|
||||
"divergent" => Property::Boolean(wrap_fn(move |commit| {
|
||||
// The given commit could be hidden in e.g. obslog.
|
||||
let maybe_entries = repo.resolve_change_id(commit.change_id());
|
||||
maybe_entries.map_or(0, |entries| entries.len()) > 1
|
||||
})),
|
||||
"conflict" => Property::Boolean(wrap_fn(|commit| commit.tree().has_conflict())),
|
||||
"empty" => Property::Boolean(wrap_fn(move |commit| {
|
||||
commit.tree().id() == rewrite::merge_commit_trees(repo, &commit.parents()).id()
|
||||
})),
|
||||
name => panic!("unexpected identifier: {name}"),
|
||||
};
|
||||
PropertyAndLabels(property, vec![pair.as_str().to_string()])
|
||||
|
|
|
@ -20,10 +20,9 @@ use jujutsu_lib::backend::{ObjectId, Signature, Timestamp};
|
|||
use jujutsu_lib::commit::Commit;
|
||||
use jujutsu_lib::op_store::WorkspaceId;
|
||||
use jujutsu_lib::repo::RepoRef;
|
||||
use jujutsu_lib::rewrite::merge_commit_trees;
|
||||
|
||||
use crate::formatter::Formatter;
|
||||
use crate::{cli_util, time_util};
|
||||
use crate::time_util;
|
||||
|
||||
pub trait Template<C> {
|
||||
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()>;
|
||||
|
@ -205,36 +204,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub struct DescriptionProperty;
|
||||
|
||||
impl TemplateProperty<Commit> for DescriptionProperty {
|
||||
type Output = String;
|
||||
|
||||
fn extract(&self, context: &Commit) -> Self::Output {
|
||||
cli_util::complete_newline(context.description())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AuthorProperty;
|
||||
|
||||
impl TemplateProperty<Commit> for AuthorProperty {
|
||||
type Output = Signature;
|
||||
|
||||
fn extract(&self, context: &Commit) -> Self::Output {
|
||||
context.author().clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CommitterProperty;
|
||||
|
||||
impl TemplateProperty<Commit> for CommitterProperty {
|
||||
type Output = Signature;
|
||||
|
||||
fn extract(&self, context: &Commit) -> Self::Output {
|
||||
context.committer().clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WorkingCopiesProperty<'a> {
|
||||
pub repo: RepoRef<'a>,
|
||||
}
|
||||
|
@ -383,36 +352,6 @@ impl TemplateProperty<Commit> for GitHeadProperty<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct DivergentProperty<'a> {
|
||||
repo: RepoRef<'a>,
|
||||
}
|
||||
|
||||
impl<'a> DivergentProperty<'a> {
|
||||
pub fn new(repo: RepoRef<'a>) -> Self {
|
||||
DivergentProperty { repo }
|
||||
}
|
||||
}
|
||||
|
||||
impl TemplateProperty<Commit> for DivergentProperty<'_> {
|
||||
type Output = bool;
|
||||
|
||||
fn extract(&self, context: &Commit) -> Self::Output {
|
||||
// The given commit could be hidden in e.g. obslog.
|
||||
let maybe_entries = self.repo.resolve_change_id(context.change_id());
|
||||
maybe_entries.map_or(0, |entries| entries.len()) > 1
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConflictProperty;
|
||||
|
||||
impl TemplateProperty<Commit> for ConflictProperty {
|
||||
type Output = bool;
|
||||
|
||||
fn extract(&self, context: &Commit) -> Self::Output {
|
||||
context.tree().has_conflict()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConditionalTemplate<P, T, U> {
|
||||
pub condition: P,
|
||||
pub true_template: T,
|
||||
|
@ -599,39 +538,3 @@ impl Template<()> for IdWithHighlightedPrefix {
|
|||
formatter.with_label("rest", |fmt| fmt.write_str(&self.rest))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CommitIdProperty<'a> {
|
||||
pub repo: RepoRef<'a>,
|
||||
}
|
||||
|
||||
impl<'a> TemplateProperty<Commit> for CommitIdProperty<'a> {
|
||||
type Output = CommitOrChangeId<'a>;
|
||||
|
||||
fn extract(&self, context: &Commit) -> Self::Output {
|
||||
CommitOrChangeId::new(self.repo, context.id())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChangeIdProperty<'a> {
|
||||
pub repo: RepoRef<'a>,
|
||||
}
|
||||
|
||||
impl<'a> TemplateProperty<Commit> for ChangeIdProperty<'a> {
|
||||
type Output = CommitOrChangeId<'a>;
|
||||
|
||||
fn extract(&self, context: &Commit) -> Self::Output {
|
||||
CommitOrChangeId::new(self.repo, context.change_id())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EmptyProperty<'a> {
|
||||
pub repo: RepoRef<'a>,
|
||||
}
|
||||
|
||||
impl TemplateProperty<Commit> for EmptyProperty<'_> {
|
||||
type Output = bool;
|
||||
|
||||
fn extract(&self, context: &Commit) -> Self::Output {
|
||||
context.tree().id() == merge_commit_trees(self.repo, &context.parents()).id()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue