Current section

Files

Jump to
mix_test_interactive lib mix_test_interactive command.ex
Raw

lib/mix_test_interactive/command.ex

defmodule MixTestInteractive.Command do
@moduledoc """
Behaviour for interactive mode commands.
All commands must implement this behaviour.
It is recommended to `use` this module in the command's module:
```
defmodule MyCommand do
use MixTestInteractive.Command,
command: "c",
desc: "do the thing"
# ...
end
```
This will provide overridable implementations of most of the callbacks.
`:command` is the key sequence the user will use to invoke the command. If a more appropriate
command name is required in the help text, you can override the `name/0` callback.
`:desc` is the command's description.
`:command` and `:desc` should be written so that the following pattern reads nicely in the
usage output: `<command> to <description>`. For example, `a to run all tests`.
"""
alias MixTestInteractive.Settings
@type response :: {:ok, Settings.t()} | {:no_run, Settings.t()} | :help | :quit | :unknown
@doc """
Is the command applicable given the current configuration?
Returns `true` by default if not overridden.
"""
@callback applies?(Settings.t()) :: boolean()
@doc """
The command's description.
Descriptions should be written to fit the pattern `<command> to <description>`.
For example, `a to run all tests`.
Returns the value of the `:desc` argument passed in the `use` statement.
Not overridable.
"""
@callback description :: String.t()
@doc """
The command's key sequence.
Key sequences should be short (single character preferred) and unique.
Returns the value of the `:command` argument passed in the `use` statement.
Not overridable.
"""
@callback command :: String.t()
@doc """
The command's name.
Readable name for the command.
Defaults to the `command/0`, but can be overridden to make usage output clearer.
"""
@callback name :: String.t()
@doc """
Execute the command.
Performs the desired action in response to the command.
Most commands return an `:ok` tuple with an updated configuration, allowing
`MixTestInteractive.InteractiveMode` to run the tests with the new configuration.
A command can return a `:no_run` tuple with an updated configuration if the tests
should not be run in response to the command.
A command can return `:help` to show detailed usage information, or `:quit` to
exit `mix test.interactive`.
No default provided.
"""
@callback run([String.t()], Settings.t()) :: response()
defmacro __using__(opts) do
description = Keyword.fetch!(opts, :desc)
command = Keyword.fetch!(opts, :command)
quote do
@behaviour MixTestInteractive.Command
@impl true
def applies?(_settings), do: true
@impl true
def description, do: unquote(description)
@impl true
def command, do: unquote(command)
@impl true
def name, do: unquote(command)
defoverridable applies?: 1, name: 0
end
end
end