From e0871712254f3310ac456e9cd3cf9c155d93ee87 Mon Sep 17 00:00:00 2001 From: Daniil Fedotov Date: Mon, 20 Jun 2016 16:52:36 +0100 Subject: [PATCH] Aliases in behaviour. List plugins command --- Makefile | 1 + lib/rabbit_common/records.ex | 1 + lib/rabbitmq/cli/command_behaviour.ex | 1 + lib/rabbitmq/cli/ctl/command_modules.ex | 60 ++++--- .../cli/ctl/commands/add_user_command.ex | 1 + .../cli/ctl/commands/add_vhost_command.ex | 1 + .../ctl/commands/authenticate_user_command.ex | 1 + .../ctl/commands/cancel_sync_queue_command.ex | 1 + .../ctl/commands/change_password_command.ex | 1 + .../ctl/commands/clear_parameter_command.ex | 1 + .../ctl/commands/clear_password_command.ex | 1 + .../ctl/commands/clear_permissions_command.ex | 1 + .../ctl/commands/close_connection_command.ex | 1 + .../ctl/commands/cluster_status_command.ex | 1 + .../cli/ctl/commands/delete_user_command.ex | 1 + .../cli/ctl/commands/delete_vhost_command.ex | 1 + .../cli/ctl/commands/environment_command.ex | 1 + .../cli/ctl/commands/force_reset_command.ex | 1 + lib/rabbitmq/cli/ctl/commands/help_command.ex | 1 + .../cli/ctl/commands/join_cluster_command.ex | 2 + .../cli/ctl/commands/list_bindings_command.ex | 1 + .../cli/ctl/commands/list_channels_command.ex | 1 + .../ctl/commands/list_connections_command.ex | 1 + .../ctl/commands/list_consumers_command.ex | 1 + .../ctl/commands/list_exchanges_command.ex | 1 + .../ctl/commands/list_parameters_command.ex | 1 + .../ctl/commands/list_permissions_command.ex | 1 + .../cli/ctl/commands/list_queues_command.ex | 2 + .../commands/list_user_permissions_command.ex | 1 + .../cli/ctl/commands/list_users_command.ex | 1 + .../cli/ctl/commands/list_vhosts_command.ex | 1 + .../ctl/commands/node_health_check_command.ex | 1 + .../cli/ctl/commands/purge_queue_command.ex | 1 + .../cli/ctl/commands/report_command.ex | 1 + .../cli/ctl/commands/reset_command.ex | 1 + .../cli/ctl/commands/rotate_logs_command.ex | 1 + .../ctl/commands/set_cluster_name_command.ex | 1 + .../commands/set_disk_free_limit_command.ex | 1 + .../cli/ctl/commands/set_parameter_command.ex | 1 + .../ctl/commands/set_permissions_command.ex | 1 + .../cli/ctl/commands/set_user_tags_command.ex | 1 + .../set_vm_memory_high_watermark_command.ex | 1 + .../cli/ctl/commands/start_app_command.ex | 1 + .../cli/ctl/commands/status_command.ex | 1 + .../cli/ctl/commands/stop_app_command.ex | 1 + lib/rabbitmq/cli/ctl/commands/stop_command.ex | 1 + .../cli/ctl/commands/sync_queue_command.ex | 1 + .../cli/ctl/commands/trace_off_command.ex | 1 + .../cli/ctl/commands/trace_on_command.ex | 1 + lib/rabbitmq/cli/ctl/commands/wait_command.ex | 1 + lib/rabbitmq/cli/ctl/helpers.ex | 9 +- lib/rabbitmq/cli/ctl/parser.ex | 22 ++- .../plugins/commands/list_plugins_command.ex | 158 ++++++++++++++++++ lib/rabbitmq/cli/plugins/helpers.ex | 69 ++++++++ mix.exs | 4 +- 55 files changed, 341 insertions(+), 32 deletions(-) create mode 100644 lib/rabbitmq/cli/plugins/commands/list_plugins_command.ex create mode 100644 lib/rabbitmq/cli/plugins/helpers.ex diff --git a/Makefile b/Makefile index 60e9b1e4..5b9325a2 100644 --- a/Makefile +++ b/Makefile @@ -5,5 +5,6 @@ all: tests: all mix test plugins: all + rm rabbitmq-plugins ln -s rabbitmqctl rabbitmq-plugins diff --git a/lib/rabbit_common/records.ex b/lib/rabbit_common/records.ex index b3b165c7..3f2db4ab 100644 --- a/lib/rabbit_common/records.ex +++ b/lib/rabbit_common/records.ex @@ -18,4 +18,5 @@ defmodule RabbitCommon.Records do import Record, only: [defrecord: 2, extract: 2] defrecord :amqqueue, extract(:amqqueue, from_lib: "rabbit_common/include/rabbit.hrl") + defrecord :plugin, extract(:plugin, from_lib: "rabbit_common/include/rabbit.hrl") end diff --git a/lib/rabbitmq/cli/command_behaviour.ex b/lib/rabbitmq/cli/command_behaviour.ex index fb67bec8..cc89ef49 100644 --- a/lib/rabbitmq/cli/command_behaviour.ex +++ b/lib/rabbitmq/cli/command_behaviour.ex @@ -22,4 +22,5 @@ defmodule RabbitMQ.CLI.CommandBehaviour do @callback banner(List.t, Map.t) :: String.t @callback run(List.t, Map.t) :: any @callback switches() :: Keyword.t + @callback aliases() :: Keyword.t end diff --git a/lib/rabbitmq/cli/ctl/command_modules.ex b/lib/rabbitmq/cli/ctl/command_modules.ex index 4e59d549..dea23a84 100644 --- a/lib/rabbitmq/cli/ctl/command_modules.ex +++ b/lib/rabbitmq/cli/ctl/command_modules.ex @@ -15,6 +15,8 @@ defmodule RabbitMQ.CLI.Ctl.CommandModules do + @commands_ns ~r/RabbitMQ.CLI.(.*).Commands/ + def module_map do case Application.get_env(:rabbitmqctl, :commands) do nil -> load; @@ -41,28 +43,32 @@ defmodule RabbitMQ.CLI.Ctl.CommandModules do end defp load_commands(scope) do - modules = loadable_modules() - modules - |> Enum.filter(fn(path) -> - to_string(path) =~ ~r/RabbitMQ.CLI.*.Commands/ + ctl_and_plugin_modules + |> Enum.filter(fn(mod) -> + to_string(mod) =~ @commands_ns + and + implements_command_behaviour?(mod) + and + command_in_scope(mod, scope) end) - |> Enum.map(fn(path) -> - Path.rootname(path, '.beam') - |> String.to_atom - |> Code.ensure_loaded - end) - |> Enum.filter_map(fn({res, _}) -> res == :module end, - fn({_, mod}) -> command_tuple(mod) end) - |> Enum.filter(fn({_, cmd}) -> command_in_scope(cmd, scope) end) + |> Enum.map(&command_tuple/1) |> Map.new end - defp loadable_modules do - :code.get_path() - |> Enum.flat_map(fn(path) -> - {:ok, modules} = :erl_prim_loader.list_dir(path) - modules - end) + defp ctl_and_plugin_modules do + # No plugins so far + applications = [:rabbitmqctl] + applications + |> Enum.flat_map(fn(app) -> Application.spec(app, :modules) end) + end + + + defp implements_command_behaviour?(nil) do + false + end + defp implements_command_behaviour?(module) do + Enum.member?(module.module_info(:attributes)[:behaviour] || [], + RabbitMQ.CLI.CommandBehaviour) end defp command_tuple(cmd) do @@ -107,8 +113,20 @@ defmodule RabbitMQ.CLI.Ctl.CommandModules do false end defp command_in_scope(cmd, scope) do - cmd - |> to_string - |> String.contains?("RabbitMQ.CLI.#{scope}.Commands") + Enum.member?(command_scopes(cmd), scope) + end + + defp command_scopes(cmd) do + case :erlang.function_exported(cmd, :scopes, 0) do + true -> + cmd.scopes() + false -> + @commands_ns + |> Regex.run(to_string(cmd), capture: :all_but_first) + |> List.first + |> to_snake_case + |> String.to_atom + |> List.wrap + end end end diff --git a/lib/rabbitmq/cli/ctl/commands/add_user_command.ex b/lib/rabbitmq/cli/ctl/commands/add_user_command.ex index 0104fe68..36ccf0b6 100644 --- a/lib/rabbitmq/cli/ctl/commands/add_user_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/add_user_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddUserCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def validate(args, _) when length(args) < 2 do {:validation_failure, :not_enough_args} diff --git a/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex b/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex index 5cdb7569..c042a04a 100644 --- a/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/add_vhost_command.ex @@ -25,6 +25,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AddVhostCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def run([vhost], %{node: node_name}) do :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :add, [vhost]) end diff --git a/lib/rabbitmq/cli/ctl/commands/authenticate_user_command.ex b/lib/rabbitmq/cli/ctl/commands/authenticate_user_command.ex index 206c4e08..28b76f14 100644 --- a/lib/rabbitmq/cli/ctl/commands/authenticate_user_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/authenticate_user_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.AuthenticateUserCommand do def validate([_,_], _), do: :ok def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def run([user, password], %{node: node_name}) do :rabbit_misc.rpc_call(node_name, diff --git a/lib/rabbitmq/cli/ctl/commands/cancel_sync_queue_command.ex b/lib/rabbitmq/cli/ctl/commands/cancel_sync_queue_command.ex index 17939a08..9c7d097f 100644 --- a/lib/rabbitmq/cli/ctl/commands/cancel_sync_queue_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/cancel_sync_queue_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.CancelSyncQueueCommand do def flags, do: [:vhost] def switches, do: [] + def aliases, do: [] def usage, do: "cancel_sync_queue [-p ] queue" diff --git a/lib/rabbitmq/cli/ctl/commands/change_password_command.ex b/lib/rabbitmq/cli/ctl/commands/change_password_command.ex index 1569176a..2e6f1286 100644 --- a/lib/rabbitmq/cli/ctl/commands/change_password_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/change_password_command.ex @@ -21,6 +21,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ChangePasswordCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def validate(args, _) when length(args) < 2, do: {:validation_failure, :not_enough_args} def validate([_|_] = args, _) when length(args) > 2, do: {:validation_failure, :too_many_args} diff --git a/lib/rabbitmq/cli/ctl/commands/clear_parameter_command.ex b/lib/rabbitmq/cli/ctl/commands/clear_parameter_command.ex index 1e1c85fe..9827abbd 100644 --- a/lib/rabbitmq/cli/ctl/commands/clear_parameter_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/clear_parameter_command.ex @@ -19,6 +19,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearParameterCommand do @flags [:vhost] def switches(), do: [] + def aliases(), do: [] def merge_defaults(args, opts) do default_opts = Map.merge(opts, %{vhost: "/"}) {args, default_opts} diff --git a/lib/rabbitmq/cli/ctl/commands/clear_password_command.ex b/lib/rabbitmq/cli/ctl/commands/clear_password_command.ex index 0935758c..69b16fd6 100644 --- a/lib/rabbitmq/cli/ctl/commands/clear_password_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/clear_password_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearPasswordCommand do def validate([_], _), do: :ok def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def run([_user] = args, %{node: node_name}) do :rabbit_misc.rpc_call(node_name, :rabbit_auth_backend_internal, :clear_password, args) diff --git a/lib/rabbitmq/cli/ctl/commands/clear_permissions_command.ex b/lib/rabbitmq/cli/ctl/commands/clear_permissions_command.ex index af5f667f..9c521a10 100644 --- a/lib/rabbitmq/cli/ctl/commands/clear_permissions_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/clear_permissions_command.ex @@ -29,6 +29,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClearPermissionsCommand do def validate([_], _), do: :ok def switches(), do: [] + def aliases(), do: [] def run([username], %{node: node_name, vhost: vhost}) do :rabbit_misc.rpc_call(node_name, diff --git a/lib/rabbitmq/cli/ctl/commands/close_connection_command.ex b/lib/rabbitmq/cli/ctl/commands/close_connection_command.ex index f53fa1f2..95cf55e3 100644 --- a/lib/rabbitmq/cli/ctl/commands/close_connection_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/close_connection_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.CloseConnectionCommand do def validate(args, _) when length(args) < 2, do: {:validation_failure, :not_enough_args} def validate([_,_], _), do: :ok def switches(), do: [] + def aliases(), do: [] def run([pid, explanation], %{node: node_name}) do diff --git a/lib/rabbitmq/cli/ctl/commands/cluster_status_command.ex b/lib/rabbitmq/cli/ctl/commands/cluster_status_command.ex index 34210e6c..7b23337c 100644 --- a/lib/rabbitmq/cli/ctl/commands/cluster_status_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/cluster_status_command.ex @@ -20,6 +20,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ClusterStatusCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def validate(args, _) when length(args) != 0, do: {:validation_failure, :too_many_args} def validate([], _), do: :ok diff --git a/lib/rabbitmq/cli/ctl/commands/delete_user_command.ex b/lib/rabbitmq/cli/ctl/commands/delete_user_command.ex index 9ad28f70..af3a80e0 100644 --- a/lib/rabbitmq/cli/ctl/commands/delete_user_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/delete_user_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DeleteUserCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def run([username], %{node: node_name}) do :rabbit_misc.rpc_call(node_name, :rabbit_auth_backend_internal, diff --git a/lib/rabbitmq/cli/ctl/commands/delete_vhost_command.ex b/lib/rabbitmq/cli/ctl/commands/delete_vhost_command.ex index d9f57dda..e6008bf0 100644 --- a/lib/rabbitmq/cli/ctl/commands/delete_vhost_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/delete_vhost_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.DeleteVhostCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def run([arg], %{node: node_name}) do :rabbit_misc.rpc_call(node_name, :rabbit_vhost, :delete, [arg]) end diff --git a/lib/rabbitmq/cli/ctl/commands/environment_command.ex b/lib/rabbitmq/cli/ctl/commands/environment_command.ex index 9f3de466..6a9c988a 100644 --- a/lib/rabbitmq/cli/ctl/commands/environment_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/environment_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.EnvironmentCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def run([], %{node: node_name}) do :rabbit_misc.rpc_call(node_name, :rabbit, :environment, []) end diff --git a/lib/rabbitmq/cli/ctl/commands/force_reset_command.ex b/lib/rabbitmq/cli/ctl/commands/force_reset_command.ex index 57ea3153..2f443b05 100644 --- a/lib/rabbitmq/cli/ctl/commands/force_reset_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/force_reset_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ForceResetCommand do def validate([_|_] = args, _) when length(args) > 0, do: {:validation_failure, :too_many_args} def validate([], _), do: :ok def switches(), do: [] + def aliases(), do: [] def run([], %{node: node_name}) do diff --git a/lib/rabbitmq/cli/ctl/commands/help_command.ex b/lib/rabbitmq/cli/ctl/commands/help_command.ex index 4b55c1e0..135980fb 100644 --- a/lib/rabbitmq/cli/ctl/commands/help_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/help_command.ex @@ -24,6 +24,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.HelpCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def run([command_name], _) do case Helpers.is_command?(command_name) do diff --git a/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex b/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex index 394bbd70..3986b058 100644 --- a/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/join_cluster_command.ex @@ -31,6 +31,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.JoinClusterCommand do ] end + def aliases(), do: [] + def merge_defaults(args, opts) do {args, Map.merge(%{disc: true, ram: false}, opts)} end diff --git a/lib/rabbitmq/cli/ctl/commands/list_bindings_command.ex b/lib/rabbitmq/cli/ctl/commands/list_bindings_command.ex index ecf6ee53..26cb5ca0 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_bindings_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_bindings_command.ex @@ -38,6 +38,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListBindingsCommand do {args, Map.merge(default_opts, opts)} end def switches(), do: [] + def aliases(), do: [] def flags() do [:vhost] diff --git a/lib/rabbitmq/cli/ctl/commands/list_channels_command.ex b/lib/rabbitmq/cli/ctl/commands/list_channels_command.ex index 892dc52b..e5ecde04 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_channels_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_channels_command.ex @@ -39,6 +39,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListChannelsCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def flags() do [] diff --git a/lib/rabbitmq/cli/ctl/commands/list_connections_command.ex b/lib/rabbitmq/cli/ctl/commands/list_connections_command.ex index 53d14ca3..5ee419f4 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_connections_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_connections_command.ex @@ -40,6 +40,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListConnectionsCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def flags() do [] diff --git a/lib/rabbitmq/cli/ctl/commands/list_consumers_command.ex b/lib/rabbitmq/cli/ctl/commands/list_consumers_command.ex index 9dcf1e85..b49a3e5d 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_consumers_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_consumers_command.ex @@ -36,6 +36,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListConsumersCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def flags() do [:vhost] diff --git a/lib/rabbitmq/cli/ctl/commands/list_exchanges_command.ex b/lib/rabbitmq/cli/ctl/commands/list_exchanges_command.ex index f658d7b2..79c322a1 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_exchanges_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_exchanges_command.ex @@ -34,6 +34,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListExchangesCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def flags() do [:vhost] diff --git a/lib/rabbitmq/cli/ctl/commands/list_parameters_command.ex b/lib/rabbitmq/cli/ctl/commands/list_parameters_command.ex index d2725bd4..73cc3d81 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_parameters_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_parameters_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListParametersCommand do end def switches(), do: [] + def aliases(), do: [] def validate([_|_], _) do {:validation_failure, :too_many_args} diff --git a/lib/rabbitmq/cli/ctl/commands/list_permissions_command.ex b/lib/rabbitmq/cli/ctl/commands/list_permissions_command.ex index 04d1622c..4b2dc277 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_permissions_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_permissions_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListPermissionsCommand do end def switches(), do: [] + def aliases(), do: [] def validate([_|_], _) do {:validation_failure, :too_many_args} diff --git a/lib/rabbitmq/cli/ctl/commands/list_queues_command.ex b/lib/rabbitmq/cli/ctl/commands/list_queues_command.ex index 1a963f27..20923b18 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_queues_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_queues_command.ex @@ -48,6 +48,8 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListQueuesCommand do def switches(), do: [offline: :boolean, online: :boolean] + def aliases(), do: [] + def flags() do [:vhost, :offline, :online] end diff --git a/lib/rabbitmq/cli/ctl/commands/list_user_permissions_command.ex b/lib/rabbitmq/cli/ctl/commands/list_user_permissions_command.ex index 8950c93a..cba4ad08 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_user_permissions_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_user_permissions_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListUserPermissionsCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def run([username], %{node: node_name, timeout: time_out}) do :rabbit_misc.rpc_call(node_name, diff --git a/lib/rabbitmq/cli/ctl/commands/list_users_command.ex b/lib/rabbitmq/cli/ctl/commands/list_users_command.ex index 7825182a..2020efb3 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_users_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_users_command.ex @@ -20,6 +20,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListUsersCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def validate([_|_], _) do {:validation_failure, :too_many_args} end diff --git a/lib/rabbitmq/cli/ctl/commands/list_vhosts_command.ex b/lib/rabbitmq/cli/ctl/commands/list_vhosts_command.ex index ad6663ba..d1b3f01a 100644 --- a/lib/rabbitmq/cli/ctl/commands/list_vhosts_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/list_vhosts_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ListVhostsCommand do @info_keys ~w(name tracing)a def switches(), do: [] + def aliases(), do: [] def validate(args, _) do case InfoKeys.validate_info_keys(args, @info_keys) do {:ok, _} -> :ok diff --git a/lib/rabbitmq/cli/ctl/commands/node_health_check_command.ex b/lib/rabbitmq/cli/ctl/commands/node_health_check_command.ex index f882a16b..8a458b45 100644 --- a/lib/rabbitmq/cli/ctl/commands/node_health_check_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/node_health_check_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.NodeHealthCheckCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def usage, do: "node_health_check" diff --git a/lib/rabbitmq/cli/ctl/commands/purge_queue_command.ex b/lib/rabbitmq/cli/ctl/commands/purge_queue_command.ex index 081a363b..60aab679 100644 --- a/lib/rabbitmq/cli/ctl/commands/purge_queue_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/purge_queue_command.ex @@ -20,6 +20,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.PurgeQueueCommand do def flags, do: [] def switches, do: [] + def aliases, do: [] def usage, do: "purge_queue " def run([queue], %{node: node_name, vhost: vhost, timeout: timeout}) do diff --git a/lib/rabbitmq/cli/ctl/commands/report_command.ex b/lib/rabbitmq/cli/ctl/commands/report_command.ex index 84073df2..1594e0c0 100644 --- a/lib/rabbitmq/cli/ctl/commands/report_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/report_command.ex @@ -29,6 +29,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ReportCommand do @flags [] def switches(), do: [] + def aliases(), do: [] def merge_defaults(args, opts), do: {args, opts} def validate([_|_] = args, _) when length(args) != 0, do: {:validation_failure, :too_many_args} diff --git a/lib/rabbitmq/cli/ctl/commands/reset_command.ex b/lib/rabbitmq/cli/ctl/commands/reset_command.ex index 272c74be..f360fcda 100644 --- a/lib/rabbitmq/cli/ctl/commands/reset_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/reset_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.ResetCommand do def validate([_|_] = args, _) when length(args) > 0, do: {:validation_failure, :too_many_args} def validate([], _), do: :ok def switches(), do: [] + def aliases(), do: [] def run([], %{node: node_name}) do diff --git a/lib/rabbitmq/cli/ctl/commands/rotate_logs_command.ex b/lib/rabbitmq/cli/ctl/commands/rotate_logs_command.ex index 4eadd346..614368d9 100644 --- a/lib/rabbitmq/cli/ctl/commands/rotate_logs_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/rotate_logs_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.RotateLogsCommand do def validate([_|_] = args, _) when length(args) > 0, do: {:validation_failure, :too_many_args} def validate([], _), do: :ok def switches(), do: [] + def aliases(), do: [] def run([], %{node: node_name}) do diff --git a/lib/rabbitmq/cli/ctl/commands/set_cluster_name_command.ex b/lib/rabbitmq/cli/ctl/commands/set_cluster_name_command.ex index d6362e6f..757de7b5 100644 --- a/lib/rabbitmq/cli/ctl/commands/set_cluster_name_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/set_cluster_name_command.ex @@ -19,6 +19,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetClusterNameCommand do @flags [] def switches(), do: [] + def aliases(), do: [] def merge_defaults(args, opts), do: {args, opts} diff --git a/lib/rabbitmq/cli/ctl/commands/set_disk_free_limit_command.ex b/lib/rabbitmq/cli/ctl/commands/set_disk_free_limit_command.ex index 15306154..57d63e24 100644 --- a/lib/rabbitmq/cli/ctl/commands/set_disk_free_limit_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/set_disk_free_limit_command.ex @@ -21,6 +21,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetDiskFreeLimitCommand do @flags [] def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def validate([], _) do {:validation_failure, :not_enough_args} diff --git a/lib/rabbitmq/cli/ctl/commands/set_parameter_command.ex b/lib/rabbitmq/cli/ctl/commands/set_parameter_command.ex index bfa3d6b2..921ce7fd 100644 --- a/lib/rabbitmq/cli/ctl/commands/set_parameter_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/set_parameter_command.ex @@ -19,6 +19,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetParameterCommand do @flags [:vhost] def switches(), do: [] + def aliases(), do: [] def merge_defaults(args, opts) do default_opts = Map.merge(opts, %{vhost: "/"}) {args, default_opts} diff --git a/lib/rabbitmq/cli/ctl/commands/set_permissions_command.ex b/lib/rabbitmq/cli/ctl/commands/set_permissions_command.ex index 95539af7..657467ad 100644 --- a/lib/rabbitmq/cli/ctl/commands/set_permissions_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/set_permissions_command.ex @@ -20,6 +20,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetPermissionsCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def validate([], _) do {:validation_failure, :not_enough_args} end diff --git a/lib/rabbitmq/cli/ctl/commands/set_user_tags_command.ex b/lib/rabbitmq/cli/ctl/commands/set_user_tags_command.ex index 7df60716..64513047 100644 --- a/lib/rabbitmq/cli/ctl/commands/set_user_tags_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/set_user_tags_command.ex @@ -20,6 +20,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetUserTagsCommand do def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def validate([], _), do: {:validation_failure, :not_enough_args} def validate(_, _), do: :ok def run([user | tags], %{node: node_name}) do diff --git a/lib/rabbitmq/cli/ctl/commands/set_vm_memory_high_watermark_command.ex b/lib/rabbitmq/cli/ctl/commands/set_vm_memory_high_watermark_command.ex index dcb7d71e..beb6588e 100644 --- a/lib/rabbitmq/cli/ctl/commands/set_vm_memory_high_watermark_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/set_vm_memory_high_watermark_command.ex @@ -21,6 +21,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SetVmMemoryHighWatermarkCommand do @flags [] def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def validate([], _) do {:validation_failure, :not_enough_args} diff --git a/lib/rabbitmq/cli/ctl/commands/start_app_command.ex b/lib/rabbitmq/cli/ctl/commands/start_app_command.ex index 32ac8154..fc169381 100644 --- a/lib/rabbitmq/cli/ctl/commands/start_app_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/start_app_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StartAppCommand do def validate([_|_] = args, _) when length(args) > 0, do: {:validation_failure, :too_many_args} def validate([], _), do: :ok def switches(), do: [] + def aliases(), do: [] def run([], %{node: node_name}) do diff --git a/lib/rabbitmq/cli/ctl/commands/status_command.ex b/lib/rabbitmq/cli/ctl/commands/status_command.ex index 8ff55b23..8360268b 100644 --- a/lib/rabbitmq/cli/ctl/commands/status_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/status_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StatusCommand do def validate([_|_] = args, _) when length(args) > 0, do: {:validation_failure, :too_many_args} def validate([], _), do: :ok def switches(), do: [] + def aliases(), do: [] def run([], %{node: node_name}) do diff --git a/lib/rabbitmq/cli/ctl/commands/stop_app_command.ex b/lib/rabbitmq/cli/ctl/commands/stop_app_command.ex index bdeee345..d2a71b21 100644 --- a/lib/rabbitmq/cli/ctl/commands/stop_app_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/stop_app_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StopAppCommand do def validate([_|_] = args, _) when length(args) > 0, do: {:validation_failure, :too_many_args} def validate([], _), do: :ok def switches(), do: [] + def aliases(), do: [] def run([], %{node: node_name}) do diff --git a/lib/rabbitmq/cli/ctl/commands/stop_command.ex b/lib/rabbitmq/cli/ctl/commands/stop_command.ex index d7036367..d04f3172 100644 --- a/lib/rabbitmq/cli/ctl/commands/stop_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/stop_command.ex @@ -22,6 +22,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.StopCommand do def validate([_|_] = args, _) when length(args) > 0, do: {:validation_failure, :too_many_args} def validate([], _), do: :ok def switches(), do: [] + def aliases(), do: [] def run([], %{node: node_name}) do diff --git a/lib/rabbitmq/cli/ctl/commands/sync_queue_command.ex b/lib/rabbitmq/cli/ctl/commands/sync_queue_command.ex index c86c867d..7ad35046 100644 --- a/lib/rabbitmq/cli/ctl/commands/sync_queue_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/sync_queue_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.SyncQueueCommand do def flags, do: [:vhost] def switches, do: [] + def aliases, do: [] def usage, do: "sync_queue [-p ] queue" diff --git a/lib/rabbitmq/cli/ctl/commands/trace_off_command.ex b/lib/rabbitmq/cli/ctl/commands/trace_off_command.ex index a7f1c59b..630d9646 100644 --- a/lib/rabbitmq/cli/ctl/commands/trace_off_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/trace_off_command.ex @@ -23,6 +23,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.TraceOffCommand do def validate([_|_], _), do: {:validation_failure, :too_many_args} def validate(_, _), do: :ok def switches(), do: [] + def aliases(), do: [] def merge_defaults(_, opts) do {[], Map.merge(opts, %{vhost: @default_vhost})} end diff --git a/lib/rabbitmq/cli/ctl/commands/trace_on_command.ex b/lib/rabbitmq/cli/ctl/commands/trace_on_command.ex index 3834051a..7d24bb33 100644 --- a/lib/rabbitmq/cli/ctl/commands/trace_on_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/trace_on_command.ex @@ -26,6 +26,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.TraceOnCommand do end def merge_defaults(args, opts), do: {args, opts} def switches(), do: [] + def aliases(), do: [] def run([], %{node: node_name, vhost: vhost}) do :rabbit_misc.rpc_call(node_name, :rabbit_trace, :start, [vhost]) diff --git a/lib/rabbitmq/cli/ctl/commands/wait_command.ex b/lib/rabbitmq/cli/ctl/commands/wait_command.ex index 78cd5db6..44a2a2cd 100644 --- a/lib/rabbitmq/cli/ctl/commands/wait_command.ex +++ b/lib/rabbitmq/cli/ctl/commands/wait_command.ex @@ -25,6 +25,7 @@ defmodule RabbitMQ.CLI.Ctl.Commands.WaitCommand do def validate([_], _), do: :ok def switches(), do: [] + def aliases(), do: [] def run([pid_file], %{node: node_name}) do wait_for_application(node_name, pid_file, :rabbit_and_plugins); diff --git a/lib/rabbitmq/cli/ctl/helpers.ex b/lib/rabbitmq/cli/ctl/helpers.ex index 6dc3026f..f5643a7d 100644 --- a/lib/rabbitmq/cli/ctl/helpers.ex +++ b/lib/rabbitmq/cli/ctl/helpers.ex @@ -28,14 +28,7 @@ defmodule RabbitMQ.CLI.Ctl.Helpers do def is_command?([]), do: true def is_command?([head | _]), do: is_command?(head) - def is_command?(str), do: implements_command_behaviour?(commands[str]) - - defp implements_command_behaviour?(nil) do - false - end - defp implements_command_behaviour?(module) do - [RabbitMQ.CLI.CommandBehaviour] === module.module_info(:attributes)[:behaviour] - end + def is_command?(str), do: commands[str] != nil def get_rabbit_hostname(), do: ("rabbit@#{hostname}") |> String.to_atom diff --git a/lib/rabbitmq/cli/ctl/parser.ex b/lib/rabbitmq/cli/ctl/parser.ex index 2041de1b..8da7847c 100644 --- a/lib/rabbitmq/cli/ctl/parser.ex +++ b/lib/rabbitmq/cli/ctl/parser.ex @@ -27,7 +27,8 @@ defmodule RabbitMQ.CLI.Ctl.Parser do timeout: :integer, vhost: :string, longnames: :boolean]), - aliases: [p: :vhost, n: :node, q: :quiet, t: :timeout, l: :longnames] + aliases: build_aliases([p: :vhost, n: :node, q: :quiet, + t: :timeout, l: :longnames]) ) {clear_on_empty_command(cmd), options_map(options), invalid} end @@ -51,6 +52,25 @@ defmodule RabbitMQ.CLI.Ctl.Parser do end) end + defp build_aliases(default) do + Enum.reduce(RabbitMQ.CLI.Ctl.Helpers.commands, + default, + fn({_, _}, {:error, _} = err) -> err; + ({_, command}, aliases) -> + command_aliases = command.aliases() + case Enum.filter(command_aliases, + fn({key, val}) -> + existing_val = aliases[key] + existing_val != nil and existing_val != val + end) do + [] -> aliases ++ command_aliases; + _ -> exit({:command_invalid, + {command, {:invalid_switches, + command_aliases}}}) + end + end) + end + defp options_map(opts) do opts |> Map.new diff --git a/lib/rabbitmq/cli/plugins/commands/list_plugins_command.ex b/lib/rabbitmq/cli/plugins/commands/list_plugins_command.ex new file mode 100644 index 00000000..e3286740 --- /dev/null +++ b/lib/rabbitmq/cli/plugins/commands/list_plugins_command.ex @@ -0,0 +1,158 @@ +## The contents of this file are subject to the Mozilla Public License +## Version 1.1 (the "License"); you may not use this file except in +## compliance with the License. You may obtain a copy of the License +## at http://www.mozilla.org/MPL/ +## +## Software distributed under the License is distributed on an "AS IS" +## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +## the License for the specific language governing rights and +## limitations under the License. +## +## The Original Code is RabbitMQ. +## +## The Initial Developer of the Original Code is GoPivotal, Inc. +## Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved. + + +defmodule RabbitMQ.CLI.Plugins.Commands.ListCommand do + + import RabbitCommon.Records + + alias RabbitMQ.CLI.Plugins.Helpers, as: PluginHelpers + + @behaviour RabbitMQ.CLI.CommandBehaviour + + def merge_defaults([], opts), do: merge_defaults([".*"], opts) + def merge_defaults(args, opts), do: {args, Map.merge(default_opts, opts)} + + def switches(), do: [verbose: :boolean, + minimal: :boolean, + enabled: :boolean, + 'implicitly-enabled': :boolean] + def aliases(), do: [v: :verbose, m: :minimal, + 'E': :enabled, e: :'implicitly-enabled'] + + def validate(args, _) when length(args) > 1 do + {:validation_failure, :too_many_args} + end + + def validate(_, %{verbose: true, minimal: true}) do + {:validation_failure, {:bad_argument, "Cannot set both verbose and minimal"}} + end + + def validate(_, opts) do + :ok + |> validate_step(fn() -> PluginHelpers.require_rabbit(opts) end) + |> validate_step(fn() -> PluginHelpers.enabled_plugins_file(opts) end) + |> validate_step(fn() -> PluginHelpers.plugins_dist_dir(opts) end) + end + + def validate_step(:ok, step) do + case step.() do + {:error, err} -> {:validation_failure, err}; + _ -> :ok + end + end + def validate_step({:validation_failure, err}, _) do + {:validation_failure, err} + end + + def usage, do: "list [pattern] [--verbose] [--minimal] [--enabled] [--implicitly-enabled]" + + def banner([pattern], _), do: "Listing plugins with pattern \"#{pattern}\" ..." + + def flags, do: Keyword.keys(switches()) + + def run([pattern] = args, %{node: node_name} = opts) do + %{verbose: verbose, minimal: minimal, + enabled: only_enabled, + 'implicitly-enabled': all_enabled} = opts + + all = PluginHelpers.list(opts) + enabled = PluginHelpers.read_enabled(opts) + + case enabled -- plugin_names(all) do + [] -> :ok; + missing -> IO.puts("WARNING - plugins currently enabled but missing: #{missing}~n~n") + end + implicit = :rabbit_plugins.dependencies(false, enabled, all) + enabled_implicitly = implicit -- enabled + + {status, running} = + case :rabbit_misc.rpc_call(node_name, :rabbit_plugins, :active, []) do + {:badrpc, _} -> {:node_down, []}; + active -> {:running, active} + end + + {:ok, re} = Regex.compile(pattern) + + format = case {verbose, minimal} do + {true, false} -> :verbose; + {false, true} -> :minimal; + {false, false} -> :normal + end + + plugins = Enum.filter(all, + fn(plugin) -> + name = plugin_name(plugin) + + Regex.match?(re, to_string(name)) and + cond do + only_enabled -> Enum.member?(enabled, name); + all_enabled -> Enum.member(enabled ++ enabled_implicitly, name); + true -> true + end + end) + + %{status: status, + plugins: format_plugins(plugins, format, enabled, enabled_implicitly, running)} + end + + defp format_plugins(plugins, format, enabled, enabled_implicitly, running) do + plugins + |> sort_plugins + |> Enum.map(fn(plugin) -> + format_plugin(plugin, format, enabled, enabled_implicitly, running) + end) + end + + defp sort_plugins(plugins) do + Enum.sort_by(plugins, &plugin_name/1) + end + + defp format_plugin(plugin, :minimal, _, _, _) do + plugin_name(plugin) + end + defp format_plugin(plugin, :normal, enabled, enabled_implicitly, running) do + plugin(name: name, version: version) = plugin + enabled_mode = case {Enum.member?(enabled, name), Enum.member?(enabled_implicitly, name)} do + {true, false} -> :enabled; + {false, true} -> :implicit; + {false, false} -> :not_enabled + end + %{name: name, + version: version, + enabled: enabled_mode, + running: Enum.member?(running, name)} + end + defp format_plugin(plugin, :verbose, enabled, enabled_implicitly, running) do + normal = format_plugin(plugin, :normal, enabled, enabled_implicitly, running) + plugin(dependencies: dependencies, description: description) = plugin + Map.merge(normal, %{dependencies: dependencies, description: description}) + end + + defp plugin_names(plugins) do + for plugin <- plugins, do: plugin_name(plugin) + end + + defp plugin_name(plugin) do + plugin(name: name) = plugin + name + end + + defp default_opts() do + %{minimal: false, verbose: false, + enabled: false, 'implicitly-enabled': false} + end + +end diff --git a/lib/rabbitmq/cli/plugins/helpers.ex b/lib/rabbitmq/cli/plugins/helpers.ex new file mode 100644 index 00000000..0f4c5be1 --- /dev/null +++ b/lib/rabbitmq/cli/plugins/helpers.ex @@ -0,0 +1,69 @@ +## The contents of this file are subject to the Mozilla Public License +## Version 1.1 (the "License"); you may not use this file except in +## compliance with the License. You may obtain a copy of the License +## at http://www.mozilla.org/MPL/ +## +## Software distributed under the License is distributed on an "AS IS" +## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +## the License for the specific language governing rights and +## limitations under the License. +## +## The Original Code is RabbitMQ. +## +## The Initial Developer of the Original Code is GoPivotal, Inc. +## Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved. + + +defmodule RabbitMQ.CLI.Plugins.Helpers do + def list(opts) do + {:ok, dir} = plugins_dist_dir(opts) + add_all_to_path(dir) + :rabbit_plugins.list(String.to_char_list(dir)) + end + + def read_enabled(opts) do + {:ok, enabled} = enabled_plugins_file(opts) + :rabbit_plugins.read_enabled(String.to_char_list(enabled)) + end + + def enabled_plugins_file(opts) do + case opts[:enabled_plugins_file] || System.get_env("RABBITMQ_ENABLED_PLUGINS_FILE") do + nil -> {:error, :no_plugins_file}; + file -> + case File.exists?(file) do + true -> {:ok, file}; + false -> {:error, :plugins_file_not_exists} + end + end + end + + def plugins_dist_dir(opts) do + case opts[:plugins_dist_dir] || System.get_env("RABBITMQ_PLUGINS_DIR") do + nil -> {:error, :no_plugins_dir}; + dir -> + case File.dir?(dir) do + true -> {:ok, dir}; + false -> {:error, :plugins_dist_dir_not_exists} + end + end + end + + def require_rabbit(opts) do + home = opts[:rabbitmq_home] || System.get_env("RABBITMQ_HOME") + path = :filename.join(home, "ebin") + Code.append_path(path) + case Application.load(:rabbit) do + :ok -> :ok; + {:error, {:already_loaded, :rabbit}} -> :ok; + {:error, err} -> {:error, {:unable_to_load_rabbit, err}} + end + end + + defp add_all_to_path(dir) do + {:ok, subdirs} = File.ls(dir) + for subdir <- subdirs do + Path.join([dir, subdir, "ebin"]) + |> Code.append_path + end + end +end diff --git a/mix.exs b/mix.exs index 72723838..a2e9ca29 100644 --- a/mix.exs +++ b/mix.exs @@ -35,8 +35,8 @@ defmodule RabbitMQCtl.MixfileBase do # Type "mix help compile.app" for more information def application do [applications: [:logger, :mix], - env: [scopes: [{:'rabbitmq-plugins', "Plugins"}, - {:rabbitmqctl, "Ctl"}]] + env: [scopes: ['rabbitmq-plugins': :plugins, + rabbitmqctl: :ctl]] ] end