app: Make hidden/experimental flags for command parsing

I think this ends up being cleaner - the properties of
a command are now consistently represented as flags.

Prep work for https://github.com/projectatomic/rpm-ostree/issues/682

Closes: #683
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-03-15 16:20:03 -04:00 committed by Atomic Bot
parent 7453c955df
commit 7226b4135a
6 changed files with 44 additions and 56 deletions

View File

@ -33,7 +33,7 @@
#include "libglnx.h"
static RpmOstreeCommand supported_commands[] = {
static RpmOstreeCommand commands[] = {
#ifdef HAVE_COMPOSE_TOOLING
{ "compose", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD | RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT,
rpmostree_builtin_compose },
@ -60,27 +60,19 @@ static RpmOstreeCommand supported_commands[] = {
rpmostree_builtin_pkg_add },
{ "uninstall", RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT,
rpmostree_builtin_pkg_remove },
{ NULL }
};
static RpmOstreeCommand legacy_alias_commands[] = {
{ "pkg-add", RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT,
/* Legacy aliases */
{ "pkg-add", RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT | RPM_OSTREE_BUILTIN_FLAG_HIDDEN,
rpmostree_builtin_pkg_add },
{ "pkg-remove", RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT,
{ "pkg-remove", RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT | RPM_OSTREE_BUILTIN_FLAG_HIDDEN,
rpmostree_builtin_pkg_remove },
{ NULL }
};
static RpmOstreeCommand experimental_commands[] = {
{ "internals", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD,
/* Experimental */
{ "internals", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD | RPM_OSTREE_BUILTIN_FLAG_EXPERIMENTAL,
rpmostree_builtin_internals },
{ "container", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD,
{ "container", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD | RPM_OSTREE_BUILTIN_FLAG_EXPERIMENTAL,
rpmostree_builtin_container },
{ NULL }
};
static RpmOstreeCommand hidden_commands[] = {
{ "start-daemon", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD | RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT,
/* Hidden */
{ "start-daemon", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD | RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT |
RPM_OSTREE_BUILTIN_FLAG_HIDDEN,
rpmostree_builtin_start_daemon },
{ NULL }
};
@ -103,7 +95,7 @@ static GOptionEntry daemon_entries[] = {
static GOptionContext *
option_context_new_with_commands (void)
{
RpmOstreeCommand *command = supported_commands;
RpmOstreeCommand *command = commands;
GOptionContext *context;
GString *summary;
@ -113,7 +105,10 @@ option_context_new_with_commands (void)
while (command->name != NULL)
{
g_string_append_printf (summary, "\n %s", command->name);
gboolean is_hidden = (command->flags & RPM_OSTREE_BUILTIN_FLAG_HIDDEN) > 0;
gboolean is_experimental = (command->flags & RPM_OSTREE_BUILTIN_FLAG_EXPERIMENTAL) > 0;
if (!(is_hidden || is_experimental))
g_string_append_printf (summary, "\n %s", command->name);
command++;
}
@ -219,27 +214,14 @@ rpmostree_print_gpg_verify_result (OstreeGpgVerifyResult *result)
static RpmOstreeCommand *
lookup_command_of_type (RpmOstreeCommand *commands,
const char *name,
const char *type)
lookup_command (const char *name)
{
RpmOstreeCommand *command = commands;
const int is_tty = isatty (1);
const char *bold_prefix;
const char *bold_suffix;
bold_prefix = is_tty ? "\x1b[1m" : "";
bold_suffix = is_tty ? "\x1b[0m" : "";
while (command->name)
{
if (g_strcmp0 (name, command->name) == 0)
{
if (type)
g_printerr ("%snotice%s: %s is %s command and subject to change.\n",
bold_prefix, bold_suffix, name, type);
return command;
}
return command;
command++;
}
return NULL;
@ -247,12 +229,25 @@ lookup_command_of_type (RpmOstreeCommand *commands,
const char *
rpmostree_subcommand_parse (int *inout_argc,
char **inout_argv)
char **inout_argv,
RpmOstreeCommandInvocation *invocation)
{
const int argc = *inout_argc;
const char *command_name = NULL;
int in, out;
if (invocation && (invocation->command->flags & RPM_OSTREE_BUILTIN_FLAG_EXPERIMENTAL) > 0)
{
const int is_tty = isatty (1);
const char *bold_prefix = is_tty ? "\x1b[1m" : "";
const char *bold_suffix = is_tty ? "\x1b[0m" : "";
g_assert (invocation);
g_printerr ("%snotice%s: %s is an experimental command and subject to change.\n",
bold_prefix, bold_suffix, invocation->command->name);
}
for (in = 1, out = 1; in < argc; in++, out++)
{
/* The non-option is the command, take it out of the arguments */
@ -300,21 +295,13 @@ main (int argc,
* necessary, in order to pass relevant options through
* to the commands, but also have them take effect globally.
*/
command_name = rpmostree_subcommand_parse (&argc, argv);
command_name = rpmostree_subcommand_parse (&argc, argv, NULL);
/* Keep the "rpm" command working for backward-compatibility. */
if (g_strcmp0 (command_name, "rpm") == 0)
command_name = "db";
command = lookup_command_of_type (supported_commands, command_name, NULL);
if (!command)
command = lookup_command_of_type (legacy_alias_commands, command_name, NULL);
if (!command)
command = lookup_command_of_type (experimental_commands, command_name, "an experimental");
if (!command)
command = lookup_command_of_type (hidden_commands, command_name, NULL);
command = lookup_command (command_name);
if (!command)
{

View File

@ -29,7 +29,7 @@
#include <glib/gi18n.h>
static RpmOstreeCommand compose_subcommands[] = {
{ "tree", RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT,
{ "tree", RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD | RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT,
rpmostree_compose_builtin_tree },
{ NULL, 0, NULL }
};
@ -68,7 +68,7 @@ rpmostree_builtin_compose (int argc, char **argv,
g_autofree char *prgname = NULL;
int exit_status = EXIT_SUCCESS;
subcommand_name = rpmostree_subcommand_parse (&argc, argv);
subcommand_name = rpmostree_subcommand_parse (&argc, argv, invocation);
subcommand = compose_subcommands;
while (subcommand->name)

View File

@ -66,8 +66,7 @@ rpmostree_builtin_container (int argc, char **argv, RpmOstreeCommandInvocation *
g_autofree char *prgname = NULL;
int exit_status = EXIT_SUCCESS;
subcommand_name = rpmostree_subcommand_parse (&argc, argv);
subcommand_name = rpmostree_subcommand_parse (&argc, argv, invocation);
subcommand = container_subcommands;
while (subcommand->name)
{
@ -82,13 +81,13 @@ rpmostree_builtin_container (int argc, char **argv, RpmOstreeCommandInvocation *
container_option_context_new_with_commands ();
g_autofree char *help = NULL;
/* This will not return for some options (e.g. --version). */
(void) rpmostree_option_context_parse (context, NULL,
&argc, &argv,
invocation,
cancellable,
NULL,
NULL);
if (subcommand_name == NULL)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,

View File

@ -133,7 +133,7 @@ rpmostree_builtin_db (int argc, char **argv,
g_autofree char *prgname = NULL;
int exit_status = EXIT_SUCCESS;
subcommand_name = rpmostree_subcommand_parse (&argc, argv);
subcommand_name = rpmostree_subcommand_parse (&argc, argv, invocation);
subcommand = rpm_subcommands;
while (subcommand->name)

View File

@ -69,8 +69,7 @@ rpmostree_builtin_internals (int argc, char **argv,
g_autofree char *prgname = NULL;
int exit_status = EXIT_SUCCESS;
subcommand_name = rpmostree_subcommand_parse (&argc, argv);
subcommand_name = rpmostree_subcommand_parse (&argc, argv, invocation);
subcommand = internals_subcommands;
while (subcommand->name)
{
@ -84,13 +83,13 @@ rpmostree_builtin_internals (int argc, char **argv,
g_autoptr(GOptionContext) context = internals_option_context_new_with_commands ();
g_autofree char *help = NULL;
/* This will not return for some options (e.g. --version). */
(void) rpmostree_option_context_parse (context, NULL,
&argc, &argv,
invocation,
cancellable,
NULL,
NULL);
if (subcommand_name == NULL)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,

View File

@ -33,6 +33,8 @@ typedef enum {
RPM_OSTREE_BUILTIN_FLAG_NONE = 0,
RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD = 1 << 0,
RPM_OSTREE_BUILTIN_FLAG_REQUIRES_ROOT = 1 << 1,
RPM_OSTREE_BUILTIN_FLAG_EXPERIMENTAL = 1 << 2,
RPM_OSTREE_BUILTIN_FLAG_HIDDEN = 1 << 3,
} RpmOstreeBuiltinFlags;
typedef struct RpmOstreeCommand RpmOstreeCommand;
@ -75,7 +77,8 @@ BUILTINPROTO(start_daemon);
#undef BUILTINPROTO
const char *rpmostree_subcommand_parse (int *inout_argc,
char **inout_argv);
char **inout_argv,
RpmOstreeCommandInvocation *invocation);
gboolean rpmostree_option_context_parse (GOptionContext *context,
const GOptionEntry *main_entries,