rev-parse --parseopt: option argument name hints

Built-in commands can specify names for option arguments when usage text is generated for a command. sh based commands should be able to do the same. Option argument name hint is any text that comes after [*=?!] after the argument name up to the first whitespace. Signed-off-by: Ilya Bobyr <ilya.bobyr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ilya Bobyr committed Mar 22, 2014 at 02:47 UTC 9bab5b6061f1bc8ca54f8ac145f4f88c644e3bc4
3 files changed +64 -3
Documentation/git-rev-parse.txt
+32 -2
@@ -284,13 +284,13 @@ Input Format
284
285 'git rev-parse --parseopt' input format is fully text based. It has two parts,
286 separated by a line that contains only `--`. The lines before the separator
287 -(should be more than one) are used for the usage.
287 +(should be one or more) are used for the usage.
288 The lines after the separator describe the options.
289
290 Each line of options has this format:
291
292 ------------
293 -<opt_spec><flags>* SP+ help LF
293 +<opt_spec><flags>*<arg_hint>? SP+ help LF
294 ------------
295
296 `<opt_spec>`::
@@ -313,6 +313,12 @@ Each line of options has this format:
313
314 * Use `!` to not make the corresponding negated long option available.
315
316 +`<arg_hint>`::
317 + `<arg_hint>`, if specified, is used as a name of the argument in the
318 + help output, for options that take arguments. `<arg_hint>` is
319 + terminated by the first whitespace. When you need to use space in the
320 + argument hint use dash instead.
321 +
322 The remainder of the line, after stripping the spaces, is used
323 as the help associated to the option.
324
@@ -333,6 +339,8 @@ h,help show the help
339
340 foo some nifty option --foo
341 bar= some cool option --bar with an argument
342 +baz=arg another cool option --baz with a named argument
343 +qux?path qux may take a path argument but has meaning by itself
344
345 An option group Header
346 C? option C with an optional argument"
@@ -340,6 +348,28 @@ C? option C with an optional argument"
348 eval "$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
349 ------------
350
351 +
352 +Usage text
353 +~~~~~~~~~~
354 +
355 +When `"$@"` is `-h` or `--help` in the above example, the following
356 +usage text would be shown:
357 +
358 +------------
359 +usage: some-command [options] <args>...
360 +
361 + some-command does foo and bar!
362 +
363 + -h, --help show the help
364 + --foo some nifty option --foo
365 + --bar ... some cool option --bar with an argument
366 + --bar <arg> another cool option --baz with a named argument
367 + --qux[=<path>] qux may take a path argument but has meaning by itself
368 +
369 +An option group Header
370 + -C[...] option C with an optional argument
371 +------------
372 +
373 SQ-QUOTE
374 --------
375
builtin/rev-parse.c
+12 -1
@@ -395,9 +395,10 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
395 usage[unb++] = strbuf_detach(&sb, NULL);
396 }
397
398 - /* parse: (<short>|<short>,<long>|<long>)[=?]? SP+ <help> */
398 + /* parse: (<short>|<short>,<long>|<long>)[*=?!]*<arghint>? SP+ <help> */
399 while (strbuf_getline(&sb, stdin, '\n') != EOF) {
400 const char *s;
401 + const char *end;
402 struct option *o;
403
404 if (!sb.len)
@@ -419,6 +420,16 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
420 o->value = &parsed;
421 o->flags = PARSE_OPT_NOARG;
422 o->callback = &parseopt_dump;
423 +
424 + /* Possible argument name hint */
425 + end = s;
426 + while (s > sb.buf && strchr("*=?!", s[-1]) == NULL)
427 + --s;
428 + if (s != sb.buf && s != end)
429 + o->argh = xmemdupz(s, end - s);
430 + if (s == sb.buf)
431 + s = end;
432 +
433 while (s > sb.buf && strchr("*=?!", s[-1])) {
434 switch (*--s) {
435 case '=':
t/t1502-rev-parse-parseopt.sh
+20
@@ -18,6 +18,17 @@ An option group Header
18 -C[...] option C with an optional argument
19 -d, --data[=...] short and long option with an optional argument
20
21 +Argument hints
22 + -b <arg> short option required argument
23 + --bar2 <arg> long option required argument
24 + -e, --fuz <with-space>
25 + short and long option required argument
26 + -s[<some>] short option optional argument
27 + --long[=<data>] long option optional argument
28 + -g, --fluf[=<path>] short and long option optional argument
29 + --longest <very-long-argument-hint>
30 + a very long argument hint
31 +
32 Extras
33 --extra1 line above used to cause a segfault but no longer does
34
@@ -39,6 +50,15 @@ b,baz a short and long option
50 C? option C with an optional argument
51 d,data? short and long option with an optional argument
52
53 + Argument hints
54 +b=arg short option required argument
55 +bar2=arg long option required argument
56 +e,fuz=with-space short and long option required argument
57 +s?some short option optional argument
58 +long?data long option optional argument
59 +g,fluf?path short and long option optional argument
60 +longest=very-long-argument-hint a very long argument hint
61 +
62 Extras
63 extra1 line above used to cause a segfault but no longer does
64 EOF