ref-filter: use pretty.c logic for trailers
Now, ref-filter is using pretty.c logic for setting trailer options. New to ref-filter: :key=<K> - only show trailers with specified key. :valueonly[=val] - only show the value part. :separator=<SEP> - inserted between trailer lines. :key_value_separator=<SEP> - inserted between key and value in trailer lines Enhancement to existing options(now can take value and its optional): :only[=val] :unfold[=val] 'val' can be: true, on, yes or false, off, no. Mentored-by: Christian Couder <chriscool@tuxfamily.org> Mentored-by: Heba Waly <heba.waly@gmail.com> Signed-off-by: Hariom Verma <hariom18599@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Hariom Verma committed
Feb 13, 2021 at 01:52 UTC
ee82a487f68a7c86551fb59f6176812d63be61b6
3 files changed
+118
-21
Documentation/git-for-each-ref.txt
+3
-5
@@ -260,11 +260,9 @@ contents:lines=N::
260
The first `N` lines of the message.
261
262
Additionally, the trailers as interpreted by linkgit:git-interpret-trailers[1]
263
-are obtained as `trailers` (or by using the historical alias
264
-`contents:trailers`). Non-trailer lines from the trailer block can be omitted
265
-with `trailers:only`. Whitespace-continuations can be removed from trailers so
266
-that each trailer appears on a line by itself with its full content with
267
-`trailers:unfold`. Both can be used together as `trailers:unfold,only`.
263
+are obtained as `trailers[:options]` (or by using the historical alias
264
+`contents:trailers[:options]`). For valid [:option] values see `trailers`
265
+section of linkgit:git-log[1].
266
267
For sorting purposes, fields with numeric values sort in numeric order
268
(`objectsize`, `authordate`, `committerdate`, `creatordate`, `taggerdate`).
ref-filter.c
+20
-16
@@ -67,6 +67,12 @@ struct refname_atom {
67
int lstrip, rstrip;
68
};
69
70
+static struct ref_trailer_buf {
71
+ struct string_list filter_list;
72
+ struct strbuf sepbuf;
73
+ struct strbuf kvsepbuf;
74
+} ref_trailer_buf = {STRING_LIST_INIT_NODUP, STRBUF_INIT, STRBUF_INIT};
75
+
76
static struct expand_data {
77
struct object_id oid;
78
enum object_type type;
@@ -313,28 +319,26 @@ static int subject_atom_parser(const struct ref_format *format, struct used_atom
319
static int trailers_atom_parser(const struct ref_format *format, struct used_atom *atom,
320
const char *arg, struct strbuf *err)
321
{
316
- struct string_list params = STRING_LIST_INIT_DUP;
317
- int i;
318
-
322
atom->u.contents.trailer_opts.no_divider = 1;
323
324
if (arg) {
322
- string_list_split(¶ms, arg, ',', -1);
323
- for (i = 0; i < params.nr; i++) {
324
- const char *s = params.items[i].string;
325
- if (!strcmp(s, "unfold"))
326
- atom->u.contents.trailer_opts.unfold = 1;
327
- else if (!strcmp(s, "only"))
328
- atom->u.contents.trailer_opts.only_trailers = 1;
329
- else {
330
- strbuf_addf(err, _("unknown %%(trailers) argument: %s"), s);
331
- string_list_clear(¶ms, 0);
332
- return -1;
333
- }
325
+ const char *argbuf = xstrfmt("%s)", arg);
326
+ char *invalid_arg = NULL;
327
+
328
+ if (format_set_trailers_options(&atom->u.contents.trailer_opts,
329
+ &ref_trailer_buf.filter_list,
330
+ &ref_trailer_buf.sepbuf,
331
+ &ref_trailer_buf.kvsepbuf,
332
+ &argbuf, &invalid_arg)) {
333
+ if (!invalid_arg)
334
+ strbuf_addf(err, _("expected %%(trailers:key=<value>)"));
335
+ else
336
+ strbuf_addf(err, _("unknown %%(trailers) argument: %s"), invalid_arg);
337
+ free((char *)invalid_arg);
338
+ return -1;
339
}
340
}
341
atom->u.contents.option = C_TRAILERS;
337
- string_list_clear(¶ms, 0);
342
return 0;
343
}
344
t/t6300-for-each-ref.sh
+95
@@ -837,6 +837,24 @@ test_trailer_option '%(trailers:only) shows only "key: value" trailers' \
837
838
EOF
839
840
+test_trailer_option '%(trailers:only=no,only=true) shows only "key: value" trailers' \
841
+ 'trailers:only=no,only=true' <<-EOF
842
+ $(grep -v patch.description <trailers)
843
+
844
+ EOF
845
+
846
+test_trailer_option '%(trailers:only=yes) shows only "key: value" trailers' \
847
+ 'trailers:only=yes' <<-EOF
848
+ $(grep -v patch.description <trailers)
849
+
850
+ EOF
851
+
852
+test_trailer_option '%(trailers:only=no) shows all trailers' \
853
+ 'trailers:only=no' <<-EOF
854
+ $(cat trailers)
855
+
856
+ EOF
857
+
858
test_trailer_option '%(trailers:only) and %(trailers:unfold) work together' \
859
'trailers:only,unfold' <<-EOF
860
$(grep -v patch.description <trailers | unfold)
@@ -849,6 +867,78 @@ test_trailer_option '%(trailers:unfold) and %(trailers:only) work together' \
867
868
EOF
869
870
+test_trailer_option '%(trailers:key=foo) shows that trailer' \
871
+ 'trailers:key=Signed-off-by' <<-EOF
872
+ Signed-off-by: A U Thor <author@example.com>
873
+
874
+ EOF
875
+
876
+test_trailer_option '%(trailers:key=foo) is case insensitive' \
877
+ 'trailers:key=SiGned-oFf-bY' <<-EOF
878
+ Signed-off-by: A U Thor <author@example.com>
879
+
880
+ EOF
881
+
882
+test_trailer_option '%(trailers:key=foo:) trailing colon also works' \
883
+ 'trailers:key=Signed-off-by:' <<-EOF
884
+ Signed-off-by: A U Thor <author@example.com>
885
+
886
+ EOF
887
+
888
+test_trailer_option '%(trailers:key=foo) multiple keys' \
889
+ 'trailers:key=Reviewed-by:,key=Signed-off-by' <<-EOF
890
+ Reviewed-by: A U Thor <author@example.com>
891
+ Signed-off-by: A U Thor <author@example.com>
892
+
893
+ EOF
894
+
895
+test_trailer_option '%(trailers:key=nonexistent) becomes empty' \
896
+ 'trailers:key=Shined-off-by:' <<-EOF
897
+
898
+ EOF
899
+
900
+test_trailer_option '%(trailers:key=foo) handles multiple lines even if folded' \
901
+ 'trailers:key=Acked-by' <<-EOF
902
+ $(grep -v patch.description <trailers | grep -v Signed-off-by | grep -v Reviewed-by)
903
+
904
+ EOF
905
+
906
+test_trailer_option '%(trailers:key=foo,unfold) properly unfolds' \
907
+ 'trailers:key=Signed-Off-by,unfold' <<-EOF
908
+ $(unfold <trailers | grep Signed-off-by)
909
+
910
+ EOF
911
+
912
+test_trailer_option '%(trailers:key=foo,only=no) also includes nontrailer lines' \
913
+ 'trailers:key=Signed-off-by,only=no' <<-EOF
914
+ Signed-off-by: A U Thor <author@example.com>
915
+ $(grep patch.description <trailers)
916
+
917
+ EOF
918
+
919
+test_trailer_option '%(trailers:key=foo,valueonly) shows only value' \
920
+ 'trailers:key=Signed-off-by,valueonly' <<-EOF
921
+ A U Thor <author@example.com>
922
+
923
+ EOF
924
+
925
+test_trailer_option '%(trailers:separator) changes separator' \
926
+ 'trailers:separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF
927
+ Reviewed-by: A U Thor <author@example.com>,Signed-off-by: A U Thor <author@example.com>
928
+ EOF
929
+
930
+test_trailer_option '%(trailers:key_value_separator) changes key-value separator' \
931
+ 'trailers:key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF
932
+ Reviewed-by,A U Thor <author@example.com>
933
+ Signed-off-by,A U Thor <author@example.com>
934
+
935
+ EOF
936
+
937
+test_trailer_option '%(trailers:separator,key_value_separator) changes both separators' \
938
+ 'trailers:separator=%x2C,key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF
939
+ Reviewed-by,A U Thor <author@example.com>,Signed-off-by,A U Thor <author@example.com>
940
+ EOF
941
+
942
test_failing_trailer_option () {
943
title=$1 option=$2
944
cat >expect
@@ -866,6 +956,11 @@ test_failing_trailer_option '%(trailers) rejects unknown trailers arguments' \
956
fatal: unknown %(trailers) argument: unsupported
957
EOF
958
959
+test_failing_trailer_option '%(trailers:key) without value is error' \
960
+ 'trailers:key' <<-\EOF
961
+ fatal: expected %(trailers:key=<value>)
962
+ EOF
963
+
964
test_expect_success 'if arguments, %(contents:trailers) shows error if colon is missing' '
965
cat >expect <<-EOF &&
966
fatal: unrecognized %(contents) argument: trailersonly