Skip to content

Commit

Permalink
author/committer templates: add a username method
Browse files Browse the repository at this point in the history
I haven't used a proper email address parser as I'm not really sure if it's
worth the extra dependency and effort -- thoughts?
  • Loading branch information
avamsi committed Feb 11, 2023
1 parent 3744ae4 commit aacdcf6
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `jj new --insert-after` inserts the new commit between the target commit and
its children.

* `author`/`committer` templates now support `.username()`, which leaves out the
domain information of `.email()`.

### Fixed bugs

* When sharing the working copy with a Git repo, we used to forget to export
Expand Down
18 changes: 18 additions & 0 deletions src/template_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,14 @@ fn expect_arguments<const N: usize, const M: usize>(
}
}

fn split_email(email: &str) -> (&str, Option<&str>) {
if let Some((username, rest)) = email.split_once('@') {
(username, Some(rest))
} else {
(email, None)
}
}

fn parse_method_chain<'a, I: 'a>(
input_property: PropertyAndLabels<'a, I>,
method_pairs: Pairs<Rule>,
Expand Down Expand Up @@ -556,6 +564,16 @@ fn parse_signature_method<'a, I: 'a>(
TemplatePropertyFn(|signature: &Signature| signature.email.clone()),
))
}
"username" => {
expect_no_arguments(args_pair)?;
Property::String(chain_properties(
self_property,
TemplatePropertyFn(|signature: &Signature| {
let (username, _) = split_email(&signature.email);
username.to_owned()
}),
))
}
"timestamp" => {
expect_no_arguments(args_pair)?;
Property::Timestamp(chain_properties(
Expand Down
62 changes: 62 additions & 0 deletions tests/test_templater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,68 @@ fn test_templater_string_method() {
insta::assert_snapshot!(render(r#""foo\nbar".first_line()"#), @"foo");
}

#[test]
fn test_templater_signature() {
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");
let render = |template| get_template_output(&test_env, &repo_path, "@", template);

test_env.jj_cmd_success(&repo_path, &["new"]);

insta::assert_snapshot!(render(r#"author"#), @"Test User <[email protected]>");
insta::assert_snapshot!(render(r#"author.name()"#), @"Test User");
insta::assert_snapshot!(render(r#"author.email()"#), @"[email protected]");
insta::assert_snapshot!(render(r#"author.username()"#), @"test.user");

test_env.jj_cmd_success(
&repo_path,
&["--config-toml=user.name='Another Test User'", "new"],
);

insta::assert_snapshot!(render(r#"author"#), @"Another Test User <[email protected]>");
insta::assert_snapshot!(render(r#"author.name()"#), @"Another Test User");
insta::assert_snapshot!(render(r#"author.email()"#), @"[email protected]");
insta::assert_snapshot!(render(r#"author.username()"#), @"test.user");

test_env.jj_cmd_success(
&repo_path,
&[
"--config-toml=user.email='test.user@[email protected]'",
"new",
],
);

insta::assert_snapshot!(render(r#"author"#), @"Test User <test.user@[email protected]>");
insta::assert_snapshot!(render(r#"author.name()"#), @"Test User");
insta::assert_snapshot!(render(r#"author.email()"#), @"test.user@[email protected]");
insta::assert_snapshot!(render(r#"author.username()"#), @"test.user");

test_env.jj_cmd_success(&repo_path, &["--config-toml=user.email='test.user'", "new"]);

insta::assert_snapshot!(render(r#"author"#), @"Test User <test.user>");
insta::assert_snapshot!(render(r#"author.email()"#), @"test.user");
insta::assert_snapshot!(render(r#"author.username()"#), @"test.user");

test_env.jj_cmd_success(
&repo_path,
&[
"--config-toml=user.email='[email protected]'",
"new",
],
);

insta::assert_snapshot!(render(r#"author"#), @"Test User <[email protected]>");
insta::assert_snapshot!(render(r#"author.email()"#), @"[email protected]");
insta::assert_snapshot!(render(r#"author.username()"#), @"test.user+tag");

test_env.jj_cmd_success(&repo_path, &["--config-toml=user.email='x@y'", "new"]);

insta::assert_snapshot!(render(r#"author"#), @"Test User <x@y>");
insta::assert_snapshot!(render(r#"author.email()"#), @"x@y");
insta::assert_snapshot!(render(r#"author.username()"#), @"x");
}

#[test]
fn test_templater_label_function() {
let test_env = TestEnvironment::default();
Expand Down

0 comments on commit aacdcf6

Please sign in to comment.