git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: "Jean-Noël Avila via GitGitGadget" <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org, "Johannes Sixt" <j6t@kdbg.org>,
	"Phillip Wood" <phillip.wood123@gmail.com>,
	"Jean-Noël Avila" <jn.avila@free.fr>
Subject: Re: [PATCH v2 1/4] i18n: factorize more 'incompatible options' messages
Date: Tue, 01 Feb 2022 22:01:52 +0100	[thread overview]
Message-ID: <220201.86a6fa9tmr.gmgdl@evledraar.gmail.com> (raw)
In-Reply-To: <844e01391e1198960072844536d736f51573cac6.1643408644.git.gitgitgadget@gmail.com>


On Fri, Jan 28 2022, Jean-Noël Avila via GitGitGadget wrote:

> From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>
> [...]
> +void die_if_incompatible_opt3(int opt1, const char *opt1_name,
> +							  int opt2, const char *opt2_name,
> +							  int opt3, const char *opt3_name)
> +{
> +	int count = 0;
> +	const char *options[3];
> +
> +	if (opt1)
> +		options[count++] = opt1_name;
> +	if (opt2)
> +		options[count++] = opt2_name;
> +	if (opt3)
> +		options[count++] = opt3_name;
> +	if (count > 2)
> +		die(_("options '%s', '%s', and '%s' cannot be used together"), opt1_name, opt2_name, opt3_name);
> +	else if (count > 1)
> +		die(_("options '%s' and '%s' cannot be used together"), options[0], options[1]);
> +}
> +
> +void die_if_incompatible_opt4(int opt1, const char *opt1_name,
> +							  int opt2, const char *opt2_name,
> +							  int opt3, const char *opt3_name,
> +							  int opt4, const char *opt4_name)
> +{
> +	int count = 0;
> +	const char *options[4];
> +
> +	if (opt1)
> +		options[count++] = opt1_name;
> +	if (opt2)
> +		options[count++] = opt2_name;
> +	if (opt3)
> +		options[count++] = opt3_name;
> +	if (opt4)
> +		options[count++] = opt4_name;
> +	switch (count) {
> +	case 4:
> +		die(_("options '%s', '%s', '%s', and '%s' cannot be used together"), opt1_name, opt2_name, opt3_name, opt4_name);
> +		break;
> +	case 3:
> +		die(_("options '%s', '%s', and '%s' cannot be used together"), options[0], options[1], options[2]);
> +		break;
> +	case 2:
> +		die(_("options '%s' and '%s' cannot be used together"), options[0], options[1]);
> +		break;
> +	default:
> +		break;
> +	}
> +}
> diff --git a/parse-options.h b/parse-options.h
> index e22846d3b7b..cf393839ac4 100644
> --- a/parse-options.h
> +++ b/parse-options.h
> @@ -339,4 +339,13 @@ int parse_opt_tracking_mode(const struct option *, const char *, int);
>  #define OPT_PATHSPEC_FILE_NUL(v)  OPT_BOOL(0, "pathspec-file-nul", v, N_("with --pathspec-from-file, pathspec elements are separated with NUL character"))
>  #define OPT_AUTOSTASH(v) OPT_BOOL(0, "autostash", v, N_("automatically stash/stash pop before and after"))
>  
> +void die_if_incompatible_opt3(int opt1, const char *opt1_name,
> +							  int opt2, const char *opt2_name,
> +							  int opt3, const char *opt3_name);
> +
> +void die_if_incompatible_opt4(int opt1, const char *opt1_name,
> +							  int opt2, const char *opt2_name,
> +							  int opt3, const char *opt3_name,
> +							  int opt4, const char *opt4_name);
> +
>  #endif
> diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh
> index 91964653a0b..5fcaa0b4f2a 100755
> --- a/t/t7500-commit-template-squash-signoff.sh
> +++ b/t/t7500-commit-template-squash-signoff.sh
> @@ -442,7 +442,7 @@ test_expect_success '--fixup=reword: give error with pathsec' '
>  '
>  
>  test_expect_success '--fixup=reword: -F give error message' '
> -	echo "fatal: Only one of -c/-C/-F/--fixup can be used." >expect &&
> +	echo "fatal: options '\''-F'\'' and '\''--fixup'\'' cannot be used together" >expect &&
>  	test_must_fail git commit --fixup=reword:HEAD~ -F msg  2>actual &&
>  	test_cmp expect actual
>  '

I've really wanted (and have been meaning to find time to work on) some
expansion of what we can get from the "these are incompatible" that
OPT_CMDMODE gives us for a while.

But I think doing it like this is really going in the wrong direction,
i.e. we have no need to run all of parse_options(), callbacks and all,
and populate all the variables, only to after the fact die when we
notice both "a" and "b" were set, and those are incompatible.

I.e. to have the API work like something resembling this:
	
	diff --git a/builtin/grep.c b/builtin/grep.c
	index 75e07b5623a..80ea323f957 100644
	--- a/builtin/grep.c
	+++ b/builtin/grep.c
	@@ -849,8 +849,11 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
	 	struct option options[] = {
	 		OPT_BOOL(0, "cached", &cached,
	 			N_("search in index instead of in the work tree")),
	+		OPT_INCOMPATIBLE("cached", "untracked"),
	 		OPT_NEGBIT(0, "no-index", &use_index,
	 			 N_("find in contents not managed by git"), 1),
	+		OPT_INCOMPATIBLE("no-index", "untracked"),
	+		OPT_INCOMPATIBLE("no-index", "cached"),
	 		OPT_BOOL(0, "untracked", &untracked,
	 			N_("search in both tracked and untracked files")),
	 		OPT_SET_INT(0, "exclude-standard", &opt_exclude,
	@@ -1167,12 +1170,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
	 	if (!show_in_pager && !opt.status_only)
	 		setup_pager();
	 
	-	if (!use_index && (untracked || cached))
	-		die(_("--cached or --untracked cannot be used with --no-index"));
	-
	-	if (untracked && cached)
	-		die(_("--untracked cannot be used with --cached"));
	-
	 	if (!use_index || untracked) {
	 		int use_exclude = (opt_exclude < 0) ? use_index : !!opt_exclude;
	 		hit = grep_directory(&opt, &pathspec, use_exclude, use_index);
	
I.e. to have this be a new parse_opt_type. Then we'd just make note of
what's incompatible with what other stuff, and in parse_options_step()
check if the option we're currently looking at (e.g. --no-index) is
still the only one set out of a list-of-lists incompatible options.

And for i18n I really don't think we need to spend effort on detecting a
case where --foo --bar and --baz are all incompatible, and saying one
of:

    --bar is incompatible with --foo

Or:

    --bar is incompatible with --foo and --baz

Depending on whether the command-line is "--foo --bar" or "--foo --bar
--baz", let's just in both cases say:

    --bar is incompatible with --foo

Then if the user adjusts "--foo --bar --baz" to "--foo --baz" we'll just
show them a new error, using the same template:

    --baz is incompatible with --foo

I.e. doing this as we iterate options is Good Enough, it's not worth the
complexity or translator time to try to exhaustively list all
conflicting options at once.

  parent reply	other threads:[~2022-02-01 21:14 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-22 18:35 [PATCH 0/4] Factorize i18n Jean-Noël Avila via GitGitGadget
2022-01-22 18:35 ` [PATCH 1/4] i18n: factorize more 'incompatible options' messages Jean-Noël Avila via GitGitGadget
2022-01-24  7:14   ` Johannes Sixt
2022-01-24 11:06     ` Phillip Wood
2022-01-25 20:52       ` Jean-Noël AVILA
2022-01-25 21:26         ` Johannes Sixt
2022-01-22 18:35 ` [PATCH 2/4] i18n: factorize "invalid value" messages Jean-Noël Avila via GitGitGadget
2022-01-24 11:09   ` Phillip Wood
2022-01-22 18:35 ` [PATCH 3/4] i18n: remove from i18n strings that do not hold translatable parts Jean-Noël Avila via GitGitGadget
2022-01-22 18:35 ` [PATCH 4/4] i18n: transfer variables into placeholders in command synopsis Jean-Noël Avila via GitGitGadget
2022-01-28 22:23 ` [PATCH v2 0/4] Factorize i18n Jean-Noël Avila via GitGitGadget
2022-01-28 22:24   ` [PATCH v2 1/4] i18n: factorize more 'incompatible options' messages Jean-Noël Avila via GitGitGadget
2022-01-28 23:21     ` Johannes Sixt
2022-01-28 23:58       ` Junio C Hamano
2022-01-29  8:08         ` Johannes Sixt
2022-01-29 10:41           ` Jean-Noël AVILA
2022-01-29 13:18             ` Johannes Sixt
2022-02-01 21:01     ` Ævar Arnfjörð Bjarmason [this message]
2022-01-28 22:24   ` [PATCH v2 2/4] i18n: factorize "invalid value" messages Jean-Noël Avila via GitGitGadget
2022-01-28 22:24   ` [PATCH v2 3/4] i18n: remove from i18n strings that do not hold translatable parts Jean-Noël Avila via GitGitGadget
2022-01-28 22:24   ` [PATCH v2 4/4] i18n: transfer variables into placeholders in command synopsis Jean-Noël Avila via GitGitGadget
2022-01-30 22:01   ` [PATCH v3 0/4] Factorize i18n Jean-Noël Avila via GitGitGadget
2022-01-30 22:01     ` [PATCH v3 1/4] i18n: factorize more 'incompatible options' messages Jean-Noël Avila via GitGitGadget
2022-01-31  7:15       ` Johannes Sixt
2022-01-31 10:56       ` Phillip Wood
2022-01-30 22:01     ` [PATCH v3 2/4] i18n: factorize "invalid value" messages Jean-Noël Avila via GitGitGadget
2022-01-30 22:01     ` [PATCH v3 3/4] i18n: remove from i18n strings that do not hold translatable parts Jean-Noël Avila via GitGitGadget
2022-01-30 22:01     ` [PATCH v3 4/4] i18n: transfer variables into placeholders in command synopsis Jean-Noël Avila via GitGitGadget
2022-01-31 11:00       ` Phillip Wood
2022-01-31 13:36         ` Jean-Noël Avila
2022-01-31  7:15     ` [PATCH v3 0/4] Factorize i18n Johannes Sixt
2022-01-31 22:07     ` [PATCH v4 " Jean-Noël Avila via GitGitGadget
2022-01-31 22:07       ` [PATCH v4 1/4] i18n: factorize more 'incompatible options' messages Jean-Noël Avila via GitGitGadget
2022-01-31 22:41         ` Junio C Hamano
2022-02-01  7:01           ` Johannes Sixt
2022-02-01 17:58             ` Junio C Hamano
2022-02-02 16:05           ` Jean-Noël Avila
2022-02-02 17:29             ` Johannes Sixt
2022-01-31 22:07       ` [PATCH v4 2/4] i18n: factorize "invalid value" messages Jean-Noël Avila via GitGitGadget
2022-01-31 22:07       ` [PATCH v4 3/4] i18n: remove from i18n strings that do not hold translatable parts Jean-Noël Avila via GitGitGadget
2022-01-31 22:07       ` [PATCH v4 4/4] i18n: fix some misformated placeholders in command synopsis Jean-Noël Avila via GitGitGadget

Reply instructions:

You may reply publicly 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

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

  git send-email \
    --in-reply-to=220201.86a6fa9tmr.gmgdl@evledraar.gmail.com \
    --to=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=j6t@kdbg.org \
    --cc=jn.avila@free.fr \
    --cc=phillip.wood123@gmail.com \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).