# `Alaja.CLI.Definition`
[🔗](https://github.com/Lorenzo-SF/alaja/blob/2.1.0/lib/alaja/cli/definition.ex#L1)

Declarative DSL for defining CLI commands.

## Usage

    defmodule MyApp.CLI do
      use Alaja.CLI.Definition, otp_app: :my_app

      command "deploy", "Deploy to production" do
        flag :env, :string, default: "staging", values: ~w(staging production)
        flag :force, :boolean, default: false

        run fn opts ->
          IO.puts("Deploying to " <> opts.env)
          if opts.force, do: IO.puts("Forced mode!")
        end
      end

      subcommand "config", "Manage configuration" do
        command "get", "Read a value" do
          argument :key, :string, required: true
          run fn opts -> IO.inspect(opts.key) end
        end
      end
    end

## Structure

The DSL generates a command map with the following shape:

    %{
      name: "deploy",
      description: "Deploy to production",
      flags: [...],
      arguments: [...],
      subcommands: %{},
      run: function
    }

# `arg_type`

```elixir
@type arg_type() :: :string | :integer | :float
```

# `flag_type`

```elixir
@type flag_type() :: :string | :integer | :float | :boolean | :atom
```

# `argument`
*macro* 

```elixir
@spec argument(atom(), arg_type(), Keyword.t()) :: Macro.t()
```

Defines a positional argument within a command.

# `command`
*macro* 

```elixir
@spec command(String.t(), String.t(), [{:do, Macro.t()}]) :: Macro.t()
```

Defines a CLI command with a name, description, and block.

# `flag`
*macro* 

```elixir
@spec flag(atom(), flag_type(), Keyword.t()) :: Macro.t()
```

Defines a CLI flag within a command.

# `run`
*macro* 

```elixir
@spec run({module(), atom()}) :: Macro.t()
```

Defines the handler for a command.

Accepts a `{module, function_name}` tuple. The handler will be called
with a single argument: the parsed opts map, which includes `:_args`
(the raw positional arguments).

## Example

    command "deploy", "Deploy to production" do
      flag :env, :string, default: "staging"
      run {MyApp.Deploy, :run}
    end

# `subcommand`
*macro* 

```elixir
@spec subcommand(String.t(), String.t(), [{:do, Macro.t()}]) :: Macro.t()
```

Defines a CLI subcommand group.

---

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