summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--rabbitmq-components.mk1
-rw-r--r--src/rabbit_ff_extra.erl176
3 files changed, 98 insertions, 81 deletions
diff --git a/Makefile b/Makefile
index 9e818a8937..4e61332513 100644
--- a/Makefile
+++ b/Makefile
@@ -135,7 +135,7 @@ endef
LOCAL_DEPS = sasl mnesia os_mon inets compiler public_key crypto ssl syntax_tools
BUILD_DEPS = rabbitmq_cli syslog
-DEPS = ranch lager rabbit_common ra sysmon_handler
+DEPS = ranch lager rabbit_common ra sysmon_handler stdout_formatter
TEST_DEPS = rabbitmq_ct_helpers rabbitmq_ct_client_helpers amqp_client meck proper
dep_syslog = git https://github.com/schlagert/syslog 3.4.5
diff --git a/rabbitmq-components.mk b/rabbitmq-components.mk
index d3ae30465e..8223a3e970 100644
--- a/rabbitmq-components.mk
+++ b/rabbitmq-components.mk
@@ -118,6 +118,7 @@ dep_prometheus = hex 4.2.2
dep_ra = git https://github.com/rabbitmq/ra.git master
dep_ranch = hex 1.7.1
dep_recon = hex 2.4.0
+dep_stdout_formatter = hex 0.2.2
dep_sysmon_handler = hex 1.1.0
RABBITMQ_COMPONENTS = amqp_client \
diff --git a/src/rabbit_ff_extra.erl b/src/rabbit_ff_extra.erl
index 1b77a0f3fd..533ec88cb3 100644
--- a/src/rabbit_ff_extra.erl
+++ b/src/rabbit_ff_extra.erl
@@ -23,6 +23,8 @@
-module(rabbit_ff_extra).
+-include_lib("stdout_formatter/include/stdout_formatter.hrl").
+
-export([cli_info/0,
info/1,
info/2,
@@ -40,7 +42,7 @@
%% A list of properties for a single feature flag, formatted for the
%% RabbitMQ CLI.
--type info_options() :: #{color => boolean(),
+-type info_options() :: #{colors => boolean(),
lines => boolean(),
verbose => non_neg_integer()}.
%% Options accepted by {@link info/1} and {@link info/2}.
@@ -91,17 +93,15 @@ cli_info(FeatureFlags) ->
%% @param Options Options to tune what is displayed and how.
info(Options) ->
- UseColors = use_colors(Options),
%% Two tables: one for stable feature flags, one for experimental ones.
StableFF = rabbit_feature_flags:list(all, stable),
case maps:size(StableFF) of
0 ->
ok;
_ ->
- io:format(
- "~n~s## Stable feature flags:~s~n",
- [rabbit_pretty_stdout:ascii_color(bright_white, UseColors),
- rabbit_pretty_stdout:ascii_color(default, UseColors)]),
+ stdout_formatter:display(
+ #paragraph{content = "\n## Stable feature flags:",
+ props = #{bold => true}}),
info(StableFF, Options)
end,
ExpFF = rabbit_feature_flags:list(all, experimental),
@@ -109,10 +109,9 @@ info(Options) ->
0 ->
ok;
_ ->
- io:format(
- "~n~s## Experimental feature flags:~s~n",
- [rabbit_pretty_stdout:ascii_color(bright_white, UseColors),
- rabbit_pretty_stdout:ascii_color(default, UseColors)]),
+ stdout_formatter:display(
+ #paragraph{content = "\n## Experimental feature flags:",
+ props = #{bold => true}}),
info(ExpFF, Options)
end,
case maps:size(StableFF) + maps:size(ExpFF) of
@@ -132,103 +131,120 @@ info(FeatureFlags, Options) ->
Verbose = maps:get(verbose, Options, 0),
UseColors = use_colors(Options),
UseLines = use_lines(Options),
+ Title = case UseColors of
+ true -> #{title => true};
+ false -> #{}
+ end,
+ Bold = case UseColors of
+ true -> #{bold => true};
+ false -> #{}
+ end,
+ {Green, Yellow, Red} = case UseColors of
+ true ->
+ {#{fg => green},
+ #{fg => yellow},
+ #{bold => true,
+ bg => red}};
+ false ->
+ {#{}, #{}, #{}}
+ end,
+ Border = case UseLines of
+ true -> #{border_drawing => ansi};
+ false -> #{border_drawing => ascii}
+ end,
%% Table columns:
%% | Name | State | Provided by | Description
%%
%% where:
%% State = Enabled | Disabled | Unavailable (if a node doesn't
%% support it).
- TableHeader = [
- [{"Name", bright_white},
- {"State", bright_white},
- {"Provided by", bright_white},
- {"Description", bright_white}]
- ],
+ TableHeader = #row{cells = ["Name",
+ "State",
+ "Provided",
+ "Description"],
+ props = Title},
Nodes = lists:sort([node() | rabbit_feature_flags:remote_nodes()]),
- Rows = lists:foldr(
- fun(FeatureName, Acc) ->
+ Rows = lists:map(
+ fun(FeatureName) ->
FeatureProps = maps:get(FeatureName, FeatureFlags),
State0 = rabbit_feature_flags:get_state(FeatureName),
- {State, StateColor} = case State0 of
- enabled ->
- {"Enabled", green};
- disabled ->
- {"Disabled", yellow};
- unavailable ->
- {"Unavailable", red_bg}
- end,
+ {State, Color} = case State0 of
+ enabled ->
+ {"Enabled", Green};
+ disabled ->
+ {"Disabled", Yellow};
+ unavailable ->
+ {"Unavailable", Red}
+ end,
App = maps:get(provided_by, FeatureProps),
Desc = maps:get(desc, FeatureProps, ""),
- MainLine = [{atom_to_list(FeatureName), bright_white},
- {State, StateColor},
- {atom_to_list(App), default},
- {Desc, default}],
VFun = fun(Node) ->
Supported =
rabbit_feature_flags:does_node_support(
Node, [FeatureName], 60000),
{Label, LabelColor} =
case Supported of
- true -> {"supported", default};
- false -> {"unsupported", red_bg}
+ true -> {"supported", #{}};
+ false -> {"unsupported", Red}
end,
- Uncolored = rabbit_misc:format(
- " ~s: ~s", [Node, Label]),
- Colored = rabbit_misc:format(
- " ~s: ~s~s~s",
- [Node,
- rabbit_pretty_stdout:
- ascii_color(LabelColor,
- UseColors),
- Label,
- rabbit_pretty_stdout:
- ascii_color(default,
- UseColors)]),
- [empty,
- empty,
- empty,
- {Uncolored, Colored}]
+ #paragraph{content =
+ [rabbit_misc:format(" ~s: ",
+ [Node]),
+ #paragraph{content = Label,
+ props = LabelColor}]}
end,
- if
- Verbose > 0 ->
- [[MainLine,
- empty,
- [empty,
- empty,
- empty,
- {"Per-node support level:", default}]
- | lists:map(VFun, Nodes)] | Acc];
- true ->
- [[MainLine] | Acc]
- end
- end, [], lists:sort(maps:keys(FeatureFlags))),
+ ExtraLines = if
+ Verbose > 0 ->
+ NodesList = lists:join(
+ "\n",
+ lists:map(
+ VFun, Nodes)),
+ ["\n\n",
+ "Per-node support level:\n"
+ | NodesList];
+ true ->
+ []
+ end,
+ [#paragraph{content = FeatureName,
+ props = Bold},
+ #paragraph{content = State,
+ props = Color},
+ #paragraph{content = App},
+ #paragraph{content = [Desc | ExtraLines]}]
+ end, lists:sort(maps:keys(FeatureFlags))),
io:format("~n", []),
- rabbit_pretty_stdout:display_table([TableHeader | Rows],
- UseColors,
- UseLines).
+ stdout_formatter:display(#table{rows = [TableHeader | Rows],
+ props = Border#{cell_padding => {0, 1}}}).
use_colors(Options) ->
- maps:get(color, Options, rabbit_pretty_stdout:isatty()).
+ maps:get(colors, Options, true).
use_lines(Options) ->
- maps:get(lines, Options, rabbit_pretty_stdout:isatty()).
+ maps:get(lines, Options, true).
state_legend(Options) ->
UseColors = use_colors(Options),
- io:format(
- "~n"
- "Possible states:~n"
- " ~sEnabled~s: The feature flag is enabled on all nodes~n"
- " ~sDisabled~s: The feature flag is disabled on all nodes~n"
- " ~sUnavailable~s: The feature flag cannot be enabled because one or "
- "more nodes do not support it~n"
- "~n",
- [rabbit_pretty_stdout:ascii_color(green, UseColors),
- rabbit_pretty_stdout:ascii_color(default, UseColors),
- rabbit_pretty_stdout:ascii_color(yellow, UseColors),
- rabbit_pretty_stdout:ascii_color(default, UseColors),
- rabbit_pretty_stdout:ascii_color(red_bg, UseColors),
- rabbit_pretty_stdout:ascii_color(default, UseColors)]).
+ {Green, Yellow, Red} = case UseColors of
+ true ->
+ {#{fg => green},
+ #{fg => yellow},
+ #{bold => true,
+ bg => red}};
+ false ->
+ {#{}, #{}, #{}}
+ end,
+ Enabled = #paragraph{content = "Enabled", props = Green},
+ Disabled = #paragraph{content = "Disabled", props = Yellow},
+ Unavailable = #paragraph{content = "Unavailable", props = Red},
+ stdout_formatter:display(
+ #paragraph{
+ content =
+ ["\n",
+ "Possible states:\n",
+ " ", Enabled, ": The feature flag is enabled on all nodes\n",
+ " ", Disabled, ": The feature flag is disabled on all nodes\n",
+ " ", Unavailable, ": The feature flag cannot be enabled because"
+ " one or more nodes do not support it\n"]}).
-spec format_error(any()) -> string().
%% @doc