]> git.ipfire.org Git - thirdparty/git.git/commitdiff
tests: disallow the use of abbreviated options (by default)
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Fri, 12 Apr 2019 09:37:24 +0000 (02:37 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 15 Apr 2019 02:54:04 +0000 (11:54 +0900)
Git's command-line parsers support uniquely abbreviated options, e.g.
`git init --ba` would automatically expand `--ba` to `--bare`.

This is a very convenient feature in every day life for Git users, in
particular when tab completion is not available.

However, it is not a good idea to rely on that in Git's test suite, as
something that is a unique abbreviation of a command line option today
might no longer be a unique abbreviation tomorrow.

For example, if a future contribution added a new mode
`git init --babyproofing` and a previously-introduced test case used the
fact that `git init --ba` expanded to `git init --bare`, that future
contribution would now have to touch seemingly unrelated tests just to
keep the test suite from failing.

So let's disallow abbreviated options in the test suite by default.

Note: for ease of implementation, this patch really only touches the
`parse-options` machinery: more and more hand-rolled option parsers are
converted to use that internal API, and more and more scripts are
converted to built-ins (naturally using the parse-options API, too), so
in practice this catches most issues, and is definitely the biggest bang
for the buck.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
parse-options.c
t/README
t/t0040-parse-options.sh
t/test-lib.sh

index cec74522e56b084fbb0c8eeec47456d0bb2f7d3e..acc3a93660e6b567bd8a7285dd4e43860dd0a7f3 100644 (file)
@@ -6,6 +6,8 @@
 #include "color.h"
 #include "utf8.h"
 
+static int disallow_abbreviated_options;
+
 #define OPT_SHORT 1
 #define OPT_UNSET 2
 
@@ -344,6 +346,10 @@ is_abbreviated:
                return get_value(p, options, all_opts, flags ^ opt_flags);
        }
 
+       if (disallow_abbreviated_options && (ambiguous_option || abbrev_option))
+               die("disallowed abbreviated or ambiguous option '%.*s'",
+                   (int)(arg_end - arg), arg);
+
        if (ambiguous_option) {
                error(_("ambiguous option: %s "
                        "(could be --%s%s or --%s%s)"),
@@ -708,6 +714,9 @@ int parse_options(int argc, const char **argv, const char *prefix,
 {
        struct parse_opt_ctx_t ctx;
 
+       disallow_abbreviated_options =
+               git_env_bool("GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS", 0);
+
        parse_options_start(&ctx, argc, argv, prefix, options, flags);
        switch (parse_options_step(&ctx, options, usagestr)) {
        case PARSE_OPT_HELP:
index 656288edcea5a23a5893ade5c2d81ee429eb26e8..9ed3051a1cc662208cd84afbd4817f1abbc7f5f5 100644 (file)
--- a/t/README
+++ b/t/README
@@ -399,6 +399,10 @@ GIT_TEST_SIDEBAND_ALL=<boolean>, when true, overrides the
 fetch-pack to not request sideband-all (even if the server advertises
 sideband-all).
 
+GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is
+the default when running tests), errors out when an abbreviated option
+is used.
+
 Naming Tests
 ------------
 
index b8f366c4420f47d913b1d830037d846e4e443074..800b3ea5f5b64650efa95bfa05e8f90945966f85 100755 (executable)
@@ -203,20 +203,24 @@ file: (not set)
 EOF
 
 test_expect_success 'unambiguously abbreviated option' '
+       GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
        test-tool parse-options --int 2 --boolean --no-bo >output 2>output.err &&
        test_must_be_empty output.err &&
        test_cmp expect output
 '
 
 test_expect_success 'unambiguously abbreviated option with "="' '
+       GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
        test-tool parse-options --expect="integer: 2" --int=2
 '
 
 test_expect_success 'ambiguously abbreviated option' '
-       test_expect_code 129 test-tool parse-options --strin 123
+       test_expect_code 129 env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
+       test-tool parse-options --strin 123
 '
 
 test_expect_success 'non ambiguous option (after two options it abbreviates)' '
+       GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
        test-tool parse-options --expect="string: 123" --st 123
 '
 
@@ -325,6 +329,7 @@ file: (not set)
 EOF
 
 test_expect_success 'negation of OPT_NONEG flags is not ambiguous' '
+       GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
        test-tool parse-options --no-ambig >output 2>output.err &&
        test_must_be_empty output.err &&
        test_cmp expect output
@@ -370,4 +375,11 @@ test_expect_success '--no-verbose resets multiple verbose to 0' '
        test-tool parse-options --expect="verbose: 0" -v -v -v --no-verbose
 '
 
+test_expect_success 'GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS works' '
+       GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
+               test-tool parse-options --ye &&
+       test_must_fail env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=true \
+               test-tool parse-options --ye
+'
+
 test_done
index 562c57e6858b79aff074fcb7ab8c65fa2f110bc0..c14ebe68d3d1d1493ccf1aa220e0940597257ef8 100644 (file)
@@ -57,6 +57,13 @@ fi
 . "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
 export PERL_PATH SHELL_PATH
 
+# Disallow the use of abbreviated options in the test suite by default
+if test -z "${GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS}"
+then
+       GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=true
+       export GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS
+fi
+
 ################################################################
 # It appears that people try to run tests without building...
 "${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git$X" >/dev/null