script name is overridable via argument
This commit is contained in:
parent
60fdcecdb4
commit
ad90e60121
|
|
@ -8,6 +8,8 @@ dep_json = hex 1.0.0
|
||||||
|
|
||||||
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk
|
DEP_PLUGINS = rabbit_common/mk/rabbitmq-plugin.mk
|
||||||
|
|
||||||
|
TEST_FILE ?= ""
|
||||||
|
|
||||||
include rabbitmq-components.mk
|
include rabbitmq-components.mk
|
||||||
include erlang.mk
|
include erlang.mk
|
||||||
|
|
||||||
|
|
@ -32,5 +34,11 @@ rel::
|
||||||
tests:: all
|
tests:: all
|
||||||
mix test --trace
|
mix test --trace
|
||||||
|
|
||||||
|
test:: all
|
||||||
|
mix test --trace $(TEST_FILE)
|
||||||
|
|
||||||
clean::
|
clean::
|
||||||
mix clean
|
mix clean
|
||||||
|
|
||||||
|
repl:
|
||||||
|
iex -S mix
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ use Mix.Config
|
||||||
#
|
#
|
||||||
# Or configure a 3rd-party app:
|
# Or configure a 3rd-party app:
|
||||||
#
|
#
|
||||||
# config :logger, level: :info
|
config :logger, level: :warn
|
||||||
#
|
#
|
||||||
|
|
||||||
# It is also possible to import configuration files, relative to this
|
# It is also possible to import configuration files, relative to this
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ defmodule RabbitMQ.CLI.Config do
|
||||||
def get_option(name, opts) do
|
def get_option(name, opts) do
|
||||||
raw_option = opts[name] ||
|
raw_option = opts[name] ||
|
||||||
get_system_option(name) ||
|
get_system_option(name) ||
|
||||||
default(name, opts)
|
default(name)
|
||||||
normalize(name, raw_option)
|
normalize(name, raw_option)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -28,6 +28,11 @@ defmodule RabbitMQ.CLI.Config do
|
||||||
def normalize(:longnames, _), do: :shortnames
|
def normalize(:longnames, _), do: :shortnames
|
||||||
def normalize(_, value), do: value
|
def normalize(_, value), do: value
|
||||||
|
|
||||||
|
def get_system_option(:script_name) do
|
||||||
|
Path.basename(:escript.script_name())
|
||||||
|
|> Path.rootname
|
||||||
|
|> String.to_atom
|
||||||
|
end
|
||||||
def get_system_option(name) do
|
def get_system_option(name) do
|
||||||
system_env_option = case name do
|
system_env_option = case name do
|
||||||
:longnames -> "RABBITMQ_USE_LONGNAME";
|
:longnames -> "RABBITMQ_USE_LONGNAME";
|
||||||
|
|
@ -40,5 +45,6 @@ defmodule RabbitMQ.CLI.Config do
|
||||||
System.get_env(system_env_option)
|
System.get_env(system_env_option)
|
||||||
end
|
end
|
||||||
|
|
||||||
def default(_, _), do: nil
|
def default(:script_name), do: :rabbitmqctl
|
||||||
|
def default(_), do: nil
|
||||||
end
|
end
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
defmodule AutoComplete do
|
defmodule AutoComplete do
|
||||||
alias RabbitMQ.CLI.Ctl.Helpers, as: Helpers
|
alias RabbitMQ.CLI.Ctl.Helpers, as: Helpers
|
||||||
alias RabbitMQ.CLI.Ctl.Parser, as: Parser
|
alias RabbitMQ.CLI.Ctl.Parser, as: Parser
|
||||||
|
alias RabbitMQ.CLI.Ctl.CommandModules, as: CommandModules
|
||||||
|
|
||||||
@spec complete(String.t) :: {:ok, [String.t]}
|
@spec complete(String.t) :: {:ok, [String.t]}
|
||||||
def complete(str) do
|
def complete(str) do
|
||||||
|
|
@ -24,7 +25,8 @@ defmodule AutoComplete do
|
||||||
case List.last(tokens) do
|
case List.last(tokens) do
|
||||||
nil -> [];
|
nil -> [];
|
||||||
last_token ->
|
last_token ->
|
||||||
{args, _, _} = Parser.parse(tokens)
|
{args, opts, _} = Parser.parse(tokens)
|
||||||
|
CommandModules.load(opts)
|
||||||
variants = case args do
|
variants = case args do
|
||||||
[] -> complete_default_opts(last_token);
|
[] -> complete_default_opts(last_token);
|
||||||
[cmd|_] -> complete_command_opts(cmd, last_token)
|
[cmd|_] -> complete_command_opts(cmd, last_token)
|
||||||
|
|
|
||||||
|
|
@ -13,33 +13,25 @@
|
||||||
## The Initial Developer of the Original Code is GoPivotal, Inc.
|
## The Initial Developer of the Original Code is GoPivotal, Inc.
|
||||||
## Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.
|
## Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.
|
||||||
|
|
||||||
|
alias RabbitMQ.CLI.Config, as: Config
|
||||||
|
|
||||||
defmodule RabbitMQ.CLI.Ctl.CommandModules do
|
defmodule RabbitMQ.CLI.Ctl.CommandModules do
|
||||||
@commands_ns ~r/RabbitMQ.CLI.(.*).Commands/
|
@commands_ns ~r/RabbitMQ.CLI.(.*).Commands/
|
||||||
|
|
||||||
def module_map do
|
def module_map do
|
||||||
case Application.get_env(:rabbitmqctl, :commands) do
|
Application.get_env(:rabbitmqctl, :commands) || load(%{})
|
||||||
nil -> load;
|
|
||||||
val -> val
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def load do
|
def load(opts) do
|
||||||
scope = script_scope
|
scope = script_scope(opts)
|
||||||
commands = load_commands(scope)
|
commands = load_commands(scope)
|
||||||
Application.put_env(:rabbitmqctl, :commands, commands)
|
Application.put_env(:rabbitmqctl, :commands, commands)
|
||||||
commands
|
commands
|
||||||
end
|
end
|
||||||
|
|
||||||
def script_scope do
|
def script_scope(opts) do
|
||||||
scopes = Application.get_env(:rabbitmqctl, :scopes, [])
|
scopes = Application.get_env(:rabbitmqctl, :scopes, [])
|
||||||
scopes[script_name] || :none
|
scopes[Config.get_option(:script_name, opts)] || :none
|
||||||
end
|
|
||||||
|
|
||||||
def script_name do
|
|
||||||
Path.basename(:escript.script_name())
|
|
||||||
|> Path.rootname
|
|
||||||
|> String.to_atom
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_commands(scope) do
|
def load_commands(scope) do
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,15 @@ defmodule RabbitMQ.CLI.Ctl.Parser do
|
||||||
# Output: A 2-tuple of lists: one containing the command,
|
# Output: A 2-tuple of lists: one containing the command,
|
||||||
# one containing flagged options.
|
# one containing flagged options.
|
||||||
def parse(command) do
|
def parse(command) do
|
||||||
|
switches = build_switches(default_switches())
|
||||||
{options, cmd, invalid} = OptionParser.parse(
|
{options, cmd, invalid} = OptionParser.parse(
|
||||||
command,
|
command,
|
||||||
strict: build_switches(default_switches()),
|
strict: switches,
|
||||||
aliases: build_aliases([p: :vhost, n: :node, q: :quiet,
|
aliases: build_aliases([p: :vhost, n: :node, q: :quiet,
|
||||||
t: :timeout, l: :longnames])
|
t: :timeout, l: :longnames])
|
||||||
)
|
)
|
||||||
{clear_on_empty_command(cmd), options_map(options), invalid}
|
norm_options = normalize_options(options, switches)
|
||||||
|
{clear_on_empty_command(cmd), Map.new(norm_options), invalid}
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_switches() do
|
def default_switches() do
|
||||||
|
|
@ -37,7 +39,8 @@ defmodule RabbitMQ.CLI.Ctl.Parser do
|
||||||
longnames: :boolean,
|
longnames: :boolean,
|
||||||
formatter: :string,
|
formatter: :string,
|
||||||
printer: :string,
|
printer: :string,
|
||||||
file: :string]
|
file: :string,
|
||||||
|
script_name: :atom]
|
||||||
end
|
end
|
||||||
|
|
||||||
defp build_switches(default) do
|
defp build_switches(default) do
|
||||||
|
|
@ -78,9 +81,18 @@ defmodule RabbitMQ.CLI.Ctl.Parser do
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp options_map(opts) do
|
defp normalize_options(options, switches) do
|
||||||
opts
|
Enum.map(options,
|
||||||
|> Map.new
|
fn({key, option}) ->
|
||||||
|
{key, normalize_type(option, switches[key])}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp normalize_type(value, :atom) when is_binary(value) do
|
||||||
|
String.to_atom(value)
|
||||||
|
end
|
||||||
|
defp normalize_type(value, _type) do
|
||||||
|
value
|
||||||
end
|
end
|
||||||
|
|
||||||
# Discards entire command if first command term is empty.
|
# Discards entire command if first command term is empty.
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,8 @@ defmodule RabbitMQ.CLI.Plugins.Commands.DisableCommand do
|
||||||
@behaviour RabbitMQ.CLI.CommandBehaviour
|
@behaviour RabbitMQ.CLI.CommandBehaviour
|
||||||
use RabbitMQ.CLI.DefaultOutput
|
use RabbitMQ.CLI.DefaultOutput
|
||||||
|
|
||||||
def merge_defaults(args, %{offline: false, online: false} = opts) do
|
|
||||||
{args, Map.merge(%{online: true, offline: false}, opts)}
|
|
||||||
end
|
|
||||||
def merge_defaults(args, opts) do
|
def merge_defaults(args, opts) do
|
||||||
{args, Map.merge(%{online: true, offline: false}, opts)}
|
{args, Map.merge(%{online: false, offline: false}, opts)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def switches(), do: [online: :boolean,
|
def switches(), do: [online: :boolean,
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,8 @@ defmodule RabbitMQ.CLI.Plugins.Commands.EnableCommand do
|
||||||
@behaviour RabbitMQ.CLI.CommandBehaviour
|
@behaviour RabbitMQ.CLI.CommandBehaviour
|
||||||
use RabbitMQ.CLI.DefaultOutput
|
use RabbitMQ.CLI.DefaultOutput
|
||||||
|
|
||||||
def merge_defaults(args, %{offline: false, online: false} = opts) do
|
|
||||||
{args, Map.merge(%{online: true, offline: false}, opts)}
|
|
||||||
end
|
|
||||||
def merge_defaults(args, opts) do
|
def merge_defaults(args, opts) do
|
||||||
{args, Map.merge(%{online: true, offline: false}, opts)}
|
{args, Map.merge(%{online: false, offline: false}, opts)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def switches(), do: [online: :boolean,
|
def switches(), do: [online: :boolean,
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,9 @@ defmodule RabbitMQ.CLI.Plugins.Commands.SetCommand do
|
||||||
@behaviour RabbitMQ.CLI.CommandBehaviour
|
@behaviour RabbitMQ.CLI.CommandBehaviour
|
||||||
use RabbitMQ.CLI.DefaultOutput
|
use RabbitMQ.CLI.DefaultOutput
|
||||||
|
|
||||||
def merge_defaults(args, %{offline: false, online: false} = opts) do
|
|
||||||
{args, Map.merge(%{online: true, offline: false}, opts)}
|
|
||||||
end
|
|
||||||
def merge_defaults(args, opts) do
|
def merge_defaults(args, opts) do
|
||||||
{args, Map.merge(%{online: true, offline: false}, opts)}
|
IO.inspect opts
|
||||||
|
{args, Map.merge(%{online: false, offline: false}, opts)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def switches(), do: [online: :boolean,
|
def switches(), do: [online: :boolean,
|
||||||
|
|
@ -66,8 +64,9 @@ defmodule RabbitMQ.CLI.Plugins.Commands.SetCommand do
|
||||||
%{online: online, offline: offline} = opts
|
%{online: online, offline: offline} = opts
|
||||||
|
|
||||||
mode = case {online, offline} do
|
mode = case {online, offline} do
|
||||||
{true, false} -> :online;
|
{true, false} -> :online;
|
||||||
{false, true} -> :offline
|
{false, true} -> :offline;
|
||||||
|
{false, false} -> :online
|
||||||
end
|
end
|
||||||
|
|
||||||
PluginHelpers.set_enabled_plugins(plugins, mode, node_name, opts)
|
PluginHelpers.set_enabled_plugins(plugins, mode, node_name, opts)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ defmodule RabbitMQCtl do
|
||||||
alias RabbitMQ.CLI.Ctl.Commands.HelpCommand, as: HelpCommand
|
alias RabbitMQ.CLI.Ctl.Commands.HelpCommand, as: HelpCommand
|
||||||
alias RabbitMQ.CLI.Output, as: Output
|
alias RabbitMQ.CLI.Output, as: Output
|
||||||
alias RabbitMQ.CLI.ExitCodes, as: ExitCodes
|
alias RabbitMQ.CLI.ExitCodes, as: ExitCodes
|
||||||
|
alias RabbitMQ.CLI.Ctl.CommandModules, as: CommandModules
|
||||||
|
|
||||||
import RabbitMQ.CLI.Ctl.Helpers
|
import RabbitMQ.CLI.Ctl.Helpers
|
||||||
import RabbitMQ.CLI.Ctl.Parser
|
import RabbitMQ.CLI.Ctl.Parser
|
||||||
|
|
@ -32,6 +33,8 @@ defmodule RabbitMQCtl do
|
||||||
end
|
end
|
||||||
def main(unparsed_command) do
|
def main(unparsed_command) do
|
||||||
{parsed_cmd, parsed_options, invalid} = parse(unparsed_command)
|
{parsed_cmd, parsed_options, invalid} = parse(unparsed_command)
|
||||||
|
options = parsed_options |> merge_all_defaults |> normalize_node
|
||||||
|
CommandModules.load(options)
|
||||||
case {is_command?(parsed_cmd), invalid} do
|
case {is_command?(parsed_cmd), invalid} do
|
||||||
## No such command
|
## No such command
|
||||||
{false, _} ->
|
{false, _} ->
|
||||||
|
|
@ -42,7 +45,6 @@ defmodule RabbitMQCtl do
|
||||||
error = validation_error({:bad_option, invalid}, unparsed_command);
|
error = validation_error({:bad_option, invalid}, unparsed_command);
|
||||||
## Command valid
|
## Command valid
|
||||||
{true, []} ->
|
{true, []} ->
|
||||||
options = parsed_options |> merge_all_defaults |> normalize_node
|
|
||||||
Distribution.start(options)
|
Distribution.start(options)
|
||||||
|
|
||||||
[command_name | arguments] = parsed_cmd
|
[command_name | arguments] = parsed_cmd
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
## The Initial Developer of the Original Code is GoPivotal, Inc.
|
## The Initial Developer of the Original Code is GoPivotal, Inc.
|
||||||
## Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.
|
## Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.
|
||||||
|
|
||||||
|
alias RabbitMQ.CLI.Config, as: Config
|
||||||
|
|
||||||
defmodule CommandModulesTest do
|
defmodule CommandModulesTest do
|
||||||
use ExUnit.Case, async: false
|
use ExUnit.Case, async: false
|
||||||
|
|
@ -54,7 +55,7 @@ defmodule CommandModulesTest do
|
||||||
|
|
||||||
test "load commands for current scope" do
|
test "load commands for current scope" do
|
||||||
set_scope(:ctl)
|
set_scope(:ctl)
|
||||||
commands = @subject.load
|
commands = @subject.load(%{})
|
||||||
assert commands == @subject.load_commands(:ctl)
|
assert commands == @subject.load_commands(:ctl)
|
||||||
|
|
||||||
assert commands["duck"] == RabbitMQ.CLI.Ctl.Commands.DuckCommand
|
assert commands["duck"] == RabbitMQ.CLI.Ctl.Commands.DuckCommand
|
||||||
|
|
@ -67,7 +68,7 @@ defmodule CommandModulesTest do
|
||||||
assert commands["raven"] == nil
|
assert commands["raven"] == nil
|
||||||
|
|
||||||
set_scope(:plugins)
|
set_scope(:plugins)
|
||||||
commands = @subject.load
|
commands = @subject.load(%{})
|
||||||
assert commands == @subject.load_commands(:plugins)
|
assert commands == @subject.load_commands(:plugins)
|
||||||
assert commands["duck"] == nil
|
assert commands["duck"] == nil
|
||||||
assert commands["gray_goose"] == nil
|
assert commands["gray_goose"] == nil
|
||||||
|
|
@ -111,7 +112,7 @@ defmodule CommandModulesTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_scope(scope) do
|
def set_scope(scope) do
|
||||||
script_name = @subject.script_name
|
script_name = Config.get_option(:script_name, %{})
|
||||||
scopes = Keyword.put(Application.get_env(:rabbitmqctl, :scopes), script_name, scope)
|
scopes = Keyword.put(Application.get_env(:rabbitmqctl, :scopes), script_name, scope)
|
||||||
Application.put_env(:rabbitmqctl, :scopes, scopes)
|
Application.put_env(:rabbitmqctl, :scopes, scopes)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -47,26 +47,26 @@ defmodule ParserTest do
|
||||||
|
|
||||||
test "one arity 0 command, one single-dash node option" do
|
test "one arity 0 command, one single-dash node option" do
|
||||||
assert @subject.parse(["sandwich", "-n", "rabbitmq@localhost"]) ==
|
assert @subject.parse(["sandwich", "-n", "rabbitmq@localhost"]) ==
|
||||||
{["sandwich"], %{node: "rabbitmq@localhost"}, []}
|
{["sandwich"], %{node: :"rabbitmq@localhost"}, []}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "one arity 1 command, one single-dash node option" do
|
test "one arity 1 command, one single-dash node option" do
|
||||||
assert @subject.parse(["sandwich", "pastrami", "-n", "rabbitmq@localhost"]) ==
|
assert @subject.parse(["sandwich", "pastrami", "-n", "rabbitmq@localhost"]) ==
|
||||||
{["sandwich", "pastrami"], %{node: "rabbitmq@localhost"}, []}
|
{["sandwich", "pastrami"], %{node: :"rabbitmq@localhost"}, []}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "one arity 1 command, one single-dash node option and one quiet flag" do
|
test "one arity 1 command, one single-dash node option and one quiet flag" do
|
||||||
assert @subject.parse(["sandwich", "pastrami", "-n", "rabbitmq@localhost", "--quiet"]) ==
|
assert @subject.parse(["sandwich", "pastrami", "-n", "rabbitmq@localhost", "--quiet"]) ==
|
||||||
{["sandwich", "pastrami"], %{node: "rabbitmq@localhost", quiet: true}, []}
|
{["sandwich", "pastrami"], %{node: :"rabbitmq@localhost", quiet: true}, []}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "single-dash node option before command" do
|
test "single-dash node option before command" do
|
||||||
assert @subject.parse(["-n", "rabbitmq@localhost", "sandwich", "pastrami"]) ==
|
assert @subject.parse(["-n", "rabbitmq@localhost", "sandwich", "pastrami"]) ==
|
||||||
{["sandwich", "pastrami"], %{node: "rabbitmq@localhost"}, []}
|
{["sandwich", "pastrami"], %{node: :"rabbitmq@localhost"}, []}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "no commands, one double-dash node option" do
|
test "no commands, one double-dash node option" do
|
||||||
assert @subject.parse(["--node=rabbitmq@localhost"]) == {[], %{node: "rabbitmq@localhost"}, []}
|
assert @subject.parse(["--node=rabbitmq@localhost"]) == {[], %{node: :"rabbitmq@localhost"}, []}
|
||||||
end
|
end
|
||||||
|
|
||||||
test "no commands, one integer --timeout value" do
|
test "no commands, one integer --timeout value" do
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue