rabbitmq / rabbitmq-cli

Command line tools for RabbitMQ
Other
105 stars 34 forks source link

Make it possible to evaluate scripts from standard input or a file #441

Closed michaelklishin closed 4 years ago

michaelklishin commented 4 years ago

Ways to QA:

ERL_LIBS=../rabbit/plugins ./escript/rabbitmqctl eval <<< "1 + 1."

ERL_LIBS=../rabbit/plugins ./escript/rabbitmqctl eval <<< "1 + ."

cat /path/to/expression.file | ERL_LIBS=../rabbit/plugins ./escript/rabbitmqctl eval

ERL_LIBS=../rabbit/plugins ./escript/rabbitmqctl eval < /path/to/expression.file
ERL_LIBS=../rabbit/plugins ./escript/rabbitmqctl eval_file /path/to/expression.file

Closes #438.

gerhard commented 4 years ago

Looking good, almost there:

# ✅ Here string fails as expected
sbin/rabbitmqctl eval <<< 'io:format("~p~n", [rabbit:product_info()])'
Error:
Evaluation failed: syntax error before:

# ✅ Here string works as expected
$ sbin/rabbitmqctl eval <<< 'io:format("~p~n", [rabbit:product_info()]).'
#{otp_release => "23.0.2",product_base_name => "RabbitMQ",
  product_base_version => "3.8.0+rc.1.349.g167c376"}
ok

# ✅ Here doc fails as expected
$ sbin/rabbitmqctl eval <<EOF
io:format("~p~n~p~n", [
    rabbit:product_info(),
    rabbit:alarms()
]))
EOF
Error:
Evaluation failed: syntax error before:

# ❌ Multiline here doc does not work as expected
$ sbin/rabbitmqctl eval <<EOF
io:format("~p~n~p~n", [
    rabbit:product_info(),
    rabbit:alarms()
]).
EOF
Error:
Evaluation failed: syntax error before:

# 💡 Single-line here doc works as expected
sbin/rabbitmqctl eval <<EOF
io:format("~p~n~p~n", [rabbit:product_info(), rabbit:alarms()]).
EOF

# ✅ Pipe fails as expected
echo "rabbit:is_bootin()." | sbin/rabbitmqctl eval
Error:
{:undef, [{:rabbit, :is_bootin, [], []}, {:erl_eval, :do_apply, 6, [file: 'erl_eval.erl', line: 680]}, {:erl_eval, :exprs, 2, []}]}

# ✅ Pipe works as expected
echo "rabbit:is_booting()." | sbin/rabbitmqctl eval
false

# ✅ Command redirect fails as expected
sbin/rabbitmqctl eval < <(echo "rabbit:maybe_insert_default_dat().")
Error:
{:undef, [{:rabbit, :maybe_insert_default_dat, [], []}, {:erl_eval, :do_apply, 6, [file: 'erl_eval.erl', line: 680]}, {:erl_eval, :exprs, 2, []}]}

# ✅ Command redirect works as expected
sbin/rabbitmqctl eval < <(echo "rabbit:maybe_insert_default_data().")
ok

cat > qa.erl <<EOF
Print = fun (Head, Body) -> io:format("=== ~s~n~p~n~n", [Head, Body]) end,
Print("INFO", rabbit:product_info()),
Print("ALARMS", rabbit:alarms()).
EOF

# ✅ File redirect fails as expected
$ sbin/rabbitmqctl eval < qa.erl
Error:
Evaluation failed: syntax error before:

# ❌ File redirect does not work as expected (same as multiline here doc)
$ sbin/rabbitmqctl eval < qa.erl
Error:
Evaluation failed: syntax error before:

# ✅ eval_file fails as expected
$ sbin/rabbitmqctl eval_file qa.erl
Error (argument validation): "syntax error before: Print"
Arguments given:
    eval_file qa.erl

Usage

rabbitmqctl [--node <node>] [--longnames] [--quiet] eval_file <file path>

# ✅ eval_file works as expected
$ sbin/rabbitmqctl eval_file qa.erl
=== INFO
#{otp_release => "23.0.2",product_base_name => "RabbitMQ",
  product_base_version => "3.8.0+rc.1.349.g167c376"}

=== ALARMS
[]

ok
gerhard commented 4 years ago
# ✅ Multiline here doc works as expected

sbin/rabbitmqctl eval <<EOF
io:format("~p~n~p~n", [
    rabbit:product_info(),
    rabbit:alarms()
]).
EOF
#{otp_release => "23.0.2",product_base_name => "RabbitMQ",
  product_base_version => "3.8.0+rc.1.349.g167c376"}
[]
ok

# ✅ File redirect works as expected
sbin/rabbitmqctl eval < qa.erl
=== INFO
#{otp_release => "23.0.2",product_base_name => "RabbitMQ",
  product_base_version => "3.8.0+rc.1.349.g167c376"}

=== ALARMS
[]

ok

:shipit:

michaelklishin commented 4 years ago

Backported to v3.8.x.

lukebakken commented 4 years ago

This is great! :partying_face: