# `CliMate.CLI`
[🔗](https://github.com/lud/cli_mate/blob/v0.10.2/lib/cli_mate/cli.ex#L1)

Main API to interact with the command line.

### Basic usage

    import CliMate.CLI

    def run(argv) do
      command = [options: [verbose: [type: :boolean]], arguments: [n: [type: :integer]]]
      %{options: opts, arguments: args} = parse_or_halt!(argv, command)

      if opts.verbose do
        writeln("Hello!")
      end

      case do_something_useful(args.n) do
        :ok -> halt_success("Done!")
        {:error, reason} -> halt_error(reason)
      end
    end

# `parsed`

```elixir
@type parsed() :: %{
  :options =&gt; map(),
  :arguments =&gt; map(),
  :path =&gt; [atom()],
  optional(:execute) =&gt; function()
}
```

# `color`

```elixir
@spec color(iodata(), atom()) :: [atom() | [iodata() | [:default_color | []]]]
```

Wraps the given `iodata` with the given `color`.

`color` should be a `IO.ANSI.format/2` compatible atom.

# `debug`

Outputs `iodata` in the current shell, formatted with cyan color.

# `do_parse`

# `error`

Outputs `iodata` to `stderr` in the current shell, formatted with bright
red color.

# `extend`
*macro* 

Delegates all `CliMate.CLI` functions from the calling module.

This is useful if you want to define a module where all your CLI helpers
reside, instead of calling, say, `writeln("hello")` from
`CliMate.CLI` but `fancy_subtitle("Hello!")` from
`MyApp.CliHelpers`.

# `format_usage`

Returns a standard "usage" documentation block describing the different
options of the given command.

### Options

* `:format` - If `:moduledoc`, the formatted usage will be compatible for
  embedding in a `@moduledoc` attribute. Any other value will generate a
  simple terminal styled text. Defaults to `:cli`.
* `:io_columns` - Number of columns for the terminal, defaults to a call to
  `:io.columns/0`. Only used when format is `:cli`.

# `halt`

Stops the execution of the Erlang runtime, with a given return code.

If not provided, the return code will be `0`.

# `halt_error`

```elixir
@spec halt_error(err_code :: integer(), term()) :: no_return()
```

Combines `error/1` then `halt/1`. Halts the Erlang runtime with a `1`
return code by default.

# `halt_success`

Combines `success/1` then `halt/1`. Halts the Erlang runtime with a `0`
return code.

# `parse`

Accepts the command line arguments and the definition of a command (options,
arguments, and metadata) and returns a parse result with flues extracted from
the command line arguments.

### Defining options

Options definitions is a `Keyword` whose keys are the option name, and values
are the options parameters. Keys with underscores like `some_thing` define
options in kebab case like `--some-thing`.

The available settings for an option are described in the
`CliMate.CLI.Option` module.

The `:help` option is always defined and cannot be overridden.

### Options examples

    iex> {:ok, result} = parse(~w(--who joe), [options: [who: [type: :string]]])
    iex> result.options.who
    "joe"

    iex> {:ok, result} = parse(~w(--who joe), [options: [who: []]])
    iex> result.options.who
    "joe"

    iex> {:ok, result} = parse(~w(--port 4000), [options: [port: [type: :integer]]])
    iex> result.options.port
    4000

    iex> {:ok, result} = parse(~w(-p 4000), [options: [port: [type: :integer, short: :p]]])
    iex> result.options.port
    4000

    iex> parse(~w(--port nope), [options: [port: [type: :integer]]])
    {:error, {:invalid, [{"--port", "nope"}]}}

    iex> {:ok, result} = parse([], [options: [lang: [default: "elixir"]]])
    iex> result.options.lang
    "elixir"

    iex> {:ok, result} = parse([], [options: [lang: []]])
    iex> Map.has_key?(result.options, :lang)
    false

    iex> {:ok, result} = parse([], options: [])
    iex> result.options.help
    false

    iex> {:ok, result} = parse(~w(--help), options: [])
    iex> result.options.help
    true

### Defining arguments

Arguments can be defined in the same way as options, providing a `Keyword`
where the keys are the argument names and the values are the parameters.

The available settings for an argument are described in the
`CliMate.CLI.Argument` module.

### Arguments examples

    iex> {:ok, result} = parse(~w(joe), arguments: [who: []])
    iex> result.arguments.who
    "joe"

    iex> parse([], arguments: [who: []])
    {:error, {:missing_argument, :who}}

    iex> {:ok, result} = parse([], arguments: [who: [required: false]])
    iex> result.arguments
    %{}

    iex> cast = fn string -> Date.from_iso8601(string) end
    iex> {:ok, result} = parse(["2022-12-22"], arguments: [date: [cast: cast]])
    iex> result.arguments.date
    ~D[2022-12-22]

    iex> cast = {Date, :from_iso8601, []}
    iex> {:ok, result} = parse(["2022-12-22"], arguments: [date: [cast: cast]])
    iex> result.arguments.date
    ~D[2022-12-22]

    iex> cast = {Date, :from_iso8601, []}
    iex> parse(["not-a-date"], arguments: [date: [cast: cast]])
    {:error, {:argument_cast, :date, :invalid_format}}

### Parse result

On success, returns `{:ok, parsed}` where `parsed` is a map with:

* `:options` — map of parsed option values (with defaults applied).
* `:arguments` — map of parsed positional arguments.
* `:path` — list of sub-command keys resolved, in order (empty for a flat
  command).
* `:execute` — a zero-arity closure when the resolved command defines an
  `:execute` function (or a module-based command implementing `execute/1`),
  otherwise `nil`. Calling it invokes the function with the parsed map (with
  the `:execute` key removed). Always `nil` when `--help` was given.

### Sub-commands

A command may declare `:subcommands` instead of `:arguments`. The first
positional argument is then consumed as the sub-command name and parsing
recurses into the selected child. Options declared on a parent are inherited
and can be passed on any level. See `CliMate.CLI.Command` for the
full inheritance and merging rules.

# `parse_or_halt!`

Attempts to parse the command line arguments `argv` with the defined
command.

Command options and arguments are documented in the `parse/2` function of
this module.

In `parse_or_halt!/2`, the successful return value will not be wrapped in
an `:ok` tuple, but directly a map with the `:options` and `:arguments`
keys.

In case of a parse error, this function will output the usage block
followed by a formatted error message, and halt the Erlang runtime.

# `put_shell`

Defines the current shell to send console messages to. Accepts either
`CliMate.CLI` or `CliMate.CLI.ProcessShell`.

This is mostly done for testing. The default shell outputs to standard io as
you would expect.

The shell is saved to `:persistent_term`, so shell should not be changed
repeatedly during runtime. This method of persistence is subject to change and
should not be relied on.

# `safe_to_string`

```elixir
@spec safe_to_string(term()) :: binary()
```

Returns a string representation of the given term, with fallback to
`Kernel.inspect/1`.

# `shell`

Returns the current shell to send output to.

# `success`

Outputs `iodata` in the current shell, formatted with green color.

# `warn`

Outputs `iodata` to `stderr` in the current shell, formatted with yellow
color.

# `with_safe_path`

Executes the given fun while keeping the paths for the given app or apps
code in the current code path.

This is useful when running mix tasks that change the code path, for command
line applications installed globally with `mix archive.insall`.

It is not needed for regular mix tasks or escripts.

# `write`

Outputs `iodata` in the current shell.

# `writeln`

Outputs `iodata` in the current shell.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
