From 97558276e4f855442337be01abc8f90cf0dd1810 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 14 Nov 2014 14:00:13 -0500 Subject: [PATCH] Refactor command-line parsing Refactor command-line parsing to better utilize GOptionContext. This eliminates most of the manual parsing and global options are now shown in the help output. Here's a sample: $ ostree admin --help Usage: ostree admin [OPTION...] --print-current-dir|COMMAND Builtin "admin" Commands: cleanup config-diff deploy init-fs instutil os-init status switch undeploy upgrade Help Options: -h, --help Show help options Application Options: --sysroot=PATH Create a new OSTree sysroot at PATH -v, --verbose Print debug information during command processing --version Print version information and exit https://bugzilla.gnome.org/show_bug.cgi?id=740295 --- src/ostree/main.c | 48 +-- src/ostree/ot-admin-builtin-cleanup.c | 8 +- src/ostree/ot-admin-builtin-deploy.c | 8 +- src/ostree/ot-admin-builtin-diff.c | 6 +- src/ostree/ot-admin-builtin-init-fs.c | 7 +- src/ostree/ot-admin-builtin-instutil.c | 143 +++---- src/ostree/ot-admin-builtin-os-init.c | 7 +- src/ostree/ot-admin-builtin-status.c | 8 +- src/ostree/ot-admin-builtin-switch.c | 7 +- src/ostree/ot-admin-builtin-undeploy.c | 8 +- src/ostree/ot-admin-builtin-upgrade.c | 7 +- src/ostree/ot-admin-builtins.h | 24 +- ...ot-admin-instutil-builtin-grub2-generate.c | 8 +- ...-instutil-builtin-selinux-ensure-labeled.c | 8 +- .../ot-admin-instutil-builtin-set-kargs.c | 8 +- src/ostree/ot-admin-instutil-builtins.h | 6 +- src/ostree/ot-builtin-admin.c | 191 +++------ src/ostree/ot-builtin-cat.c | 7 +- src/ostree/ot-builtin-checkout.c | 7 +- src/ostree/ot-builtin-checksum.c | 6 +- src/ostree/ot-builtin-commit.c | 10 +- src/ostree/ot-builtin-config.c | 7 +- src/ostree/ot-builtin-diff.c | 6 +- src/ostree/ot-builtin-fsck.c | 7 +- src/ostree/ot-builtin-init.c | 7 +- src/ostree/ot-builtin-log.c | 6 +- src/ostree/ot-builtin-ls.c | 7 +- src/ostree/ot-builtin-prune.c | 7 +- src/ostree/ot-builtin-pull-local.c | 10 +- src/ostree/ot-builtin-pull.c | 7 +- src/ostree/ot-builtin-refs.c | 10 +- src/ostree/ot-builtin-remote.c | 7 +- src/ostree/ot-builtin-reset.c | 9 +- src/ostree/ot-builtin-rev-parse.c | 7 +- src/ostree/ot-builtin-show.c | 7 +- src/ostree/ot-builtin-static-delta.c | 7 +- src/ostree/ot-builtin-summary.c | 7 +- src/ostree/ot-builtin-trivial-httpd.c | 7 +- src/ostree/ot-builtins-common.c | 1 + src/ostree/ot-builtins.h | 2 +- src/ostree/ot-main.c | 377 +++++++++++------- src/ostree/ot-main.h | 18 +- 42 files changed, 555 insertions(+), 500 deletions(-) diff --git a/src/ostree/main.c b/src/ostree/main.c index e114690d..b8dccd6b 100644 --- a/src/ostree/main.c +++ b/src/ostree/main.c @@ -33,31 +33,31 @@ #include "ot-builtins.h" static OstreeCommand commands[] = { - { "admin", ostree_builtin_admin, OSTREE_BUILTIN_FLAG_NO_REPO }, - { "cat", ostree_builtin_cat, 0 }, - { "checkout", ostree_builtin_checkout, 0 }, - { "checksum", ostree_builtin_checksum, OSTREE_BUILTIN_FLAG_NO_REPO }, - { "commit", ostree_builtin_commit, 0 }, - { "config", ostree_builtin_config, 0 }, - { "diff", ostree_builtin_diff, 0 }, - { "fsck", ostree_builtin_fsck, 0 }, - { "init", ostree_builtin_init, OSTREE_BUILTIN_FLAG_NO_CHECK }, - { "log", ostree_builtin_log, 0 }, - { "ls", ostree_builtin_ls, 0 }, - { "prune", ostree_builtin_prune, 0 }, - { "pull-local", ostree_builtin_pull_local, 0 }, + { "admin", ostree_builtin_admin }, + { "cat", ostree_builtin_cat }, + { "checkout", ostree_builtin_checkout }, + { "checksum", ostree_builtin_checksum }, + { "commit", ostree_builtin_commit }, + { "config", ostree_builtin_config }, + { "diff", ostree_builtin_diff }, + { "fsck", ostree_builtin_fsck }, + { "init", ostree_builtin_init }, + { "log", ostree_builtin_log }, + { "ls", ostree_builtin_ls }, + { "prune", ostree_builtin_prune }, + { "pull-local", ostree_builtin_pull_local }, #ifdef HAVE_LIBSOUP - { "pull", ostree_builtin_pull, 0 }, + { "pull", ostree_builtin_pull }, #endif - { "refs", ostree_builtin_refs, 0 }, - { "remote", ostree_builtin_remote, 0 }, - { "reset", ostree_builtin_reset, 0 }, - { "rev-parse", ostree_builtin_rev_parse, 0 }, - { "show", ostree_builtin_show, 0 }, - { "static-delta", ostree_builtin_static_delta, 0 }, - { "summary", ostree_builtin_summary, 0 }, + { "refs", ostree_builtin_refs }, + { "remote", ostree_builtin_remote }, + { "reset", ostree_builtin_reset }, + { "rev-parse", ostree_builtin_rev_parse }, + { "show", ostree_builtin_show }, + { "static-delta", ostree_builtin_static_delta }, + { "summary", ostree_builtin_summary }, #ifdef HAVE_LIBSOUP - { "trivial-httpd", ostree_builtin_trivial_httpd, OSTREE_BUILTIN_FLAG_NO_REPO }, + { "trivial-httpd", ostree_builtin_trivial_httpd }, #endif { NULL } }; @@ -71,9 +71,11 @@ main (int argc, setlocale (LC_ALL, ""); + g_set_prgname (argv[0]); + ret = ostree_run (argc, argv, commands, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) - ostree_usage (argv, commands, TRUE); + ostree_usage (commands, TRUE); if (error != NULL) { diff --git a/src/ostree/ot-admin-builtin-cleanup.c b/src/ostree/ot-admin-builtin-cleanup.c index 015dfe7a..be9aaf32 100644 --- a/src/ostree/ot-admin-builtin-cleanup.c +++ b/src/ostree/ot-admin-builtin-cleanup.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" #include "ostree.h" @@ -34,16 +35,15 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_builtin_cleanup (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_builtin_cleanup (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeSysroot *sysroot = NULL; gboolean ret = FALSE; context = g_option_context_new ("Delete untagged deployments and repository objects"); - g_option_context_add_main_entries (context, options, NULL); - - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (!ostree_sysroot_load (sysroot, cancellable, error)) diff --git a/src/ostree/ot-admin-builtin-deploy.c b/src/ostree/ot-admin-builtin-deploy.c index 3584dee1..6c4327b7 100644 --- a/src/ostree/ot-admin-builtin-deploy.c +++ b/src/ostree/ot-admin-builtin-deploy.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" #include "ostree.h" @@ -49,11 +50,12 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_builtin_deploy (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const char *refspec; GOptionContext *context; + gs_unref_object OstreeSysroot *sysroot = NULL; GKeyFile *origin = NULL; gs_unref_object OstreeRepo *repo = NULL; gs_unref_ptrarray GPtrArray *new_deployments = NULL; @@ -64,9 +66,7 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancell context = g_option_context_new ("REFSPEC - Checkout revision REFSPEC as the new default deployment"); - g_option_context_add_main_entries (context, options, NULL); - - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (argc < 2) diff --git a/src/ostree/ot-admin-builtin-diff.c b/src/ostree/ot-admin-builtin-diff.c index 2e9abc0f..55a89110 100644 --- a/src/ostree/ot-admin-builtin-diff.c +++ b/src/ostree/ot-admin-builtin-diff.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" #include "ostree.h" @@ -37,9 +38,10 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_builtin_diff (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeSysroot *sysroot = NULL; gboolean ret = FALSE; gs_unref_object OstreeDeployment *deployment = NULL; gs_unref_object GFile *deployment_dir = NULL; @@ -53,7 +55,7 @@ ot_admin_builtin_diff (int argc, char **argv, OstreeSysroot *sysroot, GCancellab g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (!ostree_sysroot_load (sysroot, cancellable, error)) diff --git a/src/ostree/ot-admin-builtin-init-fs.c b/src/ostree/ot-admin-builtin-init-fs.c index 01114c5b..9fe46f4c 100644 --- a/src/ostree/ot-admin-builtin-init-fs.c +++ b/src/ostree/ot-admin-builtin-init-fs.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" #include "otutil.h" @@ -34,9 +35,10 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_builtin_init_fs (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_builtin_init_fs (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeSysroot *sysroot = NULL; gboolean ret = FALSE; gs_unref_object GFile *dir = NULL; gs_unref_object GFile *child = NULL; @@ -45,9 +47,8 @@ ot_admin_builtin_init_fs (int argc, char **argv, OstreeSysroot *sysroot, GCancel const char *normal_toplevels[] = {"boot", "dev", "home", "proc", "run", "sys"}; context = g_option_context_new ("PATH - Initialize a root filesystem"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (argc < 2) diff --git a/src/ostree/ot-admin-builtin-instutil.c b/src/ostree/ot-admin-builtin-instutil.c index 7a17dd3b..ba4d9b42 100644 --- a/src/ostree/ot-admin-builtin-instutil.c +++ b/src/ostree/ot-admin-builtin-instutil.c @@ -32,7 +32,7 @@ typedef struct { const char *name; - gboolean (*fn) (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); + gboolean (*fn) (int argc, char **argv, GCancellable *cancellable, GError **error); } OstreeAdminInstUtilCommand; static OstreeAdminInstUtilCommand admin_instutil_subcommands[] = { @@ -44,101 +44,62 @@ static OstreeAdminInstUtilCommand admin_instutil_subcommands[] = { { NULL, NULL } }; +static GOptionContext * +ostree_admin_instutil_option_context_new_with_commands (void) +{ + OstreeAdminInstUtilCommand *command = admin_instutil_subcommands; + GOptionContext *context; + GString *summary; + + context = g_option_context_new ("COMMAND"); + + summary = g_string_new ("Builtin \"admin instutil\" Commands:"); + + while (command->name != NULL) + { + g_string_append_printf (summary, "\n %s", command->name); + command++; + } + + g_option_context_set_summary (context, summary->str); + + g_string_free (summary, TRUE); + + return context; +} + gboolean -ot_admin_builtin_instutil (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_builtin_instutil (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; OstreeAdminInstUtilCommand *subcommand; const char *subcommand_name = NULL; - gboolean want_help = FALSE; - int in, out, i; - gboolean skip; + gs_free char *prgname = NULL; + int in, out; for (in = 1, out = 1; in < argc; in++, out++) { /* The non-option is the command, take it out of the arguments */ if (argv[in][0] != '-') { - skip = (subcommand_name == NULL); if (subcommand_name == NULL) - subcommand_name = argv[in]; + { + subcommand_name = argv[in]; + out--; + continue; + } } - /* The global long options */ - else if (argv[in][1] == '-') + else if (g_str_equal (argv[in], "--")) { - skip = FALSE; - - if (g_str_equal (argv[in], "--")) - { - break; - } - else if (g_str_equal (argv[in], "--help")) - { - want_help = TRUE; - } - else if (subcommand_name == NULL) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unknown or invalid admin instutil option: %s", argv[in]); - goto out; - } + break; } - /* The global short options */ - else - { - skip = FALSE; - for (i = 1; argv[in][i] != '\0'; i++) - { - switch (argv[in][i]) - { - case 'h': - want_help = TRUE; - break; - - default: - if (subcommand_name == NULL) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unknown or invalid admin instutil option: %s", argv[in]); - goto out; - } - break; - } - } - } - - /* Skipping this argument? */ - if (skip) - out--; - else - argv[out] = argv[in]; + argv[out] = argv[in]; } argc = out; - if (subcommand_name == NULL) - { - void (*print_func) (const gchar *format, ...) = want_help ? g_print : g_printerr; - - subcommand = admin_instutil_subcommands; - print_func ("usage: ostree admin instutil COMMAND [options]\n"); - print_func ("Builtin commands:\n"); - while (subcommand->name) - { - print_func (" %s\n", subcommand->name); - subcommand++; - } - - if (want_help) - ret = TRUE; - else - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "No command specified"); - goto out; - } - subcommand = admin_instutil_subcommands; while (subcommand->name) { @@ -149,14 +110,38 @@ ot_admin_builtin_instutil (int argc, char **argv, OstreeSysroot *sysroot, GCance if (!subcommand->name) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "Unknown admin instutil command '%s'", subcommand_name); + GOptionContext *context; + gs_free char *help; + + context = ostree_admin_instutil_option_context_new_with_commands (); + + /* This will not return for some options (e.g. --version). */ + if (ostree_admin_option_context_parse (context, NULL, &argc, &argv, NULL, cancellable, error)) + { + if (subcommand_name == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No \"admin instutil\" subcommand specified"); + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Unknown \"admin instutil\" subcommand '%s'", subcommand_name); + } + } + + help = g_option_context_get_help (context, FALSE, NULL); + g_printerr ("%s", help); + + g_option_context_free (context); + goto out; } - g_set_prgname (g_strdup_printf ("ostree admin instutil %s", subcommand_name)); + prgname = g_strdup_printf ("%s %s", g_get_prgname (), subcommand_name); + g_set_prgname (prgname); - if (!subcommand->fn (argc, argv, sysroot, cancellable, error)) + if (!subcommand->fn (argc, argv, cancellable, error)) goto out; ret = TRUE; diff --git a/src/ostree/ot-admin-builtin-os-init.c b/src/ostree/ot-admin-builtin-os-init.c index 19ed4a1c..a94837e8 100644 --- a/src/ostree/ot-admin-builtin-os-init.c +++ b/src/ostree/ot-admin-builtin-os-init.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" #include "otutil.h" @@ -34,18 +35,18 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_builtin_os_init (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_builtin_os_init (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeSysroot *sysroot = NULL; gboolean ret = FALSE; const char *osname = NULL; gs_unref_object GFile *deploy_dir = NULL; gs_unref_object GFile *dir = NULL; context = g_option_context_new ("OSNAME - Initialize empty state for given operating system"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (!ostree_sysroot_ensure_initialized (sysroot, cancellable, error)) diff --git a/src/ostree/ot-admin-builtin-status.c b/src/ostree/ot-admin-builtin-status.c index 9ce2f433..382c5e61 100644 --- a/src/ostree/ot-admin-builtin-status.c +++ b/src/ostree/ot-admin-builtin-status.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" #include "ostree.h" @@ -49,9 +50,10 @@ version_of_commit (OstreeRepo *repo, const char *checksum) } gboolean -ot_admin_builtin_status (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeSysroot *sysroot = NULL; gboolean ret = FALSE; gs_unref_object OstreeRepo *repo = NULL; OstreeDeployment *booted_deployment = NULL; @@ -60,9 +62,7 @@ ot_admin_builtin_status (int argc, char **argv, OstreeSysroot *sysroot, GCancell context = g_option_context_new ("List deployments"); - g_option_context_add_main_entries (context, options, NULL); - - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (!ostree_sysroot_load (sysroot, cancellable, error)) diff --git a/src/ostree/ot-admin-builtin-switch.c b/src/ostree/ot-admin-builtin-switch.c index 3900b81c..2f6c3343 100644 --- a/src/ostree/ot-admin-builtin-switch.c +++ b/src/ostree/ot-admin-builtin-switch.c @@ -20,6 +20,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" #include "ot-builtins-common.h" @@ -40,10 +41,11 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_builtin_switch (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; + gs_unref_object OstreeSysroot *sysroot = NULL; const char *new_provided_refspec = NULL; gs_unref_object OstreeRepo *repo = NULL; gs_free char *origin_refspec = NULL; @@ -66,9 +68,8 @@ ot_admin_builtin_switch (int argc, char **argv, OstreeSysroot *sysroot, GCancell GKeyFile *new_origin = NULL; context = g_option_context_new ("REF - Construct new tree from current origin and deploy it, if it changed"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (argc < 2) diff --git a/src/ostree/ot-admin-builtin-undeploy.c b/src/ostree/ot-admin-builtin-undeploy.c index 055209db..edf89bf4 100644 --- a/src/ostree/ot-admin-builtin-undeploy.c +++ b/src/ostree/ot-admin-builtin-undeploy.c @@ -22,6 +22,7 @@ #include +#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" #include "ostree.h" @@ -32,10 +33,11 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_builtin_undeploy (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; + gs_unref_object OstreeSysroot *sysroot = NULL; const char *deploy_index_str; int deploy_index; gs_unref_ptrarray GPtrArray *current_deployments = NULL; @@ -44,9 +46,7 @@ ot_admin_builtin_undeploy (int argc, char **argv, OstreeSysroot *sysroot, GCance context = g_option_context_new ("INDEX - Delete deployment INDEX"); - g_option_context_add_main_entries (context, options, NULL); - - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (argc < 2) diff --git a/src/ostree/ot-admin-builtin-upgrade.c b/src/ostree/ot-admin-builtin-upgrade.c index ffb93d4a..1dff0a53 100644 --- a/src/ostree/ot-admin-builtin-upgrade.c +++ b/src/ostree/ot-admin-builtin-upgrade.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-admin-builtins.h" #include "ot-admin-functions.h" #include "ot-builtins-common.h" @@ -45,10 +46,11 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_builtin_upgrade (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_builtin_upgrade (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; + gs_unref_object OstreeSysroot *sysroot = NULL; gs_unref_object OstreeSysrootUpgrader *upgrader = NULL; gs_free char *origin_remote = NULL; gs_free char *origin_ref = NULL; @@ -65,9 +67,8 @@ ot_admin_builtin_upgrade (int argc, char **argv, OstreeSysroot *sysroot, GCancel OstreeSysrootUpgraderPullFlags upgraderpullflags = 0; context = g_option_context_new ("Construct new tree from current origin and deploy it, if it changed"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (!ostree_sysroot_load (sysroot, cancellable, error)) diff --git a/src/ostree/ot-admin-builtins.h b/src/ostree/ot-admin-builtins.h index a4e5754f..9858f5b5 100644 --- a/src/ostree/ot-admin-builtins.h +++ b/src/ostree/ot-admin-builtins.h @@ -26,18 +26,18 @@ G_BEGIN_DECLS -gboolean ot_admin_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_os_init (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_install (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_instutil (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_init_fs (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_undeploy (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_cleanup (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_status (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_diff (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_switch (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_builtin_upgrade (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_selinux_ensure_labeled (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_os_init (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_install (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_instutil (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_init_fs (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_undeploy (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_deploy (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_cleanup (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_status (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_switch (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_builtin_upgrade (int argc, char **argv, GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/src/ostree/ot-admin-instutil-builtin-grub2-generate.c b/src/ostree/ot-admin-instutil-builtin-grub2-generate.c index 4aa58d01..617b1608 100644 --- a/src/ostree/ot-admin-instutil-builtin-grub2-generate.c +++ b/src/ostree/ot-admin-instutil-builtin-grub2-generate.c @@ -23,6 +23,7 @@ #include #include +#include "ot-main.h" #include "ot-admin-instutil-builtins.h" #include "ostree-cmdprivate.h" @@ -33,7 +34,7 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; guint bootversion; @@ -41,13 +42,12 @@ ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, OstreeSysroot * gs_unref_object OstreeSePolicy *sepolicy = NULL; gs_unref_ptrarray GPtrArray *deployments = NULL; GOptionContext *context = NULL; + gs_unref_object OstreeSysroot *sysroot = NULL; gs_unref_object GFile *deployment_path = NULL; context = g_option_context_new ("[BOOTVERSION] - generate GRUB2 configuration from given BLS entries"); - g_option_context_add_main_entries (context, options, NULL); - - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (argc >= 2) diff --git a/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c b/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c index 8bd0c8a1..7e9ca060 100644 --- a/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c +++ b/src/ostree/ot-admin-instutil-builtin-selinux-ensure-labeled.c @@ -23,6 +23,7 @@ #include #include +#include "ot-main.h" #include "ot-admin-instutil-builtins.h" #include "otutil.h" @@ -178,7 +179,7 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const char *policy_name; @@ -188,13 +189,12 @@ ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeS gs_unref_ptrarray GPtrArray *deployments = NULL; OstreeDeployment *first_deployment; GOptionContext *context = NULL; + gs_unref_object OstreeSysroot *sysroot = NULL; gs_unref_object GFile *deployment_path = NULL; context = g_option_context_new ("[SUBPATH PREFIX] - relabel all or part of a deployment"); - g_option_context_add_main_entries (context, options, NULL); - - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (!ostree_sysroot_load (sysroot, cancellable, error)) diff --git a/src/ostree/ot-admin-instutil-builtin-set-kargs.c b/src/ostree/ot-admin-instutil-builtin-set-kargs.c index b683f19c..cef52428 100644 --- a/src/ostree/ot-admin-instutil-builtin-set-kargs.c +++ b/src/ostree/ot-admin-instutil-builtin-set-kargs.c @@ -23,6 +23,7 @@ #include #include +#include "ot-main.h" #include "ot-admin-instutil-builtins.h" #include "otutil.h" @@ -43,20 +44,19 @@ static GOptionEntry options[] = { }; gboolean -ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error) +ot_admin_instutil_builtin_set_kargs (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; guint i; gs_unref_ptrarray GPtrArray *deployments = NULL; OstreeDeployment *first_deployment = NULL; GOptionContext *context = NULL; + gs_unref_object OstreeSysroot *sysroot = NULL; __attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL; context = g_option_context_new ("ARGS - set new kernel command line arguments"); - g_option_context_add_main_entries (context, options, NULL); - - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_admin_option_context_parse (context, options, &argc, &argv, &sysroot, cancellable, error)) goto out; if (!ostree_sysroot_load (sysroot, cancellable, error)) diff --git a/src/ostree/ot-admin-instutil-builtins.h b/src/ostree/ot-admin-instutil-builtins.h index 5442eb52..16abe424 100644 --- a/src/ostree/ot-admin-instutil-builtins.h +++ b/src/ostree/ot-admin-instutil-builtins.h @@ -24,9 +24,9 @@ G_BEGIN_DECLS -gboolean ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); -gboolean ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); +gboolean ot_admin_instutil_builtin_selinux_ensure_labeled (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_instutil_builtin_set_kargs (int argc, char **argv, GCancellable *cancellable, GError **error); +gboolean ot_admin_instutil_builtin_grub2_generate (int argc, char **argv, GCancellable *cancellable, GError **error); G_END_DECLS diff --git a/src/ostree/ot-builtin-admin.c b/src/ostree/ot-builtin-admin.c index 2165656c..47cf1b74 100644 --- a/src/ostree/ot-builtin-admin.c +++ b/src/ostree/ot-builtin-admin.c @@ -34,7 +34,7 @@ typedef struct { const char *name; - gboolean (*fn) (int argc, char **argv, OstreeSysroot *sysroot, GCancellable *cancellable, GError **error); + gboolean (*fn) (int argc, char **argv, GCancellable *cancellable, GError **error); } OstreeAdminCommand; static OstreeAdminCommand admin_subcommands[] = { @@ -51,19 +51,38 @@ static OstreeAdminCommand admin_subcommands[] = { { NULL, NULL } }; +static GOptionContext * +ostree_admin_option_context_new_with_commands (void) +{ + OstreeAdminCommand *command = admin_subcommands; + GOptionContext *context; + GString *summary; + + context = g_option_context_new ("--print-current-dir|COMMAND"); + + summary = g_string_new ("Builtin \"admin\" Commands:"); + + while (command->name != NULL) + { + g_string_append_printf (summary, "\n %s", command->name); + command++; + } + + g_option_context_set_summary (context, summary->str); + + g_string_free (summary, TRUE); + + return context; +} + gboolean -ostree_builtin_admin (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_admin (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - const char *opt_sysroot = "/"; const char *subcommand_name = NULL; OstreeAdminCommand *subcommand; - gs_unref_object GFile *sysroot_path = NULL; - gs_unref_object OstreeSysroot *sysroot = NULL; - gboolean want_help = FALSE; - gboolean want_current_dir = FALSE; - int in, out, i; - gboolean skip; + gs_free char *prgname = NULL; + int in, out; /* * Parse the global options. We rearrange the options as @@ -76,130 +95,24 @@ ostree_builtin_admin (int argc, char **argv, OstreeRepo *repo, GCancellable *can /* The non-option is the command, take it out of the arguments */ if (argv[in][0] != '-') { - skip = (subcommand_name == NULL); if (subcommand_name == NULL) - subcommand_name = argv[in]; + { + subcommand_name = argv[in]; + out--; + continue; + } } - /* The global long options */ - else if (argv[in][1] == '-') + else if (g_str_equal (argv[in], "--")) { - skip = FALSE; - - if (g_str_equal (argv[in], "--")) - { - break; - } - else if (g_str_equal (argv[in], "--help")) - { - want_help = TRUE; - } - else if (g_str_equal (argv[in], "--print-current-dir")) - { - want_current_dir = TRUE; - } - else if (g_str_equal (argv[in], "--sysroot") && in + 1 < argc) - { - opt_sysroot = argv[in + 1]; - skip = TRUE; - in++; - } - else if (g_str_has_prefix (argv[in], "--sysroot=")) - { - opt_sysroot = argv[in] + 10; - skip = TRUE; - } - else if (subcommand_name == NULL) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unknown or invalid admin option: %s", argv[in]); - goto out; - } + break; } - /* The global short options */ - else - { - skip = FALSE; - for (i = 1; argv[in][i] != '\0'; i++) - { - switch (argv[in][i]) - { - case 'h': - want_help = TRUE; - break; - - default: - if (subcommand_name == NULL) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unknown or invalid admin option: %s", argv[in]); - goto out; - } - break; - } - } - } - - /* Skipping this argument? */ - if (skip) - out--; - else - argv[out] = argv[in]; + argv[out] = argv[in]; } argc = out; - if (subcommand_name == NULL && (want_help || !want_current_dir)) - { - void (*print_func) (const gchar *format, ...) = want_help ? g_print : g_printerr; - - subcommand = admin_subcommands; - print_func ("usage: ostree admin [--sysroot=PATH] [--print-current-dir|COMMAND] [options]\n"); - print_func ("Builtin commands:\n"); - while (subcommand->name) - { - print_func (" %s\n", subcommand->name); - subcommand++; - } - - if (want_help) - ret = TRUE; - else - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "No command specified"); - goto out; - } - - sysroot_path = g_file_new_for_path (opt_sysroot); - sysroot = ostree_sysroot_new (sysroot_path); - - if (want_current_dir) - { - gs_unref_ptrarray GPtrArray *deployments = NULL; - OstreeDeployment *first_deployment; - gs_unref_object GFile *deployment_file = NULL; - gs_free char *deployment_path = NULL; - - if (!ostree_sysroot_load (sysroot, cancellable, error)) - goto out; - - deployments = ostree_sysroot_get_deployments (sysroot); - if (deployments->len == 0) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unable to find a deployment in sysroot"); - goto out; - } - first_deployment = deployments->pdata[0]; - deployment_file = ostree_sysroot_get_deployment_directory (sysroot, first_deployment); - deployment_path = g_file_get_path (deployment_file); - - g_print ("%s\n", deployment_path); - ret = TRUE; - goto out; - } - subcommand = admin_subcommands; while (subcommand->name) { @@ -210,14 +123,38 @@ ostree_builtin_admin (int argc, char **argv, OstreeRepo *repo, GCancellable *can if (!subcommand->name) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, - "Unknown admin command '%s'", subcommand_name); + GOptionContext *context; + gs_free char *help; + + context = ostree_admin_option_context_new_with_commands (); + + /* This will not return for some options (e.g. --version). */ + if (ostree_admin_option_context_parse (context, NULL, &argc, &argv, NULL, cancellable, error)) + { + if (subcommand_name == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No \"admin\" subcommand specified"); + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, + "Unknown \"admin\" subcommand '%s'", subcommand_name); + } + } + + help = g_option_context_get_help (context, FALSE, NULL); + g_printerr ("%s", help); + + g_option_context_free (context); + goto out; } - g_set_prgname (g_strdup_printf ("ostree admin %s", subcommand_name)); + prgname = g_strdup_printf ("%s %s", g_get_prgname (), subcommand_name); + g_set_prgname (prgname); - if (!subcommand->fn (argc, argv, sysroot, cancellable, error)) + if (!subcommand->fn (argc, argv, cancellable, error)) goto out; ret = TRUE; diff --git a/src/ostree/ot-builtin-cat.c b/src/ostree/ot-builtin-cat.c index 92d4c840..721f992a 100644 --- a/src/ostree/ot-builtin-cat.c +++ b/src/ostree/ot-builtin-cat.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -55,9 +56,10 @@ cat_one_file (GFile *f, } gboolean -ostree_builtin_cat (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_cat (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; int i; const char *rev; @@ -66,9 +68,8 @@ ostree_builtin_cat (int argc, char **argv, OstreeRepo *repo, GCancellable *cance gs_unref_object GFile *f = NULL; context = g_option_context_new ("COMMIT PATH... - Concatenate contents of files"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc <= 2) diff --git a/src/ostree/ot-builtin-checkout.c b/src/ostree/ot-builtin-checkout.c index 3f776192..b3284ef8 100644 --- a/src/ostree/ot-builtin-checkout.c +++ b/src/ostree/ot-builtin-checkout.c @@ -25,6 +25,7 @@ #include #include +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -170,9 +171,10 @@ process_many_checkouts (OstreeRepo *repo, } gboolean -ostree_builtin_checkout (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_checkout (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; const char *commit; const char *destination; @@ -180,9 +182,8 @@ ostree_builtin_checkout (int argc, char **argv, OstreeRepo *repo, GCancellable * gs_unref_object GFile *checkout_target = NULL; context = g_option_context_new ("COMMIT [DESTINATION] - Check out a commit into a filesystem tree"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc < 2) diff --git a/src/ostree/ot-builtin-checksum.c b/src/ostree/ot-builtin-checksum.c index e7d5dd87..5c534f84 100644 --- a/src/ostree/ot-builtin-checksum.c +++ b/src/ostree/ot-builtin-checksum.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "libgsystem.h" @@ -56,7 +57,7 @@ on_checksum_received (GObject *obj, } gboolean -ostree_builtin_checksum (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_checksum (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; gboolean ret = FALSE; @@ -64,9 +65,8 @@ ostree_builtin_checksum (int argc, char **argv, OstreeRepo *repo, GCancellable * AsyncChecksumData data = { 0, }; context = g_option_context_new ("PATH - Checksum a file or directory"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error)) goto out; if (argc > 1) diff --git a/src/ostree/ot-builtin-commit.c b/src/ostree/ot-builtin-commit.c index eda556e9..47c9b7c3 100644 --- a/src/ostree/ot-builtin-commit.c +++ b/src/ostree/ot-builtin-commit.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ot-editor.h" #include "ostree.h" @@ -309,9 +310,10 @@ parse_keyvalue_strings (char **strings, } gboolean -ostree_builtin_commit (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; gboolean skip_commit = FALSE; gs_unref_object GFile *arg = NULL; @@ -328,9 +330,8 @@ ostree_builtin_commit (int argc, char **argv, OstreeRepo *repo, GCancellable *ca OstreeRepoTransactionStats stats; context = g_option_context_new ("[PATH] - Commit a new revision"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (opt_statoverride_file) @@ -563,7 +564,8 @@ ostree_builtin_commit (int argc, char **argv, OstreeRepo *repo, GCancellable *ca ret = TRUE; out: - ostree_repo_abort_transaction (repo, cancellable, NULL); + if (repo) + ostree_repo_abort_transaction (repo, cancellable, NULL); if (context) g_option_context_free (context); if (modifier) diff --git a/src/ostree/ot-builtin-config.c b/src/ostree/ot-builtin-config.c index 56ddf86e..235e4985 100644 --- a/src/ostree/ot-builtin-config.c +++ b/src/ostree/ot-builtin-config.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -52,9 +53,10 @@ split_key_string (const char *k, } gboolean -ostree_builtin_config (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_config (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context = NULL; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; const char *op; const char *section_key; @@ -64,9 +66,8 @@ ostree_builtin_config (int argc, char **argv, OstreeRepo *repo, GCancellable *ca GKeyFile *config = NULL; context = g_option_context_new ("- Change configuration settings"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc < 2) diff --git a/src/ostree/ot-builtin-diff.c b/src/ostree/ot-builtin-diff.c index 65d55be2..7948c5da 100644 --- a/src/ostree/ot-builtin-diff.c +++ b/src/ostree/ot-builtin-diff.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -115,10 +116,11 @@ object_set_total_size (OstreeRepo *repo, } gboolean -ostree_builtin_diff (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_diff (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; const char *src; const char *target; gs_free char *src_prev = NULL; @@ -131,7 +133,7 @@ ostree_builtin_diff (int argc, char **argv, OstreeRepo *repo, GCancellable *canc context = g_option_context_new ("REV TARGETDIR - Compare directory TARGETDIR against revision REV"); g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc < 2) diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c index 79bb5f2b..333614cd 100644 --- a/src/ostree/ot-builtin-fsck.c +++ b/src/ostree/ot-builtin-fsck.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -233,10 +234,11 @@ fsck_reachable_objects_from_commits (OstreeRepo *repo, } gboolean -ostree_builtin_fsck (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_fsck (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; GHashTableIter hash_iter; gpointer key, value; gboolean found_corruption = FALSE; @@ -244,9 +246,8 @@ ostree_builtin_fsck (int argc, char **argv, OstreeRepo *repo, GCancellable *canc gs_unref_hashtable GHashTable *commits = NULL; context = g_option_context_new ("- Check the repository for consistency"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (!opt_quiet) diff --git a/src/ostree/ot-builtin-init.c b/src/ostree/ot-builtin-init.c index d57ed5c5..9aceda50 100644 --- a/src/ostree/ot-builtin-init.c +++ b/src/ostree/ot-builtin-init.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "libgsystem.h" @@ -34,16 +35,16 @@ static GOptionEntry options[] = { }; gboolean -ostree_builtin_init (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_init (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context = NULL; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; OstreeRepoMode mode; context = g_option_context_new ("- Initialize a new empty repository"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NO_CHECK, &repo, cancellable, error)) goto out; if (!ostree_repo_mode_from_string (opt_mode, &mode, error)) diff --git a/src/ostree/ot-builtin-log.c b/src/ostree/ot-builtin-log.c index 89445cd9..5147adb8 100644 --- a/src/ostree/ot-builtin-log.c +++ b/src/ostree/ot-builtin-log.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ot-dump.h" #include "ostree.h" @@ -77,20 +78,19 @@ out: gboolean ostree_builtin_log (int argc, char **argv, - OstreeRepo *repo, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; const char *rev; gs_free char *checksum = NULL; OstreeDumpFlags flags = OSTREE_DUMP_NONE; context = g_option_context_new ("REF - Show log starting at commit or ref"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (opt_raw) diff --git a/src/ostree/ot-builtin-ls.c b/src/ostree/ot-builtin-ls.c index f0a85be5..1fce5003 100644 --- a/src/ostree/ot-builtin-ls.c +++ b/src/ostree/ot-builtin-ls.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "ostree-repo-file.h" @@ -239,18 +240,18 @@ print_one_argument (OstreeRepo *repo, } gboolean -ostree_builtin_ls (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_ls (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; const char *rev; int i; gs_unref_object GFile *root = NULL; context = g_option_context_new ("COMMIT [PATH...] - List file paths"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc <= 1) diff --git a/src/ostree/ot-builtin-prune.c b/src/ostree/ot-builtin-prune.c index e483bf59..cd05b2f3 100644 --- a/src/ostree/ot-builtin-prune.c +++ b/src/ostree/ot-builtin-prune.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "libgsystem.h" @@ -38,10 +39,11 @@ static GOptionEntry options[] = { }; gboolean -ostree_builtin_prune (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_prune (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gs_free char *formatted_freed_size = NULL; OstreeRepoPruneFlags pruneflags = 0; gint n_objects_total; @@ -49,9 +51,8 @@ ostree_builtin_prune (int argc, char **argv, OstreeRepo *repo, GCancellable *can guint64 objsize_total; context = g_option_context_new ("- Search for unreachable objects"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (opt_refs_only) diff --git a/src/ostree/ot-builtin-pull-local.c b/src/ostree/ot-builtin-pull-local.c index bd9773b7..808773d5 100644 --- a/src/ostree/ot-builtin-pull-local.c +++ b/src/ostree/ot-builtin-pull-local.c @@ -25,6 +25,7 @@ #include #include +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -105,10 +106,11 @@ idle_print_status (gpointer user_data) } gboolean -ostree_builtin_pull_local (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; const char *src_repo_path; int i; GHashTableIter hash_iter; @@ -124,9 +126,8 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeRepo *repo, GCancellable OtLocalCloneData *data = &datav; context = g_option_context_new ("SRC_REPO [REFS...] - Copy data from SRC_REPO"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; data->dest_repo = g_object_ref (repo); @@ -270,6 +271,7 @@ ostree_builtin_pull_local (int argc, char **argv, OstreeRepo *repo, GCancellable g_object_unref (data->dest_repo); if (context) g_option_context_free (context); - ostree_repo_abort_transaction (repo, cancellable, NULL); + if (repo) + ostree_repo_abort_transaction (repo, cancellable, NULL); return ret; } diff --git a/src/ostree/ot-builtin-pull.c b/src/ostree/ot-builtin-pull.c index 46bf5c7e..ed013ca8 100644 --- a/src/ostree/ot-builtin-pull.c +++ b/src/ostree/ot-builtin-pull.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ot-builtins-common.h" #include "ostree.h" @@ -41,9 +42,10 @@ static int opt_depth = 0; }; gboolean -ostree_builtin_pull (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_pull (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; gs_free char *remote = NULL; OstreeRepoPullFlags pullflags = 0; @@ -52,9 +54,8 @@ ostree_builtin_pull (int argc, char **argv, OstreeRepo *repo, GCancellable *canc gs_unref_object OstreeAsyncProgress *progress = NULL; context = g_option_context_new ("REMOTE [BRANCH...] - Download data from remote repository"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc < 2) diff --git a/src/ostree/ot-builtin-refs.c b/src/ostree/ot-builtin-refs.c index 9c291fba..10dcc721 100644 --- a/src/ostree/ot-builtin-refs.c +++ b/src/ostree/ot-builtin-refs.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "libgsystem.h" @@ -34,19 +35,19 @@ static GOptionEntry options[] = { }; gboolean -ostree_builtin_refs (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; const char *refspec_prefix = NULL; gs_unref_hashtable GHashTable *refs = NULL; GHashTableIter hashiter; gpointer hashkey, hashvalue; context = g_option_context_new ("[PREFIX] - List refs"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc >= 2) @@ -87,6 +88,7 @@ ostree_builtin_refs (int argc, char **argv, OstreeRepo *repo, GCancellable *canc out: if (context) g_option_context_free (context); - ostree_repo_abort_transaction (repo, cancellable, NULL); + if (repo) + ostree_repo_abort_transaction (repo, cancellable, NULL); return ret; } diff --git a/src/ostree/ot-builtin-remote.c b/src/ostree/ot-builtin-remote.c index 6e63a489..541cf76f 100644 --- a/src/ostree/ot-builtin-remote.c +++ b/src/ostree/ot-builtin-remote.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -64,9 +65,10 @@ parse_keyvalue (const char *keyvalue, } gboolean -ostree_builtin_remote (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_remote (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; const char *op; gs_free char *key = NULL; @@ -75,9 +77,8 @@ ostree_builtin_remote (int argc, char **argv, OstreeRepo *repo, GCancellable *ca const char *remote_name; context = g_option_context_new ("OPERATION NAME [args] - Control remote repository configuration"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc < 3) diff --git a/src/ostree/ot-builtin-reset.c b/src/ostree/ot-builtin-reset.c index a2ab429e..0a72846d 100644 --- a/src/ostree/ot-builtin-reset.c +++ b/src/ostree/ot-builtin-reset.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -83,11 +84,11 @@ out: gboolean ostree_builtin_reset (int argc, char **argv, - OstreeRepo *repo, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; const char *ref; const char *target = NULL; @@ -95,9 +96,8 @@ ostree_builtin_reset (int argc, gs_free gchar *checksum = NULL; context = g_option_context_new ("[ARG] - Reset a ref to a previous commit"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc <= 2) @@ -130,6 +130,7 @@ ostree_builtin_reset (int argc, out: if (context) g_option_context_free (context); - ostree_repo_abort_transaction (repo, cancellable, NULL); + if (repo) + ostree_repo_abort_transaction (repo, cancellable, NULL); return ret; } diff --git a/src/ostree/ot-builtin-rev-parse.c b/src/ostree/ot-builtin-rev-parse.c index 6c60b6fd..f0835cae 100644 --- a/src/ostree/ot-builtin-rev-parse.c +++ b/src/ostree/ot-builtin-rev-parse.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -31,18 +32,18 @@ static GOptionEntry options[] = { }; gboolean -ostree_builtin_rev_parse (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_rev_parse (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; const char *rev = "master"; int i; gs_free char *resolved_rev = NULL; context = g_option_context_new ("REV - Output the target of a rev"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc < 2) diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c index 4b877828..d0949745 100644 --- a/src/ostree/ot-builtin-show.c +++ b/src/ostree/ot-builtin-show.c @@ -22,6 +22,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ot-dump.h" #include "ostree.h" @@ -199,17 +200,17 @@ print_if_found (OstreeRepo *repo, } gboolean -ostree_builtin_show (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_show (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; const char *rev; gs_free char *resolved_rev = NULL; context = g_option_context_new ("OBJECT - Output a metadata object"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (argc <= 1) diff --git a/src/ostree/ot-builtin-static-delta.c b/src/ostree/ot-builtin-static-delta.c index be535a62..6fa01a1b 100644 --- a/src/ostree/ot-builtin-static-delta.c +++ b/src/ostree/ot-builtin-static-delta.c @@ -20,6 +20,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -36,16 +37,16 @@ static GOptionEntry options[] = { }; gboolean -ostree_builtin_static_delta (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_static_delta (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; gs_unref_ptrarray GPtrArray *delta_names = NULL; context = g_option_context_new ("Manage static delta files"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (opt_apply) diff --git a/src/ostree/ot-builtin-summary.c b/src/ostree/ot-builtin-summary.c index 2f9cae5b..d7bed442 100644 --- a/src/ostree/ot-builtin-summary.c +++ b/src/ostree/ot-builtin-summary.c @@ -20,6 +20,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -32,15 +33,15 @@ static GOptionEntry options[] = { }; gboolean -ostree_builtin_summary (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_summary (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; + gs_unref_object OstreeRepo *repo = NULL; context = g_option_context_new ("Manage summary metadata"); - g_option_context_add_main_entries (context, options, NULL); - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (opt_update) diff --git a/src/ostree/ot-builtin-trivial-httpd.c b/src/ostree/ot-builtin-trivial-httpd.c index 5ca1e4bf..31c541a4 100644 --- a/src/ostree/ot-builtin-trivial-httpd.c +++ b/src/ostree/ot-builtin-trivial-httpd.c @@ -22,6 +22,7 @@ #include +#include "ot-main.h" #include "ot-builtins.h" #include "ostree.h" #include "otutil.h" @@ -322,7 +323,7 @@ on_dir_changed (GFileMonitor *mon, } gboolean -ostree_builtin_trivial_httpd (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +ostree_builtin_trivial_httpd (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context; @@ -334,9 +335,7 @@ ostree_builtin_trivial_httpd (int argc, char **argv, OstreeRepo *repo, GCancella context = g_option_context_new ("[DIR] - Simple webserver"); - g_option_context_add_main_entries (context, options, NULL); - - if (!g_option_context_parse (context, &argc, &argv, error)) + if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error)) goto out; if (argc > 1) diff --git a/src/ostree/ot-builtins-common.c b/src/ostree/ot-builtins-common.c index 5e3e4e64..9595ab4a 100644 --- a/src/ostree/ot-builtins-common.c +++ b/src/ostree/ot-builtins-common.c @@ -20,6 +20,7 @@ #include "config.h" +#include "ot-main.h" #include "ot-builtins-common.h" #include "otutil.h" diff --git a/src/ostree/ot-builtins.h b/src/ostree/ot-builtins.h index b8b6507f..d423a3a0 100644 --- a/src/ostree/ot-builtins.h +++ b/src/ostree/ot-builtins.h @@ -26,7 +26,7 @@ G_BEGIN_DECLS -#define BUILTINPROTO(name) gboolean ostree_builtin_ ## name (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error) +#define BUILTINPROTO(name) gboolean ostree_builtin_ ## name (int argc, char **argv, GCancellable *cancellable, GError **error) BUILTINPROTO(admin); BUILTINPROTO(cat); diff --git a/src/ostree/ot-main.c b/src/ostree/ot-main.c index 585e44f7..43e09a3f 100644 --- a/src/ostree/ot-main.c +++ b/src/ostree/ot-main.c @@ -24,6 +24,7 @@ #include +#include #include #include "ostree.h" @@ -31,28 +32,73 @@ #include "otutil.h" #include "libgsystem.h" +static char *opt_repo; +static char *opt_sysroot = "/"; +static gboolean opt_verbose; +static gboolean opt_version; +static gboolean opt_print_current_dir; + +static GOptionEntry global_entries[] = { + { "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose, "Print debug information during command processing", NULL }, + { "version", 0, 0, G_OPTION_ARG_NONE, &opt_version, "Print version information and exit", NULL }, + { NULL } +}; + +static GOptionEntry repo_entry[] = { + { "repo", 0, 0, G_OPTION_ARG_STRING, &opt_repo, "Path to OSTree repository (defaults to /sysroot/ostree/repo)", "PATH" }, + { NULL } +}; + +static GOptionEntry global_admin_entries[] = { + /* No description since it's hidden from --help output. */ + { "print-current-dir", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_print_current_dir, NULL, NULL }, + { "sysroot", 0, 0, G_OPTION_ARG_STRING, &opt_sysroot, "Create a new OSTree sysroot at PATH", "PATH" }, + { NULL } +}; + +static GOptionContext * +ostree_option_context_new_with_commands (OstreeCommand *commands) +{ + GOptionContext *context; + GString *summary; + + context = g_option_context_new ("COMMAND"); + + summary = g_string_new ("Builtin Commands:"); + + while (commands->name != NULL) + { + g_string_append_printf (summary, "\n %s", commands->name); + commands++; + } + + g_option_context_set_summary (context, summary->str); + + g_string_free (summary, TRUE); + + return context; +} + int -ostree_usage (char **argv, - OstreeCommand *commands, +ostree_usage (OstreeCommand *commands, gboolean is_error) { - OstreeCommand *command = commands; - void (*print_func) (const gchar *format, ...); + GOptionContext *context; + gs_free char *help; + + context = ostree_option_context_new_with_commands (commands); + + g_option_context_add_main_entries (context, global_entries, NULL); + + help = g_option_context_get_help (context, FALSE, NULL); if (is_error) - print_func = g_printerr; + g_printerr ("%s", help); else - print_func = g_print; + g_print ("%s", help); - print_func ("usage: %s --repo=PATH COMMAND [options]\n", - argv[0]); - print_func ("Builtin commands:\n"); + g_option_context_free (context); - while (command->name) - { - print_func (" %s\n", command->name); - command++; - } return (is_error ? 1 : 0); } @@ -78,24 +124,16 @@ ostree_run (int argc, OstreeCommand *command; GError *error = NULL; GCancellable *cancellable = NULL; - gs_unref_object OstreeRepo *repo = NULL; - const char *cmd = NULL; - const char *repo_arg = NULL; - gboolean want_help = FALSE; - gboolean skip; + const char *command_name = NULL; + gs_free char *prgname = NULL; gboolean success = FALSE; - int in, out, i; + int in, out; /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */ g_setenv ("GIO_USE_VFS", "local", TRUE); - g_set_prgname (argv[0]); - g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE, message_handler, NULL); - if (argc < 2) - return ostree_usage (argv, commands, TRUE); - /* * Parse the global options. We rearrange the options as * necessary, in order to pass relevant options through @@ -107,154 +145,67 @@ ostree_run (int argc, /* The non-option is the command, take it out of the arguments */ if (argv[in][0] != '-') { - skip = (cmd == NULL); - if (cmd == NULL) - cmd = argv[in]; + if (command_name == NULL) + { + command_name = argv[in]; + out--; + continue; + } } - /* The global long options */ - else if (argv[in][1] == '-') + else if (g_str_equal (argv[in], "--")) { - skip = FALSE; - - if (g_str_equal (argv[in], "--")) - { - break; - } - else if (g_str_equal (argv[in], "--help")) - { - want_help = TRUE; - } - else if (g_str_equal (argv[in], "--repo") && in + 1 < argc) - { - repo_arg = argv[in + 1]; - skip = TRUE; - in++; - } - else if (g_str_has_prefix (argv[in], "--repo=")) - { - repo_arg = argv[in] + 7; - skip = TRUE; - } - else if (g_str_equal (argv[in], "--verbose")) - { - g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, message_handler, NULL); - skip = TRUE; - } - else if (cmd == NULL && g_str_equal (argv[in], "--version")) - { - g_print ("%s\n %s\n", PACKAGE_STRING, OSTREE_FEATURES); - return 0; - } - else if (cmd == NULL) - { - g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unknown or invalid global option: %s", argv[in]); - goto out; - } + break; } - /* The global short options */ - else - { - skip = FALSE; - for (i = 1; argv[in][i] != '\0'; i++) - { - switch (argv[in][i]) - { - case 'h': - want_help = TRUE; - break; - case 'v': - g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, message_handler, NULL); - skip = TRUE; - break; - default: - if (cmd == NULL) - { - g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unknown or invalid global option: %s", argv[in]); - goto out; - } - break; - } - } - } - - /* Skipping this argument? */ - if (skip) - out--; - else - argv[out] = argv[in]; + argv[out] = argv[in]; } argc = out; - if (cmd == NULL) - { - if (want_help) - { - success = TRUE; - } - else - { - g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, - "No command specified"); - } - ostree_usage (argv, commands, !want_help); - goto out; - } - command = commands; while (command->name) { - if (g_strcmp0 (cmd, command->name) == 0) + if (g_strcmp0 (command_name, command->name) == 0) break; command++; } if (!command->fn) { - gs_free char *msg = g_strdup_printf ("Unknown command '%s'", cmd); - g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, msg); - goto out; - } + GOptionContext *context; + gs_free char *help; - g_set_prgname (g_strdup_printf ("ostree %s", cmd)); + context = ostree_option_context_new_with_commands (commands); - if (repo_arg == NULL && !want_help && - !(command->flags & OSTREE_BUILTIN_FLAG_NO_REPO)) - { - GError *temp_error = NULL; - repo = ostree_repo_new_default (); - if (!ostree_repo_open (repo, cancellable, &temp_error)) + /* This will not return for some options (e.g. --version). */ + if (ostree_option_context_parse (context, NULL, &argc, &argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, &error)) { - if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + if (command_name == NULL) { g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Command requires a --repo argument"); - g_error_free (temp_error); - ostree_usage (argv, commands, TRUE); + "No command specified"); } else { - g_propagate_error (&error, temp_error); + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Unknown command '%s'", command_name); } - goto out; - } - } - else if (repo_arg) - { - gs_unref_object GFile *repo_file = g_file_new_for_path (repo_arg); - repo = ostree_repo_new (repo_file); - if (!(command->flags & OSTREE_BUILTIN_FLAG_NO_CHECK)) - { - if (!ostree_repo_open (repo, cancellable, &error)) - goto out; } + + help = g_option_context_get_help (context, FALSE, NULL); + g_printerr ("%s", help); + + g_option_context_free (context); + + goto out; } + + prgname = g_strdup_printf ("%s %s", g_get_prgname (), command_name); + g_set_prgname (prgname); + - if (!command->fn (argc, argv, repo, cancellable, &error)) + if (!command->fn (argc, argv, cancellable, &error)) goto out; success = TRUE; @@ -268,3 +219,143 @@ ostree_run (int argc, } return 0; } + +gboolean +ostree_option_context_parse (GOptionContext *context, + const GOptionEntry *main_entries, + int *argc, + char ***argv, + OstreeBuiltinFlags flags, + OstreeRepo **out_repo, + GCancellable *cancellable, + GError **error) +{ + gs_unref_object OstreeRepo *repo = NULL; + gboolean success = FALSE; + + /* Entries are listed in --help output in the order added. We add the + * main entries ourselves so that we can add the --repo entry first. */ + + if (!(flags & OSTREE_BUILTIN_FLAG_NO_REPO)) + g_option_context_add_main_entries (context, repo_entry, NULL); + + if (main_entries != NULL) + g_option_context_add_main_entries (context, main_entries, NULL); + + g_option_context_add_main_entries (context, global_entries, NULL); + + if (!g_option_context_parse (context, argc, argv, error)) + return FALSE; + + if (opt_version) + { + g_print ("%s\n %s\n", PACKAGE_STRING, OSTREE_FEATURES); + exit (EXIT_SUCCESS); + } + + if (opt_verbose) + g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, message_handler, NULL); + + if (opt_repo == NULL && !(flags & OSTREE_BUILTIN_FLAG_NO_REPO)) + { + GError *local_error = NULL; + + repo = ostree_repo_new_default (); + if (!ostree_repo_open (repo, cancellable, &local_error)) + { + if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + { + gs_free char *help = NULL; + + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Command requires a --repo argument"); + g_error_free (local_error); + + help = g_option_context_get_help (context, FALSE, NULL); + g_printerr ("%s", help); + } + else + { + g_propagate_error (error, local_error); + } + goto out; + } + } + else if (opt_repo != NULL) + { + gs_unref_object GFile *repo_file = g_file_new_for_path (opt_repo); + + repo = ostree_repo_new (repo_file); + if (!(flags & OSTREE_BUILTIN_FLAG_NO_CHECK)) + { + if (!ostree_repo_open (repo, cancellable, error)) + goto out; + } + } + + gs_transfer_out_value (out_repo, &repo); + + success = TRUE; + +out: + return success; +} + +gboolean +ostree_admin_option_context_parse (GOptionContext *context, + const GOptionEntry *main_entries, + int *argc, + char ***argv, + OstreeSysroot **out_sysroot, + GCancellable *cancellable, + GError **error) +{ + gs_unref_object GFile *sysroot_path = NULL; + gs_unref_object OstreeSysroot *sysroot = NULL; + gboolean success = FALSE; + + /* Entries are listed in --help output in the order added. We add the + * main entries ourselves so that we can add the --sysroot entry first. */ + + g_option_context_add_main_entries (context, global_admin_entries, NULL); + + if (!ostree_option_context_parse (context, main_entries, argc, argv, OSTREE_BUILTIN_FLAG_NO_REPO, NULL, cancellable, error)) + goto out; + + sysroot_path = g_file_new_for_path (opt_sysroot); + sysroot = ostree_sysroot_new (sysroot_path); + + if (opt_print_current_dir) + { + gs_unref_ptrarray GPtrArray *deployments = NULL; + OstreeDeployment *first_deployment; + gs_unref_object GFile *deployment_file = NULL; + gs_free char *deployment_path = NULL; + + if (!ostree_sysroot_load (sysroot, cancellable, error)) + goto out; + + deployments = ostree_sysroot_get_deployments (sysroot); + if (deployments->len == 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Unable to find a deployment in sysroot"); + goto out; + } + first_deployment = deployments->pdata[0]; + deployment_file = ostree_sysroot_get_deployment_directory (sysroot, first_deployment); + deployment_path = g_file_get_path (deployment_file); + + g_print ("%s\n", deployment_path); + + exit (EXIT_SUCCESS); + } + + gs_transfer_out_value (out_sysroot, &sysroot); + + success = TRUE; + +out: + return success; +} + diff --git a/src/ostree/ot-main.h b/src/ostree/ot-main.h index 49e310e8..5f31b240 100644 --- a/src/ostree/ot-main.h +++ b/src/ostree/ot-main.h @@ -32,10 +32,22 @@ typedef enum { typedef struct { const char *name; - gboolean (*fn) (int argc, char **argv, OstreeRepo *repo, GCancellable *cancellable, GError **error); - int flags; /* OstreeBuiltinFlags */ + gboolean (*fn) (int argc, char **argv, GCancellable *cancellable, GError **error); } OstreeCommand; int ostree_run (int argc, char **argv, OstreeCommand *commands, GError **error); -int ostree_usage (char **argv, OstreeCommand *commands, gboolean is_error); +int ostree_usage (OstreeCommand *commands, gboolean is_error); + +gboolean ostree_option_context_parse (GOptionContext *context, + const GOptionEntry *main_entries, + int *argc, char ***argv, + OstreeBuiltinFlags flags, + OstreeRepo **out_repo, + GCancellable *cancellable, GError **error); + +gboolean ostree_admin_option_context_parse (GOptionContext *context, + const GOptionEntry *main_entries, + int *argc, char ***argv, + OstreeSysroot **out_sysroot, + GCancellable *cancellable, GError **error);