[PATCH v3 0/9] help: fix usage nits & bugs, completion shellscript->C

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This series fixes various bugs & edge cases in the "git help" command,
and improves and splits the internal-only "--completion-for-config"
option into two, and as a result can get rid of an awk/sort -u
pipeline in the bash completion.

Since the v2 I:

 * Read & tried to address all the feedback in one way or another

 * We now use OPT_CMDMODE() in builtin/help.c, that's indeed much
   nicer

 * I kept the preceding non-OPT_CMDMODE() steps pretty much as-is,
   since we can't use OPT_CMDMODE() until we've explained ad changed
   --all, --guides and --config to all be mutually exclusive.

 * The "vars" completion helper is now called --completion-for-config,
   which as 8/9 explains is done for backwards compatibility.

 * There's a new post-cleanup 9/9 which moves the "colopts" code into
   the help.c library where it's used, this was in response to Junio's
   comment asking about why I'd moved a git_config() call. That older
   code was buggy, but now our git_config() usage makes more sense.

1. https://lore.kernel.org/git/cover-v2-0.5-00000000000-20210910T112545Z-avarab@xxxxxxxxx/

Ævar Arnfjörð Bjarmason (9):
  help: correct the usage string in -h and documentation
  help: correct usage & behavior of "git help --guides"
  help tests: add test for --config output
  help: correct logic error in combining --all and --config
  help: correct logic error in combining --all and --guides
  help: simplify by moving to OPT_CMDMODE()
  help tests: test --config-for-completion option & output
  help / completion: make "git help" do the hard work
  help: move column config discovery to help.c library

 Documentation/git-help.txt             |   9 +-
 builtin/help.c                         | 131 ++++++++++++++++---------
 contrib/completion/git-completion.bash |  21 ++--
 help.c                                 |  16 ++-
 help.h                                 |   2 +-
 parse-options.h                        |   6 +-
 t/t0012-help.sh                        |  49 +++++++++
 7 files changed, 166 insertions(+), 68 deletions(-)

Range-diff against v2:
 1:  b10bfd21f14 =  1:  5341ddbe23e help: correct the usage string in -h and documentation
 2:  039639a0dd3 !  2:  e24ab59bc94 help: correct usage & behavior of "git help --guides"
    @@ Commit message
     
         As noted in 65f98358c0c (builtin/help.c: add --guide option,
         2013-04-02) and a133737b809 (doc: include --guide option description
    -    for "git help", 2013-04-02) which introduced the --guide option it
    +    for "git help", 2013-04-02) which introduced the --guide option, it
         cannot be combined with e.g. <command>.
     
    -    Change both the usage string to reflect that, and test and assert for
    -    this behavior in the command itself. Now that we assert this in code
    -    we don't need to exhaustively describe the previous confusing behavior
    -    in the documentation either, instead of silently ignoring the provided
    +    Change the command and the "SYNOPSIS" section to reflect that desired
    +    behavior. Now that we assert this in code we don't need to
    +    exhaustively describe the previous confusing behavior in the
    +    documentation either, instead of silently ignoring the provided
         argument we'll now error out.
     
    -    The comment being removed was added in 15f7d494380 (builtin/help.c:
    -    split "-a" processing into two, 2013-04-02). The "Ignore any remaining
    -    args" part of it is now no longer applicable as explained above, let's
    -    just remove it entirely, it's rather obvious that if we're returning
    -    we're done.
    +    The "We're done. Ignore any remaining args" comment added in
    +    15f7d494380 (builtin/help.c: split "-a" processing into two,
    +    2013-04-02) can now be removed, it's obvious that we're asserting the
    +    behavior with the check of "argc".
    +
    +    The "--config" option is still missing from the synopsis, it will be
    +    added in a subsequent commit where we'll fix bugs in its
    +    implementation.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
     
    @@ t/t0012-help.sh: test_expect_success 'basic help commands' '
      '
      
     +test_expect_success 'invalid usage' '
    -+	test_expect_code 129 git help -g git-add
    ++	test_expect_code 129 git help -g add
     +'
     +
      test_expect_success "works for commands and guides by default" '
 3:  258282095de !  3:  6a8965e1b5b help tests: add test for --config output
    @@ Commit message
         2018-05-26) looks like. We should not be emitting anything except
         config variables and the brief usage information at the end here.
     
    +    The second test regexp here might not match three-level variables in
    +    general, as their second level could contain ".", but in this case
    +    we're always emitting what we extract from the documentation, so it's
    +    all strings like:
    +
    +        foo.<name>.bar
    +
    +    If we did introduce something like variable example content here we'd
    +    like this to break, since we'd then be likely to break the
    +    git-completion.bash.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
     
      ## t/t0012-help.sh ##
    @@ t/t0012-help.sh: test_expect_success 'git help -g' '
     +	git help -c >help.output &&
     +	cat >expect <<-\EOF &&
     +
    -+	'"'"'git help config'"'"' for more information
    ++	'\''git help config'\'' for more information
     +	EOF
     +	grep -v -E \
     +		-e "^[^.]+\.[^.]+$" \
 4:  32d73d5273c !  4:  d5df231954a help: correct logic error in combining --all and --config
    @@ builtin/help.c: static const char * const builtin_help_usage[] = {
      };
      
     @@ builtin/help.c: int cmd_help(int argc, const char **argv, const char *prefix)
    - 	int nongit;
    - 	enum help_format parsed_help_format;
    - 	const char *page;
    -+	int need_config = 0;
    - 
    - 	argc = parse_options(argc, argv, prefix, builtin_help_options,
      			builtin_help_usage, 0);
      	parsed_help_format = help_format;
      
    @@ builtin/help.c: int cmd_help(int argc, const char **argv, const char *prefix)
     +		usage_msg_opt(_("--guides cannot be combined with command or guide names"),
      			      builtin_help_usage, builtin_help_options);
      
    --	if (show_all) {
    -+	need_config = show_all || show_config;
    -+	if (need_config)
    - 		git_config(git_help_config, NULL);
    -+
    -+	if (show_all) {
    - 		if (verbose) {
    - 			setup_pager();
    - 			list_all_cmds_help();
    + 	if (show_all) {
     @@ builtin/help.c: int cmd_help(int argc, const char **argv, const char *prefix)
      		list_commands(colopts, &main_cmds, &other_cmds);
      	}
    @@ t/t0012-help.sh: test_expect_success 'basic help commands' '
      '
      
      test_expect_success 'invalid usage' '
    --	test_expect_code 129 git help -g git-add
    -+	test_expect_code 129 git help -g git-add &&
    -+	test_expect_code 129 git help -c git-add &&
    -+	test_expect_code 129 git help -g git-add &&
    -+
    -+	test_expect_code 129 git help -a -c &&
    -+	test_expect_code 129 git help -g -c
    +-	test_expect_code 129 git help -g add
    ++	test_expect_code 129 git help -g add &&
    ++	test_expect_code 129 git help -a -c
      '
      
      test_expect_success "works for commands and guides by default" '
 -:  ----------- >  5:  bf3ac71f256 help: correct logic error in combining --all and --guides
 -:  ----------- >  6:  b52269eeab9 help: simplify by moving to OPT_CMDMODE()
 -:  ----------- >  7:  cc031c8d339 help tests: test --config-for-completion option & output
 5:  e995a42cb8d !  8:  836e19f8612 help / completion: make "git help" do the hard work
    @@ Commit message
         We can instead simply do the relevant parsing ourselves (we were doing
         most of it already), and call string_list_remove_duplicates() after
         already sorting the list, so the caller doesn't need to invoke "sort
    -    -u".
    +    -u". The "--config-for-completion" output is the same as before after
    +    being passed through "sort -u".
     
    -    This changes the output of the section list to emit lines like "alias"
    -    instead of "alias.". The dot suffix is better done as an argument to
    -    __gitcomp().
    +    Then add a new "--config-sections-for-completion" option. Under that
    +    output we'll emit config sections like "alias" (instead of "alias." in
    +    the --config-for-completion output).
     
    -    This means that we'll have the list_config_help() function do a bit
    -    more work, let's switch its "for_human" to passing a full
    -    "show_config", but as an enum type so we can have the compiler check
    -    what values we're expecting to get.
    +    We need to be careful to leave the "--config-for-completion" option
    +    compatible with users git, but are still running a shell with an older
    +    git-completion.bash. If we e.g. changed the option name they'd see
    +    messages about git-completion.bash being unable to find the
    +    "--config-for-completion" option.
    +
    +    Such backwards compatibility isn't something we should bend over
    +    backwards for, it's only helping users who:
    +
    +     * Upgrade git
    +     * Are in an old shell
    +     * The git-completion.bash in that shell hasn't cached the old
    +       "--config-for-completion" output already.
    +
    +    But since it's easy in this case to retain compatibility, let's do it,
    +    the older versions of git-completion.bash won't care that the input
    +    they get doesn't change after a "sort -u".
    +
    +    While we're at it let's make "--config-for-completion" die if there's
    +    anything left over in "argc", and do the same in the new
    +    "--config-sections-for-completion" option.
     
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
     
      ## builtin/help.c ##
    -@@ builtin/help.c: static const char *html_path;
    +@@ builtin/help.c: enum help_format {
    + 	HELP_FORMAT_WEB
    + };
      
    - static int show_all = 0;
    - static int show_guides = 0;
    --static int show_config;
     +enum show_config_type {
    -+	SHOW_CONFIG_UNSET = 0,
     +	SHOW_CONFIG_HUMAN,
     +	SHOW_CONFIG_VARS,
     +	SHOW_CONFIG_SECTIONS,
    -+} show_config;
    - static int verbose = 1;
    - static unsigned int colopts;
    - static enum help_format help_format = HELP_FORMAT_NONE;
    ++};
    ++
    + static enum help_action {
    + 	HELP_ACTION_ALL = 1,
    + 	HELP_ACTION_GUIDES,
    + 	HELP_ACTION_CONFIG,
    + 	HELP_ACTION_CONFIG_FOR_COMPLETION,
    ++	HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION,
    + } cmd_mode;
    + 
    + static const char *html_path;
     @@ builtin/help.c: static struct option builtin_help_options[] = {
    - 	OPT_HIDDEN_BOOL(0, "exclude-guides", &exclude_guides, N_("exclude guides")),
    - 	OPT_BOOL('g', "guides", &show_guides, N_("print list of useful guides")),
    - 	OPT_BOOL('c', "config", &show_config, N_("print all configuration variable names")),
    --	OPT_SET_INT_F(0, "config-for-completion", &show_config, "", 2, PARSE_OPT_HIDDEN),
    -+	OPT_SET_INT_F(0, "config-for-completion-vars", &show_config, "",
    -+		      SHOW_CONFIG_VARS, PARSE_OPT_HIDDEN),
    -+	OPT_SET_INT_F(0, "config-for-completion-sections", &show_config, "",
    -+		      SHOW_CONFIG_SECTIONS, PARSE_OPT_HIDDEN),
    - 	OPT_SET_INT('m', "man", &help_format, N_("show man page"), HELP_FORMAT_MAN),
    - 	OPT_SET_INT('w', "web", &help_format, N_("show manual in web browser"),
    - 			HELP_FORMAT_WEB),
    + 		    HELP_ACTION_CONFIG),
    + 	OPT_CMDMODE_F(0, "config-for-completion", &cmd_mode, "",
    + 		    HELP_ACTION_CONFIG_FOR_COMPLETION, PARSE_OPT_HIDDEN),
    ++	OPT_CMDMODE_F(0, "config-sections-for-completion", &cmd_mode, "",
    ++		    HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION, PARSE_OPT_HIDDEN),
    + 
    + 	OPT_END(),
    + };
     @@ builtin/help.c: struct slot_expansion {
      	int found;
      };
    @@ builtin/help.c: static void list_config_help(int for_human)
     +			break;
     +		case SHOW_CONFIG_VARS:
     +			break;
    -+		case SHOW_CONFIG_UNSET:
    -+			BUG("should not get SHOW_CONFIG_UNSET here");
      		}
     -
      		wildcard = strchr(var, '*');
    @@ builtin/help.c: static void list_config_help(int for_human)
      
      static enum help_format parse_help_format(const char *format)
     @@ builtin/help.c: int cmd_help(int argc, const char **argv, const char *prefix)
    + 		printf("%s\n", _(git_more_info_string));
      		return 0;
    - 	}
    - 
    --	if (show_config) {
    --		int for_human = show_config == 1;
    -+	switch (show_config) {
    -+	case SHOW_CONFIG_UNSET:
    -+		break;
    -+	case SHOW_CONFIG_VARS:
    -+	case SHOW_CONFIG_SECTIONS:
    -+		list_config_help(show_config);
    - 
    --		if (!for_human) {
    --			list_config_help(for_human);
    --			return 0;
    --		}
    + 	case HELP_ACTION_CONFIG_FOR_COMPLETION:
    +-		list_config_help(0);
    ++		no_extra_argc(argc);
    ++		list_config_help(SHOW_CONFIG_VARS);
     +		return 0;
    -+	case SHOW_CONFIG_HUMAN:
    ++	case HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION:
    ++		no_extra_argc(argc);
    ++		list_config_help(SHOW_CONFIG_SECTIONS);
    + 		return 0;
    + 	case HELP_ACTION_CONFIG:
    + 		no_extra_argc(argc);
      		setup_pager();
    --		list_config_help(for_human);
    -+		list_config_help(show_config);
    +-		list_config_help(1);
    ++		list_config_help(SHOW_CONFIG_HUMAN);
      		printf("\n%s\n", _("'git help config' for more information"));
    -+
      		return 0;
      	}
    - 
     
      ## contrib/completion/git-completion.bash ##
     @@ contrib/completion/git-completion.bash: __git_config_vars=
    @@ contrib/completion/git-completion.bash: __git_config_vars=
      {
      	test -n "$__git_config_vars" ||
     -	__git_config_vars="$(git help --config-for-completion | sort -u)"
    -+	__git_config_vars="$(git help --config-for-completion-vars)"
    ++	__git_config_vars="$(git help --config-for-completion)"
     +}
     +
     +__git_config_sections=
     +__git_compute_config_sections ()
     +{
     +	test -n "$__git_config_sections" ||
    -+	__git_config_sections="$(git help --config-for-completion-sections)"
    ++	__git_config_sections="$(git help --config-sections-for-completion)"
      }
      
      # Completes possible values of various configuration variables.
    @@ contrib/completion/git-completion.bash: __git_complete_config_variable_name ()
      }
     
      ## t/t0012-help.sh ##
    -@@ t/t0012-help.sh: test_expect_success 'git help -c' '
    - 	test_cmp expect actual
    +@@ t/t0012-help.sh: test_expect_success 'invalid usage' '
    + 	test_expect_code 129 git help -a -g &&
    + 
    + 	test_expect_code 129 git help -g -c &&
    +-	test_expect_code 0 git help --config-for-completion add
    ++	test_expect_code 129 git help --config-for-completion add &&
    ++	test_expect_code 129 git help --config-sections-for-completion add
      '
      
    -+test_expect_success 'git help --config-for-completion-vars' '
    -+	git help -c >human &&
    -+	grep -E \
    -+	     -e "^[^.]+\.[^.]+$" \
    -+	     -e "^[^.]+\.[^.]+\.[^.]+$" human |
    -+	     sed -e "s/\*.*//" -e "s/<.*//" |
    -+	     sort -u >human.munged &&
    -+
    -+	git help --config-for-completion-vars >vars &&
    -+	test_cmp human.munged vars
    -+'
    -+
    -+test_expect_success 'git help --config-for-completion-sections' '
    + test_expect_success "works for commands and guides by default" '
    +@@ t/t0012-help.sh: test_expect_success 'git help --config-for-completion' '
    + 	     sort -u >human.munged &&
    + 
    + 	git help --config-for-completion >vars &&
    +-	sort -u <vars >vars.new &&
    +-	mv vars.new vars &&
    + 	test_cmp human.munged vars
    + '
    + 
    ++test_expect_success 'git help --config-sections-for-completion' '
     +	git help -c >human &&
     +	grep -E \
     +	     -e "^[^.]+\.[^.]+$" \
    @@ t/t0012-help.sh: test_expect_success 'git help -c' '
     +	     sed -e "s/\..*//" |
     +	     sort -u >human.munged &&
     +
    -+	git help --config-for-completion-sections >sections &&
    ++	git help --config-sections-for-completion >sections &&
     +	test_cmp human.munged sections
     +'
     +
 -:  ----------- >  9:  29ee7cf375b help: move column config discovery to help.c library
-- 
2.33.0.1098.gf02a64c1a2d




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux