diff options
author | Francesco Mazzoli <francesco@rabbitmq.com> | 2012-05-17 11:51:19 +0100 |
---|---|---|
committer | Francesco Mazzoli <francesco@rabbitmq.com> | 2012-05-17 11:51:19 +0100 |
commit | 3213f1d863ea0b74934ce48912a6a6f71c3efa52 (patch) | |
tree | 2118fecd49139710b6aa01670c4d4bf74bd1c843 | |
parent | 2d95d0e087e34242aa7c332b40d9bd405a2c4411 (diff) | |
download | rabbitmq-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.erl | 13 | ||||
-rw-r--r-- | src/rabbit_misc.erl | 60 | ||||
-rw-r--r-- | src/rabbit_plugins.erl | 12 |
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); |