View Source Tux.Command behaviour (Tux v0.4.0)
A command module provides the implementation for a given command,
and it can be registered on a given dispatcher using the
Tux.Dispatcher.cmd/2
macro.
At a minimum, a command module needs to implement only the main/2
callback.
The full list of callbacks is as follows:
main/2
(required) – implements the command logic.about/0
(optional) – returns the command's short description.help/0
(optional) – returns command's help message – seeTux.Help
.show/2
(optional) – writes final command output.exit/2
(optional) – stop the VM with an appropriate exit code.
Example
Here's an example of a typical command module:
defmodule ExampleCmd do
use Tux.Command
@impl true
def about(), do: "this command does something"
@impl true
def main(env, args), do: {:ok, "some result"}
@impl true
def help() do
Help.new()
|> Help.about(about())
|> ...
|> Help.ok()
end
end
Summary
Types
Command line arguments invoked with a command. These args will be available
to the command module via the second parameter to the main/2
callback.
A command module
Callbacks
Return a very short command description which might be used when generating the help message.
Stop the Erlang VM using an appropriate exit code to reflect the command's
outcome. This callback is implemented whenever you use Tux.Command
,
however it can be overwritten for more a custom exit logic
Return the full help message for the command.
Implement the command logic.
Write the final command result to the Tux.Env
's device.
Functions
Implementation of the use Tux.Command
functionality.
Types
Callbacks
@callback about() :: String.t()
Return a very short command description which might be used when generating the help message.
defmodule ExampleCmd do
use Tux.Command
@impl true
def about(), do: "this command does something really cool"
...
end
@callback exit(env :: Tux.Env.t(), result :: Tux.Result.t()) :: :ok | no_return()
Stop the Erlang VM using an appropriate exit code to reflect the command's
outcome. This callback is implemented whenever you use Tux.Command
,
however it can be overwritten for more a custom exit logic:
defmodule ExampleCmd do
use Tux.Command
@impl true
def exit(env, result) do
case result do
:ok -> System.halt(0)
:error -> System.halt(1)
end
# System.stop(..) – slower, graceful
# System.halt(..) – faster, not graceful
end
end
Do note that System.stop/1
performs an asynchronous and careful stop
of the Erlang runtime system (but takes more time), whereas System.halt/1
immediately halts the runtime system, which in turn will lead to
commands feeling snappier at the expense of graceful termination.
@callback help() :: {:ok, Tux.Help.t()}
Return the full help message for the command.
defmodule ExampleCmd do
use Tux.Command
alias Tux.Help
@impl true
def help() do
Help.new()
|> Help.usage("mycmd", "run some command")}
|> Help...
|> Help.ok()
end
end
You can also craft the help message as a string:
defmodule ExampleCmd do
use Tux.Command
@impl true
def help() do
"""
#{bold("USAGE")}
command [ARGS] [FLAGS]
#{bold("OPTIONS")}
--flag1 This flag does something
--flag2, -f2 This flag does something else
"""
|> fn msg -> {:ok, msg} end.()
end
end
@callback main(env :: Tux.Env.t(), args :: args()) :: Tux.Result.t()
Implement the command logic.
This callback accepts two arguments, a Tux.Env
and a list
of raw arguments given to the command which you can parse with
OptionParser
.
defmodule ExampleCmd do
use Tux.Command
@impl true
def main(env, args) do
... implement command and return result here
end
end
@callback show(env :: Tux.Env.t(), result :: Tux.Result.t()) :: :ok
Write the final command result to the Tux.Env
's device.
Although this callback is injected whenever you use Tux.Command
,
it is overridable and you can implement it yourself in your own command module
for a more custom command result printing.
defmodule ExampleCmd do
use Tux.Command
@impl true
def show(env, result) do
case result do
{:ok, data} -> IO.write(env.dev, data)
_ -> IO.write(env.dev, "Something failed")
end
end
end