ref-filter.c: parse trailers arguments with %(contents) atom

The %(contents) atom takes a contents "field" as its argument. Since "trailers" is one of those fields, extend contents_atom_parser to parse "trailers"'s arguments when used through "%(contents)", like: %(contents:trailers:unfold,only) A caveat: trailers_atom_parser expects NULL when no arguments are given (see: `parse_ref_filter_atom`). This is because string_list_split (given a maxsplit of -1) returns a 1-ary string_list* containing the given string if the delimiter could not be found using `strchr`. To simulate this behavior without teaching trailers_atom_parser to accept strings with length zero, conditionally pass NULL to trailers_atom_parser if the arguments portion of the argument to %(contents) is empty. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Taylor Blau committed Oct 1, 2017 at 22:25 UTC 7a5edbdb748f58c0ff3f2a459596ad6ddfda0640
2 files changed +42 -3
ref-filter.c
+4 -3
@@ -212,9 +212,10 @@ static void contents_atom_parser(const struct ref_format *format, struct used_at
212 atom->u.contents.option = C_SIG;
213 else if (!strcmp(arg, "subject"))
214 atom->u.contents.option = C_SUB;
215 - else if (!strcmp(arg, "trailers"))
216 - atom->u.contents.option = C_TRAILERS;
217 - else if (skip_prefix(arg, "lines=", &arg)) {
215 + else if (skip_prefix(arg, "trailers", &arg)) {
216 + skip_prefix(arg, ":", &arg);
217 + trailers_atom_parser(format, atom, *arg ? arg : NULL);
218 + } else if (skip_prefix(arg, "lines=", &arg)) {
219 atom->u.contents.option = C_LINES;
220 if (strtoul_ui(arg, 10, &atom->u.contents.nlines))
221 die(_("positive value expected contents:lines=%s"), arg);
t/t6300-for-each-ref.sh
+38
@@ -655,6 +655,35 @@ test_expect_success '%(trailers:only) and %(trailers:unfold) work together' '
655 test_cmp expect actual
656 '
657
658 +test_expect_success '%(contents:trailers:unfold) unfolds trailers' '
659 + git for-each-ref --format="%(contents:trailers:unfold)" refs/heads/master >actual &&
660 + {
661 + unfold <trailers
662 + echo
663 + } >expect &&
664 + test_cmp expect actual
665 +'
666 +
667 +test_expect_success '%(contents:trailers:only) shows only "key: value" trailers' '
668 + git for-each-ref --format="%(contents:trailers:only)" refs/heads/master >actual &&
669 + {
670 + grep -v patch.description <trailers &&
671 + echo
672 + } >expect &&
673 + test_cmp expect actual
674 +'
675 +
676 +test_expect_success '%(contents:trailers:only) and %(contents:trailers:unfold) work together' '
677 + git for-each-ref --format="%(contents:trailers:only,unfold)" refs/heads/master >actual &&
678 + git for-each-ref --format="%(contents:trailers:unfold,only)" refs/heads/master >reverse &&
679 + test_cmp actual reverse &&
680 + {
681 + grep -v patch.description <trailers | unfold &&
682 + echo
683 + } >expect &&
684 + test_cmp expect actual
685 +'
686 +
687 test_expect_success '%(trailers) rejects unknown trailers arguments' '
688 # error message cannot be checked under i18n
689 cat >expect <<-EOF &&
@@ -664,6 +693,15 @@ test_expect_success '%(trailers) rejects unknown trailers arguments' '
693 test_i18ncmp expect actual
694 '
695
696 +test_expect_success '%(contents:trailers) rejects unknown trailers arguments' '
697 + # error message cannot be checked under i18n
698 + cat >expect <<-EOF &&
699 + fatal: unknown %(trailers) argument: unsupported
700 + EOF
701 + test_must_fail git for-each-ref --format="%(contents:trailers:unsupported)" 2>actual &&
702 + test_i18ncmp expect actual
703 +'
704 +
705 test_expect_success 'basic atom: head contents:trailers' '
706 git for-each-ref --format="%(contents:trailers)" refs/heads/master >actual &&
707 sanitize_pgp <actual >actual.clean &&