@matheusbsbs / matheus-bagliano / commits / 78dc08875c
Fork 0

test-lib: allow short options to be bundled

When debugging a test (or a set of tests), it's common to execute it with some combination of short options, such as: $ ./txxx-testname.sh -d -x -i In cases like this, CLIs usually allow the short options to be bundled in a single argument, for convenience and agility. Let's add this feature to test-lib, allowing the above command to be run as: $ ./txxx-testname.sh -dxi (or any other permutation, e.g. '-ixd') Note: Short options that require an argument can also be used in a bundle, in any position. So, for example, '-r 5 -x', '-xr 5' and '-rx 5' are all valid and equivalent. A special case would be having a bundle with more than one of such options. To keep things simple, this case is not allowed for now. This shouldn't be a major limitation, though, as the only short option that requires an argument today is '-r'. And concatenating '-r's as in '-rr 5 6' would probably not be very practical: its unbundled format would be '-r 5 -r 6', for which test-lib currently considers only the last argument. Therefore, if '-rr 5 6' were to be allowed, it would have the same effect as just typing '-r 6'. Note: the test-lib currently doesn't support '-r5', as an alternative for '-r 5', so the former is not supported in bundles as well. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Matheus Tavares committed Mar 22, 2020 at 12:58 UTC 78dc08875cd9a92bb39815ad1420afbf3dc682de
2 files changed +49 -15
t/README
+2 -1
@@ -69,7 +69,8 @@ You can also run each test individually from command line, like this:
69
70 You can pass --verbose (or -v), --debug (or -d), and --immediate
71 (or -i) command line argument to the test, or by setting GIT_TEST_OPTS
72 -appropriately before running "make".
72 +appropriately before running "make". Short options can be bundled, i.e.
73 +'-d -v' is the same as '-dv'.
74
75 -v::
76 --verbose::
t/test-lib.sh
+47 -14
@@ -78,20 +78,23 @@ then
78 exit 1
79 fi
80
81 -# Parse options while taking care to leave $@ intact, so we will still
82 -# have all the original command line options when executing the test
83 -# script again for '--tee' and '--verbose-log' below.
81 store_arg_to=
85 -prev_opt=
86 -for opt
87 -do
88 - if test -n "$store_arg_to"
82 +opt_required_arg=
83 +# $1: option string
84 +# $2: name of the var where the arg will be stored
85 +mark_option_requires_arg () {
86 + if test -n "$opt_required_arg"
87 then
90 - eval $store_arg_to=\$opt
91 - store_arg_to=
92 - prev_opt=
93 - continue
88 + echo "error: options that require args cannot be bundled" \
89 + "together: '$opt_required_arg' and '$1'" >&2
90 + exit 1
91 fi
92 + opt_required_arg=$1
93 + store_arg_to=$2
94 +}
95 +
96 +parse_option () {
97 + local opt="$1"
98
99 case "$opt" in
100 -d|--d|--de|--deb|--debu|--debug)
@@ -101,7 +104,7 @@ do
104 -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
105 GIT_TEST_LONG=t; export GIT_TEST_LONG ;;
106 -r)
104 - store_arg_to=run_list
107 + mark_option_requires_arg "$opt" run_list
108 ;;
109 --run=*)
110 run_list=${opt#--*=} ;;
@@ -185,12 +188,42 @@ do
188 *)
189 echo "error: unknown test option '$opt'" >&2; exit 1 ;;
190 esac
191 +}
192 +
193 +# Parse options while taking care to leave $@ intact, so we will still
194 +# have all the original command line options when executing the test
195 +# script again for '--tee' and '--verbose-log' later.
196 +for opt
197 +do
198 + if test -n "$store_arg_to"
199 + then
200 + eval $store_arg_to=\$opt
201 + store_arg_to=
202 + opt_required_arg=
203 + continue
204 + fi
205
189 - prev_opt=$opt
206 + case "$opt" in
207 + --*|-?)
208 + parse_option "$opt" ;;
209 + -?*)
210 + # bundled short options must be fed separately to parse_option
211 + opt=${opt#-}
212 + while test -n "$opt"
213 + do
214 + extra=${opt#?}
215 + this=${opt%$extra}
216 + opt=$extra
217 + parse_option "-$this"
218 + done
219 + ;;
220 + *)
221 + echo "error: unknown test option '$opt'" >&2; exit 1 ;;
222 + esac
223 done
224 if test -n "$store_arg_to"
225 then
193 - echo "error: $prev_opt requires an argument" >&2
226 + echo "error: $opt_required_arg requires an argument" >&2
227 exit 1
228 fi
229