Better parsing for global ostree options
* Specifying global options after the command for a more natural: # ostree commit --repo=/path/to/repo ... * Support asking for --help without --repo # ostree commit --help * Support short form of -h * Support specifying --repo without equals sign # ostree --repo /path/to/repo commit ... * Support global --help and -h # ostree --help * Ditto for ostree admin sub commands * Removed some leaky code https://bugzilla.gnome.org/show_bug.cgi?id=705903
This commit is contained in:
parent
4765726ea1
commit
1f8c7a2524
|
|
@ -54,19 +54,95 @@ ostree_builtin_admin (int argc, char **argv, GFile *repo_path, GCancellable *can
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
const char *opt_sysroot = "/";
|
const char *opt_sysroot = "/";
|
||||||
const char *subcommand_name;
|
const char *subcommand_name = NULL;
|
||||||
OstreeAdminCommand *subcommand;
|
OstreeAdminCommand *subcommand;
|
||||||
int subcmd_argc;
|
|
||||||
gs_unref_object GFile *sysroot = NULL;
|
gs_unref_object GFile *sysroot = NULL;
|
||||||
char **subcmd_argv = NULL;
|
gboolean want_help = FALSE;
|
||||||
|
int in, out, i;
|
||||||
|
gboolean skip;
|
||||||
|
|
||||||
if (argc > 1 && g_str_has_prefix (argv[1], "--sysroot="))
|
/*
|
||||||
|
* Parse the global options. We rearrange the options as
|
||||||
|
* necessary, in order to pass relevant options through
|
||||||
|
* to the commands, but also have them take effect globally.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (in = 1, out = 1; in < argc; in++, out++)
|
||||||
{
|
{
|
||||||
opt_sysroot = argv[1] + strlen ("--sysroot=");
|
/* The non-option is the command, take it out of the arguments */
|
||||||
argc--;
|
if (argv[in][0] != '-')
|
||||||
argv++;
|
{
|
||||||
|
skip = (subcommand_name == NULL);
|
||||||
|
if (subcommand_name == NULL)
|
||||||
|
subcommand_name = argv[in];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The global long options */
|
||||||
|
else if (argv[in][1] == '-')
|
||||||
|
{
|
||||||
|
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], "--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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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];
|
||||||
}
|
}
|
||||||
else if (argc <= 1 || g_str_has_prefix (argv[1], "--help"))
|
|
||||||
|
argc = out;
|
||||||
|
|
||||||
|
if (subcommand_name == NULL || want_help)
|
||||||
{
|
{
|
||||||
subcommand = admin_subcommands;
|
subcommand = admin_subcommands;
|
||||||
g_print ("usage: ostree admin --sysroot=PATH COMMAND [options]\n");
|
g_print ("usage: ostree admin --sysroot=PATH COMMAND [options]\n");
|
||||||
|
|
@ -76,11 +152,9 @@ ostree_builtin_admin (int argc, char **argv, GFile *repo_path, GCancellable *can
|
||||||
g_print (" %s\n", subcommand->name);
|
g_print (" %s\n", subcommand->name);
|
||||||
subcommand++;
|
subcommand++;
|
||||||
}
|
}
|
||||||
return argc <= 1 ? 1 : 0;
|
return subcommand_name == NULL ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
subcommand_name = argv[1];
|
|
||||||
|
|
||||||
subcommand = admin_subcommands;
|
subcommand = admin_subcommands;
|
||||||
while (subcommand->name)
|
while (subcommand->name)
|
||||||
{
|
{
|
||||||
|
|
@ -92,14 +166,12 @@ ostree_builtin_admin (int argc, char **argv, GFile *repo_path, GCancellable *can
|
||||||
if (!subcommand->name)
|
if (!subcommand->name)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||||
"Unknown command '%s'", subcommand_name);
|
"Unknown admin command '%s'", subcommand_name);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostree_prep_builtin_argv (subcommand_name, argc-2, argv+2, &subcmd_argc, &subcmd_argv);
|
|
||||||
|
|
||||||
sysroot = g_file_new_for_path (opt_sysroot);
|
sysroot = g_file_new_for_path (opt_sysroot);
|
||||||
if (!subcommand->fn (subcmd_argc, subcmd_argv, sysroot, cancellable, error))
|
if (!subcommand->fn (argc, argv, sysroot, cancellable, error))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
|
||||||
|
|
@ -55,26 +55,6 @@ ostree_usage (char **argv,
|
||||||
return (is_error ? 1 : 0);
|
return (is_error ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
ostree_prep_builtin_argv (const char *builtin,
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
int *out_argc,
|
|
||||||
char ***out_argv)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char **cmd_argv;
|
|
||||||
|
|
||||||
cmd_argv = g_new0 (char *, argc + 2);
|
|
||||||
|
|
||||||
cmd_argv[0] = (char*)builtin;
|
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
cmd_argv[i+1] = argv[i];
|
|
||||||
cmd_argv[i+1] = NULL;
|
|
||||||
*out_argc = argc+1;
|
|
||||||
*out_argv = cmd_argv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
ostree_run (int argc,
|
ostree_run (int argc,
|
||||||
char **argv,
|
char **argv,
|
||||||
|
|
@ -84,14 +64,13 @@ ostree_run (int argc,
|
||||||
OstreeCommand *command;
|
OstreeCommand *command;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GCancellable *cancellable = NULL;
|
GCancellable *cancellable = NULL;
|
||||||
int cmd_argc;
|
|
||||||
char **cmd_argv = NULL;
|
|
||||||
gboolean have_repo_arg;
|
|
||||||
const char *cmd = NULL;
|
const char *cmd = NULL;
|
||||||
const char *repo = NULL;
|
const char *repo = NULL;
|
||||||
const char *host_repo_path = "/ostree/repo";
|
const char *host_repo_path = "/ostree/repo";
|
||||||
GFile *repo_file = NULL;
|
GFile *repo_file = NULL;
|
||||||
int arg_off;
|
gboolean want_help = FALSE;
|
||||||
|
gboolean skip;
|
||||||
|
int in, out, i;
|
||||||
|
|
||||||
/* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */
|
/* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */
|
||||||
g_setenv ("GIO_USE_VFS", "local", TRUE);
|
g_setenv ("GIO_USE_VFS", "local", TRUE);
|
||||||
|
|
@ -103,23 +82,101 @@ ostree_run (int argc,
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
return ostree_usage (argv, commands, TRUE);
|
return ostree_usage (argv, commands, TRUE);
|
||||||
|
|
||||||
if (g_str_has_prefix (argv[1], "--version"))
|
/*
|
||||||
|
* Parse the global options. We rearrange the options as
|
||||||
|
* necessary, in order to pass relevant options through
|
||||||
|
* to the commands, but also have them take effect globally.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (in = 1, out = 1; in < argc; in++, out++)
|
||||||
{
|
{
|
||||||
g_print ("%s\n %s\n", PACKAGE_STRING, OSTREE_FEATURES);
|
/* The non-option is the command, take it out of the arguments */
|
||||||
return 0;
|
if (argv[in][0] != '-')
|
||||||
|
{
|
||||||
|
skip = (cmd == NULL);
|
||||||
|
if (cmd == NULL)
|
||||||
|
cmd = argv[in];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The global long options */
|
||||||
|
else if (argv[in][1] == '-')
|
||||||
|
{
|
||||||
|
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 = argv[in + 1];
|
||||||
|
skip = TRUE;
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
else if (g_str_has_prefix (argv[in], "--repo="))
|
||||||
|
{
|
||||||
|
repo = argv[in] + 7;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 (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];
|
||||||
}
|
}
|
||||||
|
|
||||||
have_repo_arg = g_str_has_prefix (argv[1], "--repo=");
|
argc = out;
|
||||||
|
|
||||||
if (!have_repo_arg)
|
if (cmd == NULL)
|
||||||
{
|
{
|
||||||
arg_off = 2;
|
if (!want_help)
|
||||||
cmd = argv[arg_off-1];
|
{
|
||||||
}
|
g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
else
|
"No command specified");
|
||||||
{
|
}
|
||||||
arg_off = 3;
|
ostree_usage (argv, commands, TRUE);
|
||||||
cmd = argv[arg_off-1];
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
command = commands;
|
command = commands;
|
||||||
|
|
@ -139,12 +196,11 @@ ostree_run (int argc,
|
||||||
|
|
||||||
g_set_prgname (g_strdup_printf ("ostree %s", cmd));
|
g_set_prgname (g_strdup_printf ("ostree %s", cmd));
|
||||||
|
|
||||||
if (!(command->flags & OSTREE_BUILTIN_FLAG_NO_REPO))
|
if (repo == NULL && !want_help &&
|
||||||
|
!(command->flags & OSTREE_BUILTIN_FLAG_NO_REPO))
|
||||||
{
|
{
|
||||||
if (have_repo_arg)
|
if (g_file_test ("objects", G_FILE_TEST_IS_DIR)
|
||||||
repo = argv[1] + strlen ("--repo=");
|
&& g_file_test ("config", G_FILE_TEST_IS_REGULAR))
|
||||||
else if (g_file_test ("objects", G_FILE_TEST_IS_DIR)
|
|
||||||
&& g_file_test ("config", G_FILE_TEST_IS_REGULAR))
|
|
||||||
repo = ".";
|
repo = ".";
|
||||||
else if (g_file_test (host_repo_path, G_FILE_TEST_EXISTS))
|
else if (g_file_test (host_repo_path, G_FILE_TEST_EXISTS))
|
||||||
repo = host_repo_path;
|
repo = host_repo_path;
|
||||||
|
|
@ -160,13 +216,10 @@ ostree_run (int argc,
|
||||||
if (repo)
|
if (repo)
|
||||||
repo_file = g_file_new_for_path (repo);
|
repo_file = g_file_new_for_path (repo);
|
||||||
|
|
||||||
ostree_prep_builtin_argv (cmd, argc-arg_off, argv+arg_off, &cmd_argc, &cmd_argv);
|
if (!command->fn (argc, argv, repo_file, cancellable, &error))
|
||||||
|
|
||||||
if (!command->fn (cmd_argc, cmd_argv, repo_file, cancellable, &error))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
g_free (cmd_argv);
|
|
||||||
g_clear_object (&repo_file);
|
g_clear_object (&repo_file);
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -35,13 +35,6 @@ typedef struct {
|
||||||
int flags; /* OstreeBuiltinFlags */
|
int flags; /* OstreeBuiltinFlags */
|
||||||
} OstreeCommand;
|
} OstreeCommand;
|
||||||
|
|
||||||
void
|
|
||||||
ostree_prep_builtin_argv (const char *builtin,
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
int *out_argc,
|
|
||||||
char ***out_argv);
|
|
||||||
|
|
||||||
int ostree_main (int argc, char **argv, OstreeCommand *commands);
|
int ostree_main (int argc, char **argv, OstreeCommand *commands);
|
||||||
|
|
||||||
int ostree_run (int argc, char **argv, OstreeCommand *commands, GError **error);
|
int ostree_run (int argc, char **argv, OstreeCommand *commands, GError **error);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue