]> git.ipfire.org Git - thirdparty/git.git/commitdiff
interpret-trailers: add an option to unfold values
authorJeff King <peff@peff.net>
Tue, 15 Aug 2017 10:23:29 +0000 (06:23 -0400)
committerJunio C Hamano <gitster@pobox.com>
Tue, 15 Aug 2017 18:13:58 +0000 (11:13 -0700)
The point of "--only-trailers" is to give a caller an output
that's easy for them to parse. Getting rid of the
non-trailer material helps, but we still may see more
complicated syntax like whitespace continuation. Let's add
an option to unfold any continuation, giving the output as a
single "key: value" line per trailer.

As a bonus, this could be used even without --only-trailers
to clean up unusual formatting in the incoming data.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-interpret-trailers.txt
builtin/interpret-trailers.c
t/t7513-interpret-trailers.sh
trailer.c
trailer.h

index 7cc43b0e3e11535ae271d8fb17011b1155d479cf..be948e8028e4c9d680f1cc7695324c56c60c782a 100644 (file)
@@ -88,6 +88,10 @@ OPTIONS
        from the command-line or by following configured `trailer.*`
        rules.
 
+--unfold::
+       Remove any whitespace-continuation in trailers, so that each
+       trailer appears on a line by itself with its full content.
+
 CONFIGURATION VARIABLES
 -----------------------
 
index 2d90e0e4808144e3fcc016b0f6a9366b6ab66a8d..922c3bad6388d5dd64ca68f3d22b2ad75fa4bfb2 100644 (file)
@@ -26,6 +26,7 @@ int cmd_interpret_trailers(int argc, const char **argv, const char *prefix)
                OPT_BOOL(0, "trim-empty", &opts.trim_empty, N_("trim empty trailers")),
                OPT_BOOL(0, "only-trailers", &opts.only_trailers, N_("output only the trailers")),
                OPT_BOOL(0, "only-input", &opts.only_input, N_("do not apply config rules")),
+               OPT_BOOL(0, "unfold", &opts.unfold, N_("join whitespace-continued values")),
                OPT_STRING_LIST(0, "trailer", &trailers, N_("trailer"),
                                N_("trailer(s) to add")),
                OPT_END()
index 94b6c52473e3a9862d7b4107796b45cbd6cf755d..baf2feba9858de5591bfd1f7c3ba44bd356dd8ea 100755 (executable)
@@ -1330,4 +1330,25 @@ test_expect_success 'only input' '
        test_cmp expected actual
 '
 
+test_expect_success 'unfold' '
+       cat >expected <<-\EOF &&
+               foo: continued across several lines
+       EOF
+       # pass through tr to make leading and trailing whitespace more obvious
+       tr _ " " <<-\EOF |
+               my subject
+
+               my body
+
+               foo:_
+               __continued
+               ___across
+               ____several
+               _____lines
+               ___
+       EOF
+       git interpret-trailers --only-trailers --only-input --unfold >actual &&
+       test_cmp expected actual
+'
+
 test_done
index 847417ef89906694aaa3b27809d2a50b6afef789..e63f432947441a748d32ac7166c881879a7d2608 100644 (file)
--- a/trailer.c
+++ b/trailer.c
@@ -886,6 +886,33 @@ static int ends_with_blank_line(const char *buf, size_t len)
        return is_blank_line(buf + ll);
 }
 
+static void unfold_value(struct strbuf *val)
+{
+       struct strbuf out = STRBUF_INIT;
+       size_t i;
+
+       strbuf_grow(&out, val->len);
+       i = 0;
+       while (i < val->len) {
+               char c = val->buf[i++];
+               if (c == '\n') {
+                       /* Collapse continuation down to a single space. */
+                       while (i < val->len && isspace(val->buf[i]))
+                               i++;
+                       strbuf_addch(&out, ' ');
+               } else {
+                       strbuf_addch(&out, c);
+               }
+       }
+
+       /* Empty lines may have left us with whitespace cruft at the edges */
+       strbuf_trim(&out);
+
+       /* output goes back to val as if we modified it in-place */
+       strbuf_swap(&out, val);
+       strbuf_release(&out);
+}
+
 static int process_input_file(FILE *outfile,
                              const char *str,
                              struct list_head *head,
@@ -914,6 +941,8 @@ static int process_input_file(FILE *outfile,
                if (separator_pos >= 1) {
                        parse_trailer(&tok, &val, NULL, trailer,
                                      separator_pos);
+                       if (opts->unfold)
+                               unfold_value(&val);
                        add_trailer_item(head,
                                         strbuf_detach(&tok, NULL),
                                         strbuf_detach(&val, NULL));
index 76c3b571bf66f65a4cf86a4aaa08393e31136b70..194f85a102383d2d7a90ed1228034b8d99cf513f 100644 (file)
--- a/trailer.h
+++ b/trailer.h
@@ -27,6 +27,7 @@ struct process_trailer_options {
        int trim_empty;
        int only_trailers;
        int only_input;
+       int unfold;
 };
 
 #define PROCESS_TRAILER_OPTIONS_INIT {0}