Re: [PATCH v2 15/20] builtin/notes.c: let parse-options parse subcommands
From: Ævar Arnfjörð Bjarmason <hidden>
Date: 2022-08-19 18:14:23
On Fri, Aug 19 2022, SZEDER Gábor wrote:
- int result;
const char *override_notes_ref = NULL;
+ parse_opt_subcommand_fn *fn = list;
struct option options[] = {
OPT_STRING(0, "ref", &override_notes_ref, N_("notes-ref"),
N_("use notes from <notes-ref>")),
+ OPT_SUBCOMMAND("list", &fn, list),
+ OPT_SUBCOMMAND("add", &fn, add),
+ OPT_SUBCOMMAND("copy", &fn, copy),
+ OPT_SUBCOMMAND("append", &fn, append_edit),
+ OPT_SUBCOMMAND("edit", &fn, append_edit),
+ OPT_SUBCOMMAND("show", &fn, show),
+ OPT_SUBCOMMAND("merge", &fn, merge),
+ OPT_SUBCOMMAND("remove", &fn, remove_cmd),
+ OPT_SUBCOMMAND("prune", &fn, prune),
+ OPT_SUBCOMMAND("get-ref", &fn, get_ref),
OPT_END()
};
git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, options, git_notes_usage,
- PARSE_OPT_STOP_AT_NON_OPTION);
+ PARSE_OPT_SUBCOMMAND_OPTIONAL);
+ if (fn == list && argc && strcmp(argv[0], "list")) {
+ error(_("unknown subcommand: %s"), argv[0]);
+ usage_with_options(git_notes_usage, options);
+ }
I wanted to ask why the API can't smartly handle this, but your "Found
an unknown option given to a command with" comment in an earlier patch
answered it.
I think something in this direction would be a bit more readble/obvious,
as it avoids hardcoding "list":
diff --git a/builtin/notes.c b/builtin/notes.c
index 42cbae46598..43d59b1a98e 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -995,7 +995,7 @@ static int get_ref(int argc, const char **argv, const char *prefix)
int cmd_notes(int argc, const char **argv, const char *prefix)
{
const char *override_notes_ref = NULL;
- parse_opt_subcommand_fn *fn = list;
+ parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
OPT_STRING(0, "ref", &override_notes_ref, N_("notes-ref"),
N_("use notes from <notes-ref>")),
@@ -1015,10 +1015,11 @@ int cmd_notes(int argc, const char **argv, const char *prefix)
git_config(git_default_config, NULL);
argc = parse_options(argc, argv, prefix, options, git_notes_usage,
PARSE_OPT_SUBCOMMAND_OPTIONAL);
- if (fn == list && argc && strcmp(argv[0], "list")) {
- error(_("unknown subcommand: %s"), argv[0]);
- usage_with_options(git_notes_usage, options);
- }
+ if (!fn && argc)
+ usage_msg_optf(_("unknown subcommand: %s"),
+ git_notes_usage, options, argv[0]);
+ else if (!fn)
+ fn = list;
if (override_notes_ref) {
struct strbuf sb = STRBUF_INIT;
I.e. we rely on the API setting it to non-NULL if it finds a subcommand,
otherwise we just set it to "list" after checking whether we have excess
arguments.
[...]
- else if (!strcmp(argv[0], "get-ref"))
- result = get_ref(argc, argv, prefix);
- else {
- result = error(_("unknown subcommand: %s"), argv[0]);
- usage_with_options(git_notes_usage, options);
- }
-
- return result ? 1 : 0;
+ return !!fn(argc, argv, prefix);
}In any case this is a lot nicer, ditto previous comment about maybe skipping the refactoring of this end code, but I'm also fine with keeping it.