rabbitmq-server/deps/rabbitmq_cli/lib/rabbitmq/cli/command_behaviour.ex

221 lines
5.7 KiB
Elixir

## This Source Code Form is subject to the terms of the Mozilla Public
## License, v. 2.0. If a copy of the MPL was not distributed with this
## file, You can obtain one at https://mozilla.org/MPL/2.0/.
##
## Copyright (c) 2007-2023 VMware, Inc. or its affiliates. All rights reserved.
defmodule RabbitMQ.CLI.CommandBehaviour do
alias RabbitMQ.CLI.Core.Helpers
@type pair_of_strings :: nonempty_list(String.t())
@callback usage() :: String.t() | [String.t()]
# validates CLI arguments
@callback validate(list(), map()) :: :ok | {:validation_failure, atom() | {atom(), String.t()}}
@callback merge_defaults(list(), map()) :: {list(), map()}
@callback banner(list(), map()) :: [String.t()] | String.t() | nil
@callback run(list(), map()) :: any
# Coerces run/2 return value into the standard command output form
# that is then formatted, printed and returned as an exit code.
# There is a default implementation for this callback in DefaultOutput module
@callback output(any, map()) ::
:ok
| {:ok, any}
| {:stream, Enum.t()}
| {:error, RabbitMQ.CLI.Core.ExitCodes.exit_code(), [String.t()]}
@optional_callbacks formatter: 0,
printer: 0,
scopes: 0,
usage_additional: 0,
usage_doc_guides: 0,
description: 0,
help_section: 0,
switches: 0,
aliases: 0,
# validates execution environment, e.g. file presence,
# whether RabbitMQ is in an expected state on a node, etc
validate_execution_environment: 2,
distribution: 1
@callback validate_execution_environment(list(), map()) ::
:ok | {:validation_failure, atom() | {atom(), any}}
@callback switches() :: Keyword.t()
@callback aliases() :: Keyword.t()
@callback formatter() :: atom()
@callback printer() :: atom()
@callback scopes() :: [atom()] | nil
@callback description() :: String.t()
@callback help_section() :: String.t() | atom() | {:plugin, atom()}
@callback usage_additional() ::
String.t()
| [String.t()]
| nonempty_list(pair_of_strings())
| [{String.t(), String.t()}]
@callback usage_doc_guides() :: String.t() | [String.t()]
## Erlang distribution control
## :cli - default rabbitmqctl generated node name
## :none - disable erlang distribution
## {:fun, fun} - use a custom function to start distribution
@callback distribution(map()) :: :cli | :none | {:fun, (map() -> :ok | {:error, any()})}
defmacro defcmd(map) do
usage_q =
case map[:usage] do
nil ->
:ok
usage ->
quote do
def usage(), do: unquote(usage)
end
end
scopes_q =
case map[:scopes] do
nil ->
:ok
scopes ->
quote do
def scopes(), do: unquote(scopes)
end
end
description_q =
case map[:description] do
nil ->
:ok
description ->
quote do
def description(), do: unquote(description)
end
end
help_section_q =
case map[:help_section] do
nil ->
:ok
help_section ->
quote do
def help_section(), do: unquote(help_section)
end
end
usage_additional_q =
case map[:usage_additional] do
nil ->
:ok
usage_additional ->
quote do
def usage_additional(), do: unquote(usage_additional)
end
end
formatter_q =
case map[:formatter] do
nil ->
:ok
formatter ->
quote do
def formatter(), do: unquote(formatter)
end
end
switches_q =
case map[:switches] do
nil ->
:ok
switches ->
quote do
def switches(), do: unquote(switches)
end
end
aliases_q =
case map[:aliases] do
nil ->
:ok
aliases ->
quote do
def aliases(), do: unquote(aliases)
end
end
quote do
unquote(usage_q)
unquote(scopes_q)
unquote(description_q)
unquote(help_section_q)
unquote(usage_additional_q)
unquote(formatter_q)
unquote(switches_q)
unquote(aliases_q)
end
end
def usage(cmd) do
cmd.usage()
end
def scopes(cmd) do
Helpers.apply_if_exported(cmd, :scopes, [], nil)
end
def description(cmd) do
Helpers.apply_if_exported(cmd, :description, [], "")
end
def help_section(cmd) do
case Helpers.apply_if_exported(cmd, :help_section, [], :other) do
:other ->
case Application.get_application(cmd) do
:rabbitmqctl -> :other
plugin -> {:plugin, plugin}
end
section ->
section
end
end
def usage_additional(cmd) do
Helpers.apply_if_exported(cmd, :usage_additional, [], [])
end
def usage_doc_guides(cmd) do
Helpers.apply_if_exported(cmd, :usage_doc_guides, [], [])
end
def formatter(cmd, default) do
Helpers.apply_if_exported(cmd, :formatter, [], default)
end
def printer(cmd, default) do
Helpers.apply_if_exported(cmd, :printer, [], default)
end
def switches(cmd) do
Helpers.apply_if_exported(cmd, :switches, [], [])
end
def aliases(cmd) do
Helpers.apply_if_exported(cmd, :aliases, [], [])
end
def validate_execution_environment(cmd, args, options) do
Helpers.apply_if_exported(cmd, :validate_execution_environment, [args, options], :ok)
end
def distribution(cmd, options) do
Helpers.apply_if_exported(cmd, :distribution, [options], :cli)
end
end