Skip to content

Commit b02e7d5

Browse files
dschogitster
authored andcommitted
tests: disallow the use of abbreviated options (by default)
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent effc2ba commit b02e7d5

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

parse-options.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "color.h"
77
#include "utf8.h"
88

9+
static int disallow_abbreviated_options;
10+
911
#define OPT_SHORT 1
1012
#define OPT_UNSET 2
1113

@@ -344,6 +346,10 @@ static enum parse_opt_result parse_long_opt(
344346
return get_value(p, options, all_opts, flags ^ opt_flags);
345347
}
346348

349+
if (disallow_abbreviated_options && (ambiguous_option || abbrev_option))
350+
die("disallowed abbreviated or ambiguous option '%.*s'",
351+
(int)(arg_end - arg), arg);
352+
347353
if (ambiguous_option) {
348354
error(_("ambiguous option: %s "
349355
"(could be --%s%s or --%s%s)"),
@@ -708,6 +714,9 @@ int parse_options(int argc, const char **argv, const char *prefix,
708714
{
709715
struct parse_opt_ctx_t ctx;
710716

717+
disallow_abbreviated_options =
718+
git_env_bool("GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS", 0);
719+
711720
parse_options_start(&ctx, argc, argv, prefix, options, flags);
712721
switch (parse_options_step(&ctx, options, usagestr)) {
713722
case PARSE_OPT_HELP:

t/README

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,10 @@ GIT_TEST_SIDEBAND_ALL=<boolean>, when true, overrides the
399399
fetch-pack to not request sideband-all (even if the server advertises
400400
sideband-all).
401401

402+
GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is
403+
the default when running tests), errors out when an abbreviated option
404+
is used.
405+
402406
Naming Tests
403407
------------
404408

t/t0040-parse-options.sh

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,20 +203,24 @@ file: (not set)
203203
EOF
204204

205205
test_expect_success 'unambiguously abbreviated option' '
206+
GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
206207
test-tool parse-options --int 2 --boolean --no-bo >output 2>output.err &&
207208
test_must_be_empty output.err &&
208209
test_cmp expect output
209210
'
210211

211212
test_expect_success 'unambiguously abbreviated option with "="' '
213+
GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
212214
test-tool parse-options --expect="integer: 2" --int=2
213215
'
214216

215217
test_expect_success 'ambiguously abbreviated option' '
216-
test_expect_code 129 test-tool parse-options --strin 123
218+
test_expect_code 129 env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
219+
test-tool parse-options --strin 123
217220
'
218221

219222
test_expect_success 'non ambiguous option (after two options it abbreviates)' '
223+
GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
220224
test-tool parse-options --expect="string: 123" --st 123
221225
'
222226

@@ -325,6 +329,7 @@ file: (not set)
325329
EOF
326330

327331
test_expect_success 'negation of OPT_NONEG flags is not ambiguous' '
332+
GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
328333
test-tool parse-options --no-ambig >output 2>output.err &&
329334
test_must_be_empty output.err &&
330335
test_cmp expect output
@@ -370,4 +375,11 @@ test_expect_success '--no-verbose resets multiple verbose to 0' '
370375
test-tool parse-options --expect="verbose: 0" -v -v -v --no-verbose
371376
'
372377

378+
test_expect_success 'GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS works' '
379+
GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
380+
test-tool parse-options --ye &&
381+
test_must_fail env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=true \
382+
test-tool parse-options --ye
383+
'
384+
373385
test_done

t/test-lib.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ fi
5757
. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
5858
export PERL_PATH SHELL_PATH
5959

60+
# Disallow the use of abbreviated options in the test suite by default
61+
if test -z "${GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS}"
62+
then
63+
GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=true
64+
export GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS
65+
fi
66+
6067
################################################################
6168
# It appears that people try to run tests without building...
6269
"${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git$X" >/dev/null

0 commit comments

Comments
 (0)