Merge branch 'ab/align-parse-options-help'
When "git cmd -h" shows more than one line of usage text (e.g. the cmd subcommand may take sub-sub-command), parse-options API learned to align these lines, even across i18n/l10n. * ab/align-parse-options-help: parse-options: properly align continued usage output git rev-parse --parseopt tests: add more usagestr tests send-pack: properly use parse_options() API for usage string parse-options API users: align usage output in C-stringsmaint
commit
d7bc852151
|
@ -9,10 +9,10 @@ git-send-pack - Push objects over Git protocol to another repository
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git send-pack' [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>]
|
'git send-pack' [--dry-run] [--force] [--receive-pack=<git-receive-pack>]
|
||||||
[--verbose] [--thin] [--atomic]
|
[--verbose] [--thin] [--atomic]
|
||||||
[--[no-]signed|--signed=(true|false|if-asked)]
|
[--[no-]signed|--signed=(true|false|if-asked)]
|
||||||
[<host>:]<directory> [<ref>...]
|
[<host>:]<directory> (--all | <ref>...)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
|
|
|
@ -17,10 +17,10 @@
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
|
|
||||||
static const char * const send_pack_usage[] = {
|
static const char * const send_pack_usage[] = {
|
||||||
N_("git send-pack [--all | --mirror] [--dry-run] [--force] "
|
N_("git send-pack [--mirror] [--dry-run] [--force]\n"
|
||||||
"[--receive-pack=<git-receive-pack>] [--verbose] [--thin] [--atomic] "
|
" [--receive-pack=<git-receive-pack>]\n"
|
||||||
"[<host>:]<directory> [<ref>...]\n"
|
" [--verbose] [--thin] [--atomic]\n"
|
||||||
" --all and explicit <ref> specification are mutually exclusive."),
|
" [<host>:]<directory> (--all | <ref>...)"),
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
|
|
||||||
static const char * const git_tag_usage[] = {
|
static const char * const git_tag_usage[] = {
|
||||||
N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]\n"
|
N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]\n"
|
||||||
"\t\t<tagname> [<head>]"),
|
" <tagname> [<head>]"),
|
||||||
N_("git tag -d <tagname>..."),
|
N_("git tag -d <tagname>..."),
|
||||||
N_("git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--points-at <object>]\n"
|
N_("git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--points-at <object>]\n"
|
||||||
"\t\t[--format=<format>] [--merged <commit>] [--no-merged <commit>] [<pattern>...]"),
|
" [--format=<format>] [--merged <commit>] [--no-merged <commit>] [<pattern>...]"),
|
||||||
N_("git tag -v [--format=<format>] <tagname>..."),
|
N_("git tag -v [--format=<format>] <tagname>..."),
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -904,25 +904,77 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *ctx,
|
||||||
FILE *outfile = err ? stderr : stdout;
|
FILE *outfile = err ? stderr : stdout;
|
||||||
int need_newline;
|
int need_newline;
|
||||||
|
|
||||||
|
const char *usage_prefix = _("usage: %s");
|
||||||
|
/*
|
||||||
|
* The translation could be anything, but we can count on
|
||||||
|
* msgfmt(1)'s --check option to have asserted that "%s" is in
|
||||||
|
* the translation. So compute the length of the "usage: "
|
||||||
|
* part. We are assuming that the translator wasn't overly
|
||||||
|
* clever and used e.g. "%1$s" instead of "%s", there's only
|
||||||
|
* one "%s" in "usage_prefix" above, so there's no reason to
|
||||||
|
* do so even with a RTL language.
|
||||||
|
*/
|
||||||
|
size_t usage_len = strlen(usage_prefix) - strlen("%s");
|
||||||
|
/*
|
||||||
|
* TRANSLATORS: the colon here should align with the
|
||||||
|
* one in "usage: %s" translation.
|
||||||
|
*/
|
||||||
|
const char *or_prefix = _(" or: %s");
|
||||||
|
/*
|
||||||
|
* TRANSLATORS: You should only need to translate this format
|
||||||
|
* string if your language is a RTL language (e.g. Arabic,
|
||||||
|
* Hebrew etc.), not if it's a LTR language (e.g. German,
|
||||||
|
* Russian, Chinese etc.).
|
||||||
|
*
|
||||||
|
* When a translated usage string has an embedded "\n" it's
|
||||||
|
* because options have wrapped to the next line. The line
|
||||||
|
* after the "\n" will then be padded to align with the
|
||||||
|
* command name, such as N_("git cmd [opt]\n<8
|
||||||
|
* spaces>[opt2]"), where the 8 spaces are the same length as
|
||||||
|
* "git cmd ".
|
||||||
|
*
|
||||||
|
* This format string prints out that already-translated
|
||||||
|
* line. The "%*s" is whitespace padding to account for the
|
||||||
|
* padding at the start of the line that we add in this
|
||||||
|
* function. The "%s" is a line in the (hopefully already
|
||||||
|
* translated) N_() usage string, which contained embedded
|
||||||
|
* newlines before we split it up.
|
||||||
|
*/
|
||||||
|
const char *usage_continued = _("%*s%s");
|
||||||
|
const char *prefix = usage_prefix;
|
||||||
|
int saw_empty_line = 0;
|
||||||
|
|
||||||
if (!usagestr)
|
if (!usagestr)
|
||||||
return PARSE_OPT_HELP;
|
return PARSE_OPT_HELP;
|
||||||
|
|
||||||
if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
|
if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
|
||||||
fprintf(outfile, "cat <<\\EOF\n");
|
fprintf(outfile, "cat <<\\EOF\n");
|
||||||
|
|
||||||
fprintf_ln(outfile, _("usage: %s"), _(*usagestr++));
|
|
||||||
while (*usagestr && **usagestr)
|
|
||||||
/*
|
|
||||||
* TRANSLATORS: the colon here should align with the
|
|
||||||
* one in "usage: %s" translation.
|
|
||||||
*/
|
|
||||||
fprintf_ln(outfile, _(" or: %s"), _(*usagestr++));
|
|
||||||
while (*usagestr) {
|
while (*usagestr) {
|
||||||
if (**usagestr)
|
const char *str = _(*usagestr++);
|
||||||
fprintf_ln(outfile, _(" %s"), _(*usagestr));
|
struct string_list list = STRING_LIST_INIT_DUP;
|
||||||
else
|
unsigned int j;
|
||||||
|
|
||||||
|
if (!saw_empty_line && !*str)
|
||||||
|
saw_empty_line = 1;
|
||||||
|
|
||||||
|
string_list_split(&list, str, '\n', -1);
|
||||||
|
for (j = 0; j < list.nr; j++) {
|
||||||
|
const char *line = list.items[j].string;
|
||||||
|
|
||||||
|
if (saw_empty_line && *line)
|
||||||
|
fprintf_ln(outfile, _(" %s"), line);
|
||||||
|
else if (saw_empty_line)
|
||||||
fputc('\n', outfile);
|
fputc('\n', outfile);
|
||||||
usagestr++;
|
else if (!j)
|
||||||
|
fprintf_ln(outfile, prefix, line);
|
||||||
|
else
|
||||||
|
fprintf_ln(outfile, usage_continued,
|
||||||
|
(int)usage_len, "", line);
|
||||||
|
}
|
||||||
|
string_list_clear(&list, 0);
|
||||||
|
|
||||||
|
prefix = or_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
need_newline = 1;
|
need_newline = 1;
|
||||||
|
|
|
@ -282,4 +282,58 @@ test_expect_success 'test --parseopt --stuck-long and short option with unset op
|
||||||
test_cmp expect output
|
test_cmp expect output
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'test --parseopt help output: "wrapped" options normal "or:" lines' '
|
||||||
|
sed -e "s/^|//" >spec <<-\EOF &&
|
||||||
|
|cmd [--some-option]
|
||||||
|
| [--another-option]
|
||||||
|
|cmd [--yet-another-option]
|
||||||
|
|--
|
||||||
|
|h,help show the help
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sed -e "s/^|//" >expect <<-\END_EXPECT &&
|
||||||
|
|cat <<\EOF
|
||||||
|
|usage: cmd [--some-option]
|
||||||
|
| or: [--another-option]
|
||||||
|
| or: cmd [--yet-another-option]
|
||||||
|
|
|
||||||
|
| -h, --help show the help
|
||||||
|
|
|
||||||
|
|EOF
|
||||||
|
END_EXPECT
|
||||||
|
|
||||||
|
test_must_fail git rev-parse --parseopt -- -h >out <spec >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'test --parseopt help output: multi-line blurb after empty line' '
|
||||||
|
sed -e "s/^|//" >spec <<-\EOF &&
|
||||||
|
|cmd [--some-option]
|
||||||
|
| [--another-option]
|
||||||
|
|
|
||||||
|
|multi
|
||||||
|
|line
|
||||||
|
|blurb
|
||||||
|
|--
|
||||||
|
|h,help show the help
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sed -e "s/^|//" >expect <<-\END_EXPECT &&
|
||||||
|
|cat <<\EOF
|
||||||
|
|usage: cmd [--some-option]
|
||||||
|
| or: [--another-option]
|
||||||
|
|
|
||||||
|
| multi
|
||||||
|
| line
|
||||||
|
| blurb
|
||||||
|
|
|
||||||
|
| -h, --help show the help
|
||||||
|
|
|
||||||
|
|EOF
|
||||||
|
END_EXPECT
|
||||||
|
|
||||||
|
test_must_fail git rev-parse --parseopt -- -h >out <spec >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in New Issue