]> git.ipfire.org Git - thirdparty/git.git/commitdiff
bundle: framework for options before bundle file
authorRobin H. Johnson <robbat2@gentoo.org>
Sun, 10 Nov 2019 20:41:24 +0000 (12:41 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 11 Nov 2019 02:46:26 +0000 (11:46 +0900)
Make it possible for any of the git-bundle subcommands to include
options:
- before the sub-command
- after the sub-command, before the bundle filename

There is an immediate gain in support for help with all of the
sub-commands, where 'git bundle list-heads -h' previously returned an
error.

Downside here is an increase in code duplication that cannot be
trivially avoided short of shared global static options.

Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/bundle.c

index 1ea4bfdfc19868d9cb89bb7014c138f145f7dd67..09b989cfc0aae50a0d44878a1d731c65c8daa523 100644 (file)
@@ -1,4 +1,5 @@
 #include "builtin.h"
+#include "parse-options.h"
 #include "cache.h"
 #include "bundle.h"
 
  * bundle supporting "fetch", "pull", and "ls-remote".
  */
 
-static const char builtin_bundle_usage[] =
-  "git bundle create <file> <git-rev-list args>\n"
-  "   or: git bundle verify <file>\n"
-  "   or: git bundle list-heads <file> [<refname>...]\n"
-  "   or: git bundle unbundle <file> [<refname>...]";
+static const char * const builtin_bundle_usage[] = {
+  N_("git bundle create <file> <git-rev-list args>"),
+  N_("git bundle verify <file>"),
+  N_("git bundle list-heads <file> [<refname>...]"),
+  N_("git bundle unbundle <file> [<refname>...]"),
+  NULL
+};
 
-int cmd_bundle(int argc, const char **argv, const char *prefix)
-{
+static const char * const builtin_bundle_create_usage[] = {
+  N_("git bundle create <file> <git-rev-list args>"),
+  NULL
+};
+
+static const char * const builtin_bundle_verify_usage[] = {
+  N_("git bundle verify <file>"),
+  NULL
+};
+
+static const char * const builtin_bundle_list_heads_usage[] = {
+  N_("git bundle list-heads <file> [<refname>...]"),
+  NULL
+};
+
+static const char * const builtin_bundle_unbundle_usage[] = {
+  N_("git bundle unbundle <file> [<refname>...]"),
+  NULL
+};
+
+static int verbose;
+
+static int parse_options_cmd_bundle(int argc,
+               const char **argv,
+               const char* prefix,
+               const char * const usagestr[],
+               const struct option options[],
+               const char **bundle_file) {
+       int newargc;
+       newargc = parse_options(argc, argv, NULL, options, usagestr,
+                            PARSE_OPT_STOP_AT_NON_OPTION);
+       if (argc < 1)
+               usage_with_options(usagestr, options);
+       *bundle_file = prefix_filename(prefix, argv[0]);
+       return newargc;
+}
+
+static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {
+       struct option options[] = {
+               OPT_END()
+       };
+       const char* bundle_file;
+
+       argc = parse_options_cmd_bundle(argc, argv, prefix,
+                       builtin_bundle_create_usage, options, &bundle_file);
+       /* bundle internals use argv[1] as further parameters */
+
+       if (!startup_info->have_repository)
+               die(_("Need a repository to create a bundle."));
+       return !!create_bundle(the_repository, bundle_file, argc, argv);
+}
+
+static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {
        struct bundle_header header;
-       const char *cmd, *bundle_file;
        int bundle_fd = -1;
 
-       if (argc < 3)
-               usage(builtin_bundle_usage);
+       struct option options[] = {
+               OPT_END()
+       };
+       const char* bundle_file;
 
-       cmd = argv[1];
-       bundle_file = prefix_filename(prefix, argv[2]);
-       argc -= 2;
-       argv += 2;
+       argc = parse_options_cmd_bundle(argc, argv, prefix,
+                       builtin_bundle_verify_usage, options, &bundle_file);
+       /* bundle internals use argv[1] as further parameters */
 
        memset(&header, 0, sizeof(header));
-       if (strcmp(cmd, "create") && (bundle_fd =
-                               read_bundle_header(bundle_file, &header)) < 0)
+       if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
                return 1;
+       close(bundle_fd);
+       if (verify_bundle(the_repository, &header, 1))
+               return 1;
+       fprintf(stderr, _("%s is okay\n"), bundle_file);
+       return 0;
+}
 
-       if (!strcmp(cmd, "verify")) {
-               close(bundle_fd);
-               if (argc != 1) {
-                       usage(builtin_bundle_usage);
-                       return 1;
-               }
-               if (verify_bundle(the_repository, &header, 1))
-                       return 1;
-               fprintf(stderr, _("%s is okay\n"), bundle_file);
-               return 0;
-       }
-       if (!strcmp(cmd, "list-heads")) {
-               close(bundle_fd);
-               return !!list_bundle_refs(&header, argc, argv);
+static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) {
+       struct bundle_header header;
+       int bundle_fd = -1;
+
+       struct option options[] = {
+               OPT_END()
+       };
+       const char* bundle_file;
+
+       argc = parse_options_cmd_bundle(argc, argv, prefix,
+                       builtin_bundle_list_heads_usage, options, &bundle_file);
+       /* bundle internals use argv[1] as further parameters */
+
+       memset(&header, 0, sizeof(header));
+       if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
+               return 1;
+       close(bundle_fd);
+       return !!list_bundle_refs(&header, argc, argv);
+}
+
+static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) {
+       struct bundle_header header;
+       int bundle_fd = -1;
+
+       struct option options[] = {
+               OPT_END()
+       };
+       const char* bundle_file;
+
+       argc = parse_options_cmd_bundle(argc, argv, prefix,
+                       builtin_bundle_unbundle_usage, options, &bundle_file);
+       /* bundle internals use argv[1] as further parameters */
+
+       memset(&header, 0, sizeof(header));
+       if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
+               return 1;
+       if (!startup_info->have_repository)
+               die(_("Need a repository to unbundle."));
+       return !!unbundle(the_repository, &header, bundle_fd, 0) ||
+               list_bundle_refs(&header, argc, argv);
+}
+
+int cmd_bundle(int argc, const char **argv, const char *prefix)
+{
+       struct option options[] = {
+               OPT__VERBOSE(&verbose, N_("be verbose; must be placed before a subcommand")),
+               OPT_END()
+       };
+       int result;
+
+       argc = parse_options(argc, argv, prefix, options, builtin_bundle_usage,
+               PARSE_OPT_STOP_AT_NON_OPTION);
+
+       packet_trace_identity("bundle");
+
+       if (argc < 2)
+               usage_with_options(builtin_bundle_usage, options);
+
+       else if (!strcmp(argv[0], "create"))
+               result = cmd_bundle_create(argc, argv, prefix);
+       else if (!strcmp(argv[0], "verify"))
+               result = cmd_bundle_verify(argc, argv, prefix);
+       else if (!strcmp(argv[0], "list-heads"))
+               result = cmd_bundle_list_heads(argc, argv, prefix);
+       else if (!strcmp(argv[0], "unbundle"))
+               result = cmd_bundle_unbundle(argc, argv, prefix);
+       else {
+               error(_("Unknown subcommand: %s"), argv[0]);
+               usage_with_options(builtin_bundle_usage, options);
        }
-       if (!strcmp(cmd, "create")) {
-               if (argc < 2) {
-                       usage(builtin_bundle_usage);
-                       return 1;
-               }
-               if (!startup_info->have_repository)
-                       die(_("Need a repository to create a bundle."));
-               return !!create_bundle(the_repository, bundle_file, argc, argv);
-       } else if (!strcmp(cmd, "unbundle")) {
-               if (!startup_info->have_repository)
-                       die(_("Need a repository to unbundle."));
-               return !!unbundle(the_repository, &header, bundle_fd, 0) ||
-                       list_bundle_refs(&header, argc, argv);
-       } else
-               usage(builtin_bundle_usage);
+       return result ? 1 : 0;
 }