git@vger.kernel.org mailing list mirror (one of many)
 help / Atom feed
From: Anders Waldenborg <anders@0x63.nu>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>, Jeff King <peff@peff.net>,
	Olga Telezhnaya <olyatelezhnaya@gmail.com>,
	Anders Waldenborg <anders@0x63.nu>
Subject: [PATCH v4 7/7] pretty: add support for separator option in %(trailers)
Date: Sat,  8 Dec 2018 17:36:47 +0100
Message-ID: <20181208163647.19538-8-anders@0x63.nu> (raw)
In-Reply-To: <20181208163647.19538-1-anders@0x63.nu>

By default trailer lines are terminated by linebreaks ('\n'). By
specifying the new 'separator' option they will instead be separated by
user provided string and have separator semantics rather than terminator
semantics. The separator string can contain the literal formatting codes
%n and %xNN allowing it to be things that are otherwise hard to type
such as %x00, or comma and end-parenthesis which would break parsing.

E.g:
 $ git log --pretty='%(trailers:key=Reviewed-by,valueonly,separator=%x00)'

Signed-off-by: Anders Waldenborg <anders@0x63.nu>
---
 Documentation/pretty-formats.txt |  9 ++++++++
 pretty.c                         | 10 +++++++++
 t/t4205-log-pretty-formats.sh    | 36 ++++++++++++++++++++++++++++++++
 trailer.c                        | 15 +++++++++++--
 trailer.h                        |  1 +
 5 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index a920dd15b1..ce087dee80 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -239,6 +239,15 @@ endif::git-rev-list[]
    `false`, `off`, `no` to show the non-trailer lines. If option is
    given without value it is enabled. If given multiple times the last
    value is used.
+** 'separator=<SEP>': specify a separator inserted between trailer
+   lines. When this option is not given each trailer line is
+   terminated with a line feed character. The string SEP may contain
+   the literal formatting codes described above. To use comma as
+   separator one must use `%x2C` as it would otherwise be parsed as
+   next option. If separator option is given multiple times only the
+   last one is used. E.g., `%(trailers:key=Ticket,separator=%x2C )`
+   shows all trailer lines whose key is "Ticket" separated by a comma
+   and a space.
 ** 'unfold[=val]': make it behave as if interpret-trailer's `--unfold`
    option was given. In same way as to for `only` it can be followed
    by an equal sign and explicit value. E.g.,
diff --git a/pretty.c b/pretty.c
index 50d0b5830d..c7609493ee 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1357,6 +1357,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
 	if (skip_prefix(placeholder, "(trailers", &arg)) {
 		struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
 		struct string_list filter_list = STRING_LIST_INIT_NODUP;
+		struct strbuf sepbuf = STRBUF_INIT;
 		size_t ret = 0;
 
 		opts.no_divider = 1;
@@ -1376,6 +1377,14 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
 					opts.filter = format_trailer_match_cb;
 					opts.filter_data = &filter_list;
 					opts.only_trailers = 1;
+				} else if (match_placeholder_arg_value(arg, "separator", &arg, &argval, &arglen)) {
+					char *fmt;
+
+					strbuf_reset(&sepbuf);
+					fmt = xstrndup(argval, arglen);
+					strbuf_expand(&sepbuf, fmt, strbuf_expand_literal_cb, NULL);
+					free(fmt);
+					opts.separator = &sepbuf;
 				} else if (!match_placeholder_bool_arg(arg, "only", &arg, &opts.only_trailers) &&
 					   !match_placeholder_bool_arg(arg, "unfold", &arg, &opts.unfold) &&
 					   !match_placeholder_bool_arg(arg, "valueonly", &arg, &opts.value_only))
@@ -1387,6 +1396,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
 			ret = arg - placeholder + 1;
 		}
 		string_list_clear (&filter_list, 0);
+		strbuf_release(&sepbuf);
 		return ret;
 	}
 
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index 22336c5485..282369dac0 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -673,6 +673,42 @@ test_expect_success '%(trailers:key=foo,valueonly) shows only value' '
 	test_cmp expect actual
 '
 
+test_expect_success 'pretty format %(trailers:separator) changes separator' '
+	git log --no-walk --pretty=format:"X%(trailers:separator=%x00,unfold)X" >actual &&
+	printf "XSigned-off-by: A U Thor <author@example.com>\0Acked-by: A U Thor <author@example.com>\0[ v2 updated patch description ]\0Signed-off-by: A U Thor <author@example.com>X" >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'pretty format %(trailers) combining separator/key/valueonly' '
+	git commit --allow-empty -F - <<-\EOF &&
+	Important fix
+
+	The fix is explained here
+
+	Closes: #1234
+	EOF
+
+	git commit --allow-empty -F - <<-\EOF &&
+	Another fix
+
+	The fix is explained here
+
+	Closes: #567
+	Closes: #890
+	EOF
+
+	git commit --allow-empty -F - <<-\EOF &&
+	Does not close any tickets
+	EOF
+
+	git log --pretty="%s% (trailers:separator=%x2c%x20,key=Closes,valueonly)" HEAD~3.. >actual &&
+	test_write_lines \
+		"Does not close any tickets" \
+		"Another fix #567, #890" \
+		"Important fix #1234" >expect &&
+	test_cmp expect actual
+'
+
 test_expect_success 'trailer parsing not fooled by --- line' '
 	git commit --allow-empty -F - <<-\EOF &&
 	this is the subject
diff --git a/trailer.c b/trailer.c
index d0d9e91631..0c414f2fed 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1129,10 +1129,11 @@ static void format_trailer_info(struct strbuf *out,
 				const struct trailer_info *info,
 				const struct process_trailer_options *opts)
 {
+	size_t origlen = out->len;
 	size_t i;
 
 	/* If we want the whole block untouched, we can take the fast path. */
-	if (!opts->only_trailers && !opts->unfold && !opts->filter) {
+	if (!opts->only_trailers && !opts->unfold && !opts->filter && !opts->separator) {
 		strbuf_add(out, info->trailer_start,
 			   info->trailer_end - info->trailer_start);
 		return;
@@ -1150,16 +1151,26 @@ static void format_trailer_info(struct strbuf *out,
 			if (!opts->filter || opts->filter(&tok, opts->filter_data)) {
 				if (opts->unfold)
 					unfold_value(&val);
+
+				if (opts->separator && out->len != origlen)
+					strbuf_addbuf(out, opts->separator);
 				if (!opts->value_only)
 					strbuf_addf(out, "%s: ", tok.buf);
 				strbuf_addbuf(out, &val);
-				strbuf_addch(out, '\n');
+				if (!opts->separator)
+					strbuf_addch(out, '\n');
 			}
 			strbuf_release(&tok);
 			strbuf_release(&val);
 
 		} else if (!opts->only_trailers) {
+			if (opts->separator && out->len != origlen) {
+				strbuf_addbuf(out, opts->separator);
+			}
 			strbuf_addstr(out, trailer);
+			if (opts->separator) {
+				strbuf_rtrim(out);
+			}
 		}
 	}
 
diff --git a/trailer.h b/trailer.h
index 06d417fe93..203acf4ee1 100644
--- a/trailer.h
+++ b/trailer.h
@@ -73,6 +73,7 @@ struct process_trailer_options {
 	int unfold;
 	int no_divider;
 	int value_only;
+	const struct strbuf *separator;
 	int (*filter)(const struct strbuf *, void *);
 	void *filter_data;
 };
-- 
2.17.1


      parent reply index

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-28 12:50 [PATCH] pretty: Add %(trailer:X) to display single trailer Anders Waldenborg
2018-10-29  4:49 ` Junio C Hamano
2018-10-29 14:14 ` Jeff King
2018-10-29 17:05   ` Anders Waldenborg
2018-10-31 20:27     ` Jeff King
2018-10-31 23:01       ` Anders Waldenborg
2018-11-01 18:42         ` Jeff King
2018-11-04 15:22 ` [PATCH v2 0/5] %(trailers) improvements in pretty format Anders Waldenborg
2018-11-04 15:22   ` [PATCH v2 1/5] pretty: single return path in %(trailers) handling Anders Waldenborg
2018-11-04 15:22   ` [PATCH v2 2/5] pretty: allow showing specific trailers Anders Waldenborg
2018-11-04 18:14     ` Eric Sunshine
2018-11-05  3:48       ` Junio C Hamano
2018-11-05  3:52         ` Eric Sunshine
2018-11-05  8:26       ` Anders Waldenborg
2018-11-05  9:00         ` Eric Sunshine
2018-11-05  5:14     ` Junio C Hamano
2018-11-04 15:22   ` [PATCH v2 3/5] pretty: add support for "nokey" option in %(trailers) Anders Waldenborg
2018-11-04 15:22   ` [PATCH v2 4/5] pretty: extract fundamental placeholders to separate function Anders Waldenborg
2018-11-05  2:06     ` Junio C Hamano
2018-11-05  8:32       ` Anders Waldenborg
2018-11-06  1:46         ` Junio C Hamano
2018-11-04 15:22   ` [PATCH v2 5/5] pretty: add support for separator option in %(trailers) Anders Waldenborg
2018-11-05  2:10     ` Junio C Hamano
2018-11-05 18:24       ` Anders Waldenborg
2018-11-06  1:48         ` Junio C Hamano
2018-11-05  5:18     ` Junio C Hamano
2018-11-04 17:40   ` [PATCH v2 0/5] %(trailers) improvements in pretty format Eric Sunshine
2018-11-05  7:09     ` Anders Waldenborg
2018-11-18 11:44   ` [PATCH v3 " Anders Waldenborg
2018-11-18 11:44     ` [PATCH v3 1/5] pretty: single return path in %(trailers) handling Anders Waldenborg
2018-11-18 11:44     ` [PATCH v3 2/5] pretty: allow showing specific trailers Anders Waldenborg
2018-11-20  5:45       ` Junio C Hamano
2018-11-20  5:59       ` Junio C Hamano
2018-11-25 23:02         ` Anders Waldenborg
2018-11-26  3:13           ` Junio C Hamano
2018-11-26  6:56             ` Anders Waldenborg
2018-11-26  7:52               ` Junio C Hamano
2018-11-18 11:44     ` [PATCH v3 3/5] pretty: add support for "valueonly" option in %(trailers) Anders Waldenborg
2018-11-20  8:14       ` Eric Sunshine
2018-11-18 11:44     ` [PATCH v3 4/5] strbuf: separate callback for strbuf_expand:ing literals Anders Waldenborg
2018-11-18 11:44     ` [PATCH v3 5/5] pretty: add support for separator option in %(trailers) Anders Waldenborg
2018-11-20  8:25       ` Eric Sunshine
2018-12-08 16:36 ` [PATCH v4 0/7] %(trailers) improvements in pretty format Anders Waldenborg
2018-12-08 16:36   ` [PATCH v4 1/7] doc: group pretty-format.txt placeholders descriptions Anders Waldenborg
2018-12-08 16:36   ` [PATCH v4 2/7] pretty: allow %(trailers) options with explicit value Anders Waldenborg
2018-12-10  8:45     ` Junio C Hamano
2018-12-08 16:36   ` [PATCH v4 3/7] pretty: single return path in %(trailers) handling Anders Waldenborg
2018-12-08 16:36   ` [PATCH v4 4/7] pretty: allow showing specific trailers Anders Waldenborg
2018-12-10  8:56     ` Junio C Hamano
2018-12-08 16:36   ` [PATCH v4 5/7] pretty: add support for "valueonly" option in %(trailers) Anders Waldenborg
2018-12-08 16:36   ` [PATCH v4 6/7] strbuf: separate callback for strbuf_expand:ing literals Anders Waldenborg
2018-12-08 16:36   ` Anders Waldenborg [this message]

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181208163647.19538-8-anders@0x63.nu \
    --to=anders@0x63.nu \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=olyatelezhnaya@gmail.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

git@vger.kernel.org mailing list mirror (one of many)

Archives are clonable:
	git clone --mirror https://public-inbox.org/git
	git clone --mirror http://ou63pmih66umazou.onion/git
	git clone --mirror http://czquwvybam4bgbro.onion/git
	git clone --mirror http://hjrcffqmbrq6wope.onion/git

Newsgroups are available over NNTP:
	nntp://news.public-inbox.org/inbox.comp.version-control.git
	nntp://ou63pmih66umazou.onion/inbox.comp.version-control.git
	nntp://czquwvybam4bgbro.onion/inbox.comp.version-control.git
	nntp://hjrcffqmbrq6wope.onion/inbox.comp.version-control.git
	nntp://news.gmane.org/gmane.comp.version-control.git

 note: .onion URLs require Tor: https://www.torproject.org/
       or Tor2web: https://www.tor2web.org/

AGPL code for this site: git clone https://public-inbox.org/ public-inbox