summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Mazzoli <francesco@rabbitmq.com>2012-05-17 11:51:19 +0100
committerFrancesco Mazzoli <francesco@rabbitmq.com>2012-05-17 11:51:19 +0100
commit3213f1d863ea0b74934ce48912a6a6f71c3efa52 (patch)
tree2118fecd49139710b6aa01670c4d4bf74bd1c843
parent2d95d0e087e34242aa7c332b40d9bd405a2c4411 (diff)
downloadrabbitmq-server-3213f1d863ea0b74934ce48912a6a6f71c3efa52.tar.gz
change to how `get_options/4' handles flags
Now it doesn't complain on flags that should not be there, it simply eats only the flags relevant to the command.
-rw-r--r--src/rabbit_control.erl13
-rw-r--r--src/rabbit_misc.erl60
-rw-r--r--src/rabbit_plugins.erl12
3 files changed, 49 insertions, 36 deletions
diff --git a/src/rabbit_control.erl b/src/rabbit_control.erl
index 1920a314..554a31f9 100644
--- a/src/rabbit_control.erl
+++ b/src/rabbit_control.erl
@@ -132,7 +132,12 @@ start() ->
io:format(Format ++ " ...~n", Args1)
end
end,
-
+ PrintInvalidCommandError =
+ fun () ->
+ print_error("invalid command '~s'",
+ [string:join([atom_to_list(Command) | Args], " ")])
+ end,
+
%% The reason we don't use a try/catch here is that rpc:call turns
%% thrown errors into normal return values
case catch action(Command, Node, Args, Opts, Inform) of
@@ -142,6 +147,12 @@ start() ->
false -> io:format("...done.~n")
end,
rabbit_misc:quit(0);
+ {'EXIT', {function_clause, [{?MODULE, action, _} | _]}} -> %% < R15
+ PrintInvalidCommandError(),
+ usage();
+ {'EXIT', {function_clause, [{?MODULE, action, _, _} | _]}} -> %% >= R15
+ PrintInvalidCommandError(),
+ usage();
{'EXIT', {badarg, _}} ->
print_error("invalid parameter: ~p", [Args]),
usage();
diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl
index 8540bfc6..c2fefaeb 100644
--- a/src/rabbit_misc.erl
+++ b/src/rabbit_misc.erl
@@ -67,14 +67,13 @@
-ifdef(use_specs).
--export_type([resource_name/0, thunk/1]).
+-export_type([resource_name/0, thunk/1, invalid_arguments/0]).
-type(ok_or_error() :: rabbit_types:ok_or_error(any())).
-type(thunk(T) :: fun(() -> T)).
-type(resource_name() :: binary()).
--type(optdef() :: {flag, string()} | {option, string(), string()}).
--type(invalid_arguments() :: 'command_not_found' |
- {'invalid_option', atom(), string()}).
+-type(optdef() :: flag | {option, string()}).
+-type(invalid_arguments() :: 'command_not_found').
-type(channel_or_connection_exit()
:: rabbit_types:channel_exit() | rabbit_types:connection_exit()).
-type(digraph_label() :: term()).
@@ -185,7 +184,10 @@
-spec(gb_trees_foreach/2 ::
(fun ((any(), any()) -> any()), gb_tree()) -> 'ok').
-spec(get_options/4 ::
- ([{atom(), string()} | atom()], [string()], [optdef()], [string()])
+ ([{atom(), string()} | atom()],
+ [string()],
+ [{string(), optdef()}],
+ [string()])
-> {'ok', {atom(), [{string(), string()}], [string()]}} |
{'invalid', invalid_arguments()}).
-spec(handle_invalid_arguments/1 :: (invalid_arguments()) -> 'ok').
@@ -746,7 +748,8 @@ gb_trees_foreach(Fun, Tree) ->
%% the accepted commands and the optional [string()] is the list of
%% accepted options for that command
%% * A list [string()] of options valid for all commands
-%% * A list [optdef()] to determine what is a flag and what is an option
+%% * A list [{string(), optdef()}] to determine what is a flag and what is
+%% an option
%% * The list of arguments given by the user
%%
%% Returns either {ok, {atom(), [{string(), string()}], [string()]} which are
@@ -769,8 +772,10 @@ get_options(CommandsOpts0, GlobalOpts, Defs, As0) ->
end, not_found, CommandsOpts)
of
not_found -> {invalid, command_not_found};
- {found, {C, Os}} -> get_options1(C, sets:from_list(GlobalOpts ++ Os),
- Defs, As0 -- [C])
+ {found, {C, Os}} ->
+ {KVs, Arguments} = get_options(sets:from_list(GlobalOpts ++ Os),
+ Defs, As0 -- [C]),
+ {ok, {list_to_atom(C), KVs, Arguments}}
end.
drop_opts(Defs0, Opts0, As) ->
@@ -789,34 +794,19 @@ drop_opts(Opts, [A | As]) ->
error -> [A | As]
end.
-get_options1(Command, Opts, Defs, As) ->
+get_options(Opts, Defs, As) ->
%% Check that each flag is OK with this command, and get its value
- case lists:foldl(fun (_, {invalid_option, Opt}) ->
- {invalid_option, Opt};
- (Def, {ok, {Accum, As1}}) ->
- K = case Def of
- {K0, flag} -> K0;
- {K0, {option, _}} -> K0
- end,
- case {lists:member(K, As1),
- sets:is_element(K, Opts)}
- of
- %% We have a flag that shouldn't be there
- {true, false} -> {invalid_option,
- list_to_atom(Command), K};
- %% We don't care about this flag
- {false, false} -> {ok, {Accum, As1}};
- %% We need the flag
- {_, true} -> {As2, V} = get_def(Def, As1),
- {ok, {[{K, V} | Accum], As2}}
- end
- end, {ok, {[], As}}, Defs)
- of
- {ok, {Ks, Arguments}} ->
- {ok, {list_to_atom(Command), Ks, Arguments}};
- {invalid_option, Command, K} ->
- {invalid, {invalid_option, Command, K}}
- end.
+ lists:foldl(fun (Def, {Accum, As1}) ->
+ K = case Def of
+ {K0, flag} -> K0;
+ {K0, {option, _}} -> K0
+ end,
+ case sets:is_element(K, Opts) of
+ false -> {Accum, As1};
+ true -> {As2, V} = get_def(Def, As1),
+ {[{K, V} | Accum], As2}
+ end
+ end, {[], As}, Defs).
get_def({Flag, flag}, As) -> get_flag(Flag, As);
get_def({Opt, {option, Default}}, As) -> get_option(Opt, Default, As).
diff --git a/src/rabbit_plugins.erl b/src/rabbit_plugins.erl
index ab2298da..53639dc1 100644
--- a/src/rabbit_plugins.erl
+++ b/src/rabbit_plugins.erl
@@ -66,9 +66,21 @@ start() ->
usage()
end,
+ PrintInvalidCommandError =
+ fun () ->
+ print_error("invalid command '~s'",
+ [string:join([atom_to_list(Command) | Args], " ")])
+ end,
+
case catch action(Command, Args, Opts, PluginsFile, PluginsDir) of
ok ->
rabbit_misc:quit(0);
+ {'EXIT', {function_clause, [{?MODULE, action, _} | _]}} ->
+ PrintInvalidCommandError(),
+ usage();
+ {'EXIT', {function_clause, [{?MODULE, action, _, _} | _]}} ->
+ PrintInvalidCommandError(),
+ usage();
{error, Reason} ->
print_error("~p", [Reason]),
rabbit_misc:quit(2);