Cheer (Cheer v0.2.0)

Copy Markdown View Source

A clap-inspired CLI argument parsing framework for Elixir.

Provides declarative command definitions with arbitrarily nested subcommands, typed options, automatic help generation, and shell completion.

Usage

defmodule MyApp.CLI.Greet do
  use Cheer.Command

  command "greet" do
    about "Greet someone"

    argument :name, type: :string, required: true, help: "Name to greet"
    option :loud, type: :boolean, short: :l, help: "Shout the greeting"
  end

  @impl Cheer.Command
  def run(%{name: name} = args, _opts) do
    greeting = "Hello, #{name}!"
    if args[:loud], do: String.upcase(greeting), else: greeting
  end
end

Architecture

Commands are modules that use Cheer.Command. Each command declares its name, about text, arguments, options, and subcommands via macros. At compile time, Cheer builds a command tree that handles:

  • Argv routing through nested subcommands
  • Option parsing via OptionParser
  • Type validation and coercion
  • Help text generation
  • Shell completion script generation (bash, zsh, fish)

Summary

Functions

Run as an escript entry point, halting the VM with a conventional exit code.

Parse argv and dispatch to the appropriate command handler.

Returns the command tree as a nested data structure.

Functions

main(root_command, argv, opts \\ [])

@spec main(module(), [String.t()], keyword()) :: no_return()

Run as an escript entry point, halting the VM with a conventional exit code.

Dispatches argv like run/3, then halts the VM: 0 on success (including --help and --version) and 2 on a usage failure. The command's own run/2 return value does not affect the exit code; a command that wants custom codes should call run/3 and halt itself.

def main(argv), do: Cheer.main(MyApp.CLI, argv, prog: "myapp")

run(root_command, argv, opts \\ [])

@spec run(module(), [String.t()], keyword()) :: term() | {:error, :usage}

Parse argv and dispatch to the appropriate command handler.

Options:

  • :prog - program name for usage lines (default: derived from root command name)

Return value

  • On success, returns whatever the matched command's run/2 returns.
  • On a usage failure (unknown option, missing required argument, bad choice, unknown or ambiguous subcommand, missing required subcommand), prints the error and returns {:error, :usage}.
  • For --help / --version (and a bare command that just prints help), returns :ok.

Use the {:error, :usage} result to set a nonzero exit code, or call main/3 to have Cheer halt with a conventional code for you.

tree(command)

@spec tree(module()) :: map()

Returns the command tree as a nested data structure.

Useful for documentation generation, introspection, and testing.