Skip to content

Commit

Permalink
CLI: make input ordering preditable when formatting a table
Browse files Browse the repository at this point in the history
if the input is given as a map.

References #7931, #7921
  • Loading branch information
michaelklishin committed Apr 24, 2023
1 parent c094bbb commit ddf7926
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ defmodule RabbitMQ.CLI.Formatters.FormatterHelpers do
def format_info_item(item, escaped \\ true)

def format_info_item(map, escaped) when is_map(map) do
kv = to_predictably_ordered_keyword_list(map)

[
"\#\{",
Enum.map(
map,
kv,
fn {k, v} ->
["#{escape(k, escaped)} => ", format_info_item(v, escaped)]
end
Expand Down Expand Up @@ -125,6 +127,14 @@ defmodule RabbitMQ.CLI.Formatters.FormatterHelpers do
:io_lib.format("~1000000000000tp", [value])
end

@spec to_predictably_ordered_keyword_list(Enumerable.t()) :: Keyword.t()
def to_predictably_ordered_keyword_list(input0) do
case input0 do
m when is_map(m) -> Enum.sort(Keyword.new(m))
other -> other
end
end

defp prettify_amqp_table(table, escaped) do
for {k, t, v} <- table do
{escape(k, escaped), prettify_typed_amqp_value(t, v, escaped)}
Expand Down
8 changes: 6 additions & 2 deletions deps/rabbitmq_cli/lib/rabbitmq/cli/formatters/table.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defmodule RabbitMQ.CLI.Formatters.Table do
fn
[first | _] = element ->
case FormatterHelpers.proplist?(first) or is_map(first) do
true -> element
true -> FormatterHelpers.to_predictably_ordered_keyword_list(element)
false -> [element]
end

Expand All @@ -38,7 +38,10 @@ defmodule RabbitMQ.CLI.Formatters.Table do
)
end

def format_output(output, options) do
def format_output(output0, options) do
# on Erlang 26, map entry ordering has changed, this avoids
# implicitly depending on map key order
output = FormatterHelpers.to_predictably_ordered_keyword_list(output0)
maybe_header(output, options)
end

Expand All @@ -61,6 +64,7 @@ defmodule RabbitMQ.CLI.Formatters.Table do
defp format_output_1(output, options) when is_map(output) do
escaped = escaped?(options)
pad_to_header = pad_to_header?(options)

format_line(output, escaped, pad_to_header)
end

Expand Down
2 changes: 1 addition & 1 deletion deps/rabbitmq_cli/test/core/table_formatter_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ defmodule TableFormatterTest do
%{}
)
|> Enum.to_list() ==
["a\tb\tc", "apple\tbeer\t1", "aadvark\t\"bee\"\t2"]
["c\ta\tb", "1\tapple\tbeer", "2\taadvark\t\"bee\""]
end

test "format_stream tab-separates keyword values" do
Expand Down

0 comments on commit ddf7926

Please sign in to comment.