diff mbox series

[13/21] trailer: add option to make canonicalization optional

Message ID 20201025212652.3003036-14-anders@0x63.nu (mailing list archive)
State New, archived
Headers show
Series trailer fixes | expand

Commit Message

Anders Waldenborg Oct. 25, 2020, 9:26 p.m. UTC
); SAEximRunCond expanded to false

Adds a new `--(no-)canonicalize` option to interpret-trailers. By
default it is on unless `--parse` option is given.

When option is on trailer tokens and separators get canonicalized to
the form they have in config (if there is any config for that
trailer). This is same behavior as before this patch, which allows
this behavior to be disabled with `--no-canonicalize`. `--parse` now
also implies `--no-canonicalize`, if previous behavior with
canonicalization also in parse mode is wanted it needs to be combined
with `--parse --canonicalize`

Signed-off-by: Anders Waldenborg <anders@0x63.nu>
---
 Documentation/git-interpret-trailers.txt |  5 ++-
 builtin/interpret-trailers.c             |  3 ++
 t/t7513-interpret-trailers.sh            | 52 ++++++++++++++++++++++++
 trailer.c                                | 10 +++--
 trailer.h                                |  1 +
 5 files changed, 67 insertions(+), 4 deletions(-)

Comments

Jeff King Nov. 10, 2020, 8:10 p.m. UTC | #1
On Sun, Oct 25, 2020 at 10:26:44PM +0100, Anders Waldenborg wrote:

> Adds a new `--(no-)canonicalize` option to interpret-trailers. By
> default it is on unless `--parse` option is given.
> 
> When option is on trailer tokens and separators get canonicalized to
> the form they have in config (if there is any config for that
> trailer). This is same behavior as before this patch, which allows
> this behavior to be disabled with `--no-canonicalize`. `--parse` now
> also implies `--no-canonicalize`, if previous behavior with
> canonicalization also in parse mode is wanted it needs to be combined
> with `--parse --canonicalize`

I'm not sure if this should be tied to --parse or not. The idea of
--parse is that you'd normalize syntactic issues to make it easy to
parse the result. But wouldn't normalizing names around spelling or
capitalization be what you'd usually want there?

So it sounds like you'd want it to _always_ be on, but leave
"--no-canonicalize" as an escape hatch for somebody who's researching
spelling variants.

Or maybe I'm misunderstanding what it does, since...

> --- a/Documentation/git-interpret-trailers.txt
> +++ b/Documentation/git-interpret-trailers.txt
> @@ -129,13 +129,16 @@ OPTIONS
>  
>  --parse::
>  	A convenience alias for `--only-trailers --only-input
> -	--unfold`.
> +	--unfold --no-canonicalize`.
>  
>  --no-divider::
>  	Do not treat `---` as the end of the commit message. Use this
>  	when you know your input contains just the commit message itself
>  	(and not an email or the output of `git format-patch`).
>  
> +--no-canonicalize::
> +	Disable canonicalization of input trailers.

I think this needs to define "canonicalization" here.

-Peff
diff mbox series

Patch

diff --git a/Documentation/git-interpret-trailers.txt b/Documentation/git-interpret-trailers.txt
index a4be8aed66..a9e6816525 100644
--- a/Documentation/git-interpret-trailers.txt
+++ b/Documentation/git-interpret-trailers.txt
@@ -129,13 +129,16 @@  OPTIONS
 
 --parse::
 	A convenience alias for `--only-trailers --only-input
-	--unfold`.
+	--unfold --no-canonicalize`.
 
 --no-divider::
 	Do not treat `---` as the end of the commit message. Use this
 	when you know your input contains just the commit message itself
 	(and not an email or the output of `git format-patch`).
 
+--no-canonicalize::
+	Disable canonicalization of input trailers.
+
 CONFIGURATION VARIABLES
 -----------------------
 
diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c
index 84748eafc0..51678657a3 100644
--- a/builtin/interpret-trailers.c
+++ b/builtin/interpret-trailers.c
@@ -81,6 +81,7 @@  static int parse_opt_parse(const struct option *opt, const char *arg,
 	v->only_trailers = 1;
 	v->only_input = 1;
 	v->unfold = 1;
+	v->canonicalize = 0;
 	BUG_ON_OPT_NEG(unset);
 	BUG_ON_OPT_ARG(arg);
 	return 0;
@@ -105,6 +106,7 @@  int cmd_interpret_trailers(int argc, const char **argv, const char *prefix)
 		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_BOOL(0, "canonicalize", &opts.canonicalize, N_("canonicalize spelling for trailers with config")),
 		OPT_CALLBACK_F(0, "parse", &opts, NULL, N_("set parsing options"),
 			PARSE_OPT_NOARG | PARSE_OPT_NONEG, parse_opt_parse),
 		OPT_BOOL(0, "no-divider", &opts.no_divider, N_("do not treat --- specially")),
@@ -112,6 +114,7 @@  int cmd_interpret_trailers(int argc, const char **argv, const char *prefix)
 				N_("trailer(s) to add"), option_parse_trailer),
 		OPT_END()
 	};
+	opts.canonicalize = 1;
 
 	git_config(git_default_config, NULL);
 
diff --git a/t/t7513-interpret-trailers.sh b/t/t7513-interpret-trailers.sh
index 6602790b5f..4b3a2484b5 100755
--- a/t/t7513-interpret-trailers.sh
+++ b/t/t7513-interpret-trailers.sh
@@ -99,6 +99,58 @@  test_expect_success 'with config option on the command line' '
 	test_cmp expected actual
 '
 
+test_expect_success 'spelling and separators are canonicalized from configs with key' '
+	cat >patch <<-\EOF &&
+		non-trailer-line
+
+		ReviEweD-bY :abc
+		ReviEwEd-bY) rst
+		ReviEweD-BY ; xyz
+		aCked-bY) only separator gets normalized
+	EOF
+	cat >expected <<-\EOF &&
+		Reviewed-By: abc
+		Reviewed-By: rst
+		Reviewed-By: xyz
+		aCked-bY: only separator gets normalized
+	EOF
+	git \
+		-c "trailer.separators=:);" \
+		-c "trailer.rb.key=Reviewed-By" \
+		-c "trailer.Acked-By.ifmissing=doNothing" \
+		interpret-trailers --only-trailers --only-input patch >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'spelling and separators are not canonicalized with --parse or --no-canonicalize' '
+	cat >patch <<-\EOF &&
+		non-trailer-line
+
+		ReviEweD-bY :abc
+		ReviEwEd-bY) rst
+		ReviEweD-BY ; xyz
+		aCked-bY) not normalized
+	EOF
+	cat >expected <<-\EOF &&
+		ReviEweD-bY :abc
+		ReviEwEd-bY) rst
+		ReviEweD-BY ; xyz
+		aCked-bY) not normalized
+	EOF
+	git \
+		-c "trailer.separators=:);" \
+		-c "trailer.rb.key=Reviewed-By" \
+		-c "trailer.Acked-By.ifmissing=doNothing" \
+		interpret-trailers --parse patch >actual &&
+	test_cmp expected actual &&
+	git \
+		-c "trailer.separators=:);" \
+		-c "trailer.rb.key=Reviewed-By" \
+		-c "trailer.Acked-By.ifmissing=doNothing" \
+		interpret-trailers --only-trailers --only-input --no-canonicalize patch >actual &&
+	test_cmp expected actual
+'
+
 test_expect_success 'with only a title in the message' '
 	cat >expected <<-\EOF &&
 		area: change
diff --git a/trailer.c b/trailer.c
index 102eca0127..110d3ed226 100644
--- a/trailer.c
+++ b/trailer.c
@@ -141,14 +141,18 @@  static void free_arg_item(struct arg_item *item)
 	free(item);
 }
 
-static void print_item(FILE *outfile, const struct trailer_item *item)
+static void print_item(FILE *outfile, const struct trailer_item *item,
+		       const struct process_trailer_options *opts)
 {
 	if (item->token) {
 		const char *tok = item->token;
 		const char *sep = (char []){separators[0], ' ', '\0'};
 		const struct conf_info *conf = item->conf;
 
-		if (conf) {
+		if (!opts->canonicalize && item->used_separator)
+			sep = item->used_separator;
+
+		if (opts->canonicalize && conf) {
 			if (conf->key)
 				tok = conf->key;
 			if (conf->nondefault_separator)
@@ -170,7 +174,7 @@  static void print_all(FILE *outfile, struct list_head *head,
 		item = list_entry(pos, struct trailer_item, list);
 		if ((!opts->trim_empty || strlen(item->value) > 0) &&
 		    (!opts->only_trailers || item->token))
-			print_item(outfile, item);
+			print_item(outfile, item, opts);
 	}
 }
 
diff --git a/trailer.h b/trailer.h
index b362b0d44d..aad856da8c 100644
--- a/trailer.h
+++ b/trailer.h
@@ -72,6 +72,7 @@  struct process_trailer_options {
 	int unfold;
 	int no_divider;
 	int value_only;
+	int canonicalize;
 	const struct strbuf *separator;
 	int (*filter)(const struct strbuf *, const char *alias, void *);
 	void *filter_data;