parseopt: values of pathname type can be prefixed with :(optional)

In the previous step, we introduced an optional filename that can be
given to a configuration variable, and nullify the fact that such a
configuration setting even existed if the named path is missing or
empty.

Let's do the same for command line options that name a pathname.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
This commit is contained in:
Junio C Hamano
2024-10-14 13:44:27 -07:00
committed by Taylor Blau
parent dbafaff13b
commit 2da08f2c3d
2 changed files with 31 additions and 12 deletions

View File

@@ -75,7 +75,6 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
{ {
const char *s, *arg; const char *s, *arg;
const int unset = flags & OPT_UNSET; const int unset = flags & OPT_UNSET;
int err;
if (unset && p->opt) if (unset && p->opt)
return error(_("%s takes no value"), optname(opt, flags)); return error(_("%s takes no value"), optname(opt, flags));
@@ -131,22 +130,32 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
case OPTION_FILENAME: case OPTION_FILENAME:
{ {
const char *value; const char *value;
int is_optional;
FREE_AND_NULL(*(char **)opt->value);
err = 0;
if (unset) if (unset)
value = NULL; value = NULL;
else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
value = (const char *) opt->defval; value = (char *)opt->defval;
else else {
err = get_arg(p, opt, flags, &value); int err = get_arg(p, opt, flags, &value);
if (err)
if (!err)
*(char **)opt->value = fix_filename(p->prefix, value);
return err; return err;
} }
if (!value)
return 0;
is_optional = skip_prefix(value, ":(optional)", &value);
if (!value)
is_optional = 0;
value = fix_filename(p->prefix, value);
if (is_optional && is_empty_or_missing_file(value)) {
free((char *)value);
} else {
FREE_AND_NULL(*(char **)opt->value);
*(const char **)opt->value = value;
}
return 0;
}
case OPTION_CALLBACK: case OPTION_CALLBACK:
{ {
const char *p_arg = NULL; const char *p_arg = NULL;

View File

@@ -37,12 +37,22 @@ test_expect_success 'nonexistent template file should return error' '
) )
' '
test_expect_success 'nonexistent optional template file on command line' '
echo changes >> foo &&
git add foo &&
(
GIT_EDITOR="echo hello >\"\$1\"" &&
export GIT_EDITOR &&
git commit --template ":(optional)$PWD/notexist"
)
'
test_expect_success 'nonexistent template file in config should return error' ' test_expect_success 'nonexistent template file in config should return error' '
test_config commit.template "$PWD"/notexist && test_config commit.template "$PWD"/notexist &&
( (
GIT_EDITOR="echo hello >\"\$1\"" && GIT_EDITOR="echo hello >\"\$1\"" &&
export GIT_EDITOR && export GIT_EDITOR &&
test_must_fail git commit test_must_fail git commit --allow-empty
) )
' '