interpret-trailers: add an option to unfold values

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>
This commit is contained in:
Jeff King 2017-08-15 06:23:29 -04:00 коммит произвёл Junio C Hamano
Родитель fdbdb64f49
Коммит 000023961a
5 изменённых файлов: 56 добавлений и 0 удалений

Просмотреть файл

@ -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
-----------------------

Просмотреть файл

@ -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()

Просмотреть файл

@ -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

Просмотреть файл

@ -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));

Просмотреть файл

@ -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}