Skip to content

Commit e6429db

Browse files
committed
WIP
1 parent bd4a6a3 commit e6429db

File tree

5 files changed

+115
-45
lines changed

5 files changed

+115
-45
lines changed

deps/rabbit/src/rabbit_cli_cmd_list_exchanges.erl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ list_exchanges(Args) ->
5454
}}});
5555
false ->
5656
rabbit_cli_io:notify(Ret)
57-
end.
57+
end,
58+
ok.
5859

5960
get_nodename(#{node := Nodename}) ->
6061
Nodename;

deps/rabbit/src/rabbit_cli_cmd_version.erl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ cli() ->
1414
show_version(_) ->
1515
ok = application:load(rabbit),
1616
{ok, Version} = application:get_key(rabbit, vsn),
17-
rabbit_cli_io:notify(Version).
17+
rabbit_cli_io:notify({format, "~s~n", [Version]}),
18+
ok.

deps/rabbit/src/rabbit_cli_io_console.erl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@ init(_) ->
2929
handle_call(_Request, State) ->
3030
{ok, ok, State}.
3131

32-
handle_event(
33-
{log_event, LogEvent, #{formatter := {FModule, FConfig}}},
34-
State) ->
35-
io:put_chars(FModule:format(LogEvent, FConfig)),
32+
handle_event({format, Format, Args}, State) ->
33+
io:format(Format, Args),
3634
{ok, State};
3735
handle_event(
3836
{info_table, #{keys := Keys, rows := Rows0, callbacks := CBs}},
@@ -74,6 +72,11 @@ handle_event(
7472
#table{rows = [TableHeader | Rows],
7573
props = Border#{cell_padding => {0, 1}}}),
7674
{ok, State};
75+
handle_event(
76+
{log_event, LogEvent, #{formatter := {FModule, FConfig}}},
77+
State) ->
78+
io:put_chars(FModule:format(LogEvent, FConfig)),
79+
{ok, State};
7780
handle_event(Event, State) ->
7881
io:format("~p~n", [Event]),
7982
{ok, State}.

deps/rabbit/src/rabbit_cli_main.erl

Lines changed: 87 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,66 @@
11
-module(rabbit_cli_main).
22

3+
-include("src/sysexits.hrl").
4+
35
-export([run/2]).
46

57
-spec run(string(), iodata()) -> ok.
68

7-
run(_ProgName, RawArgs) ->
8-
%% 1. Argument parsing.
9+
run(ProgName, RawArgs) ->
10+
ParserOpts = #{progname => ProgName},
911
CommandMods = discover_commands(),
10-
CommandMap = collect_args_spec(CommandMods, #{}),
11-
Ret = argparse:parse(RawArgs, CommandMap),
12-
13-
%% 2. Output setup.
14-
rabbit_cli_io:setup(Ret),
15-
set_log_level(Ret),
16-
logger:debug("argparse:parse/2 -> ~p~n", [Ret]),
17-
18-
%% 3. Command execution.
12+
CommandSpec = collect_args_spec(CommandMods, ParserOpts),
13+
14+
Ret = try
15+
%% 1. Argument parsing.
16+
ParsedArgs = argparse:parse(RawArgs, CommandSpec, ParserOpts),
17+
18+
%% 2. Output setup.
19+
rabbit_cli_io:setup(ParsedArgs),
20+
set_log_level(ParsedArgs),
21+
logger:debug("argparse:parse/2 -> ~p~n", [ParsedArgs]),
22+
23+
%% 3. Command execution.
24+
Result = case ParsedArgs of
25+
{ArgMap, PathTo} ->
26+
run_handler(
27+
CommandSpec,
28+
ArgMap,
29+
PathTo,
30+
undefined);
31+
ArgMap ->
32+
run_handler(
33+
CommandSpec,
34+
ArgMap,
35+
{[], CommandSpec},
36+
{CommandMods, #{}})
37+
end,
38+
39+
%% 4. Close output and return exit status.
40+
rabbit_cli_io:close(),
41+
Result
42+
catch
43+
error:{argparse, Reason} ->
44+
Prefixes = maps:get(prefixes, ParserOpts, "-"),
45+
case help_requested(Reason, Prefixes) of
46+
false ->
47+
Error = argparse:format_error(
48+
Reason,
49+
CommandSpec,
50+
ParserOpts),
51+
io:format(standard_error, "error: ~s", [Error]);
52+
CommandPath ->
53+
Help = argparse:help(
54+
CommandSpec,
55+
ParserOpts#{command => tl(CommandPath)}),
56+
io:format(standard_error, "~s", [Help])
57+
end,
58+
{exit, ?EX_USAGE}
59+
end,
1960
case Ret of
20-
{ArgMap, PathTo} ->
21-
run_handler(
22-
CommandMap, ArgMap, PathTo, undefined);
23-
ArgMap ->
24-
%{ maps:find(default, Options), Modules, Options}
25-
run_handler(
26-
CommandMap, ArgMap, {[], CommandMap}, {CommandMods, #{}})
27-
end,
28-
29-
30-
%% 4. Close output and return exit status.
31-
rabbit_cli_io:close(),
32-
ok.
61+
ok -> ok;
62+
{exit, ExitCode} -> halt(ExitCode)
63+
end.
3364

3465
discover_commands() ->
3566
[% TODO: Generate that list.
@@ -154,37 +185,37 @@ create_handlers(Mod, _CmdName, Cmd0, DefaultTerm) ->
154185
Cmd#{commands => NewCmds}
155186
end.
156187

157-
run_handler(CmdMap, ArgMap, {Path, #{handler := {Mod, ModFun, Default}}}, _MO) ->
158-
ArgList = arg_map_to_arg_list(CmdMap, Path, ArgMap, Default),
188+
run_handler(CmdSpec, ArgMap, {Path, #{handler := {Mod, ModFun, Default}}}, _MO) ->
189+
ArgList = arg_map_to_arg_list(CmdSpec, Path, ArgMap, Default),
159190
%% if argument count may not match, better error can be produced
160191
erlang:apply(Mod, ModFun, ArgList);
161-
run_handler(_CmdMap, ArgMap, {_Path, #{handler := {Mod, ModFun}}}, _MO) when is_atom(Mod), is_atom(ModFun) ->
192+
run_handler(_CmdSpec, ArgMap, {_Path, #{handler := {Mod, ModFun}}}, _MO) when is_atom(Mod), is_atom(ModFun) ->
162193
Mod:ModFun(ArgMap);
163-
run_handler(CmdMap, ArgMap, {Path, #{handler := {Fun, Default}}}, _MO) when is_function(Fun) ->
164-
ArgList = arg_map_to_arg_list(CmdMap, Path, ArgMap, Default),
194+
run_handler(CmdSpec, ArgMap, {Path, #{handler := {Fun, Default}}}, _MO) when is_function(Fun) ->
195+
ArgList = arg_map_to_arg_list(CmdSpec, Path, ArgMap, Default),
165196
%% if argument count may not match, better error can be produced
166197
erlang:apply(Fun, ArgList);
167-
run_handler(_CmdMap, ArgMap, {_Path, #{handler := Handler}}, _MO) when is_function(Handler, 1) ->
198+
run_handler(_CmdSpec, ArgMap, {_Path, #{handler := Handler}}, _MO) when is_function(Handler, 1) ->
168199
Handler(ArgMap);
169200
%% below is compatibility mode: cli/1 behaviour has been removed in 1.1.0, but
170201
%% is still honoured for existing users
171-
run_handler(CmdMap, ArgMap, {[], _}, {Modules, Options}) when is_map_key(default, Options) ->
172-
ArgList = arg_map_to_arg_list(CmdMap, [], ArgMap, maps:get(default, Options)),
173-
exec_cli(Modules, CmdMap, ArgList, Options);
174-
run_handler(CmdMap, ArgMap, {[], _}, {Modules, Options}) ->
202+
run_handler(CmdSpec, ArgMap, {[], _}, {Modules, Options}) when is_map_key(default, Options) ->
203+
ArgList = arg_map_to_arg_list(CmdSpec, [], ArgMap, maps:get(default, Options)),
204+
exec_cli(Modules, CmdSpec, ArgList, Options);
205+
run_handler(CmdSpec, ArgMap, {[], _}, {Modules, Options}) ->
175206
% {undefined, {ok, Default}, Modules, Options}
176-
exec_cli(Modules, CmdMap, [ArgMap], Options).
207+
exec_cli(Modules, CmdSpec, [ArgMap], Options).
177208

178209
%% finds first module that exports ctl/1 and execute it
179-
exec_cli([], CmdMap, _ArgMap, ArgOpts) ->
210+
exec_cli([], CmdSpec, _ArgMap, ArgOpts) ->
180211
%% command not found, let's print usage
181-
io:format(argparse:help(CmdMap, ArgOpts));
182-
exec_cli([Mod|Tail], CmdMap, Args, ArgOpts) ->
212+
io:format(argparse:help(CmdSpec, ArgOpts));
213+
exec_cli([Mod|Tail], CmdSpec, Args, ArgOpts) ->
183214
case erlang:function_exported(Mod, cli, length(Args)) of
184215
true ->
185216
erlang:apply(Mod, cli, Args);
186217
false ->
187-
exec_cli(Tail, CmdMap, Args, ArgOpts)
218+
exec_cli(Tail, CmdSpec, Args, ArgOpts)
188219
end.
189220

190221
%% Given command map, path to reach a specific command, and a parsed argument
@@ -201,3 +232,20 @@ collect_arguments(Command, [H|Tail], Acc) ->
201232
Args = maps:get(arguments, Command, []),
202233
Next = maps:get(H, maps:get(commands, Command, H)),
203234
collect_arguments(Next, Tail, Acc ++ Args).
235+
236+
%% Finds out whether it was --help/-h requested, and exception was thrown due to that
237+
help_requested({unknown_argument, CmdPath, [Prefix, $h]}, Prefixes) ->
238+
is_prefix(Prefix, Prefixes, CmdPath);
239+
help_requested({unknown_argument, CmdPath, [Prefix, Prefix, $h, $e, $l, $p]}, Prefixes) ->
240+
is_prefix(Prefix, Prefixes, CmdPath);
241+
help_requested(_, _) ->
242+
false.
243+
244+
%% returns CmdPath when Prefix is one of supplied Prefixes
245+
is_prefix(Prefix, Prefixes, CmdPath) ->
246+
case lists:member(Prefix, Prefixes) of
247+
true ->
248+
CmdPath;
249+
false ->
250+
false
251+
end.

deps/rabbit/src/sysexits.hrl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-define(EX_OK, 0).
2+
3+
-define(EX_USAGE, 64). % Command line usage error
4+
-define(EX_DATAERR, 65). % Data format error
5+
-define(EX_NOINPUT, 66). % Cannot open input
6+
-define(EX_NOUSER, 67). % Addressee unknown
7+
-define(EX_NOHOST, 68). % Host name unknown
8+
-define(EX_UNAVAILABLE, 69). % Service unavailable
9+
-define(EX_SOFTWARE, 70). % Internal software error
10+
-define(EX_OSERR, 71). % System error (e.g., can't fork)
11+
-define(EX_OSFILE, 72). % Critical OS file missing
12+
-define(EX_CANTCREAT, 73). % Can't create (user) output file
13+
-define(EX_IOERR, 74). % Input/output error
14+
-define(EX_TEMPFAIL, 75). % Temp failure; user is invited to retry
15+
-define(EX_PROTOCOL, 76). % Remote error in protocol
16+
-define(EX_NOPERM, 77). % Permission denied
17+
-define(EX_CONFIG, 78). % Configuration error

0 commit comments

Comments
 (0)