I will introduce you to Do It, an Elixir library to create friendly CLI tools.
With DoIt, you have support to define arguments and options for your commands.
Arguments are required, and options are optional, but you can programmatically require options too.
DoIt generates a help command and a help option for each command automatically.
DoIt supports persisted options through the DoIt.Commfig module.
So, let's do it!!!
First, create a new Elixir project with mix.
mix new hello_world
Add :do_it dependency to mix.exs file, and configure escript main_module with HelloWorld module.
defmodule HelloWorld.MixProject do
  use Mix.Project
  def project do
    [
      app: :hello_world,
      version: "0.1.0",
      elixir: "~> 1.14",
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      escript: [main_moodule: HelloWorld]
    ]
  end
  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end
  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      {:do_it, "~> 0.4"}
    ]
  end
end
Now define the HelloWorld module as the main command. So, edit hello_world.ex file and use the DoIt.MainCommand module with a description key; this description is required.
defmodule HelloWorld do
  use DoIt.MainCommand,
    description: "DoIt Hello World CLI!!!"
end
Next, let's create a command, create a new file named say.ex; in the Say module use the module DoIt.Command, and add the description key to the command, too; it's mandatory.
In this command, declare an argument and two options. The argument is the message, the first option is the message template, and the last is how many times you want to print the message; define default values for the options.
defmodule HelloWorld.Say do
  use DoIt.Command,
    description: "Say something"
  argument(:message, :string, "An awesome message")
  option(:template, :string, "Message template", default: "Hello <%= @message %>!!!")
  option(:repeat, :integer, "Print message n times", default: 1)
  def run(%{message: message}, %{template: template, repeat: repeat}, _) do
    for _ <- 1..repeat, do: IO.puts(EEx.eval_string(template, assigns: [message: message]))
  end
end
Initialize the DoIt configuration and package the CLI with the mix tasks below.
mix do_it.init.config
mix escript.build
Let's try some commands.
If you run the CLI directly, without any command, you'll see an error message followed by the CLI help.
./hello_world
no command provided
Usage: hello_world COMMAND
DoIt Hello World CLI!!!
Commands:
  say     Say hello
Type ./hello_world say and you will get a new error message indicating that you must pass at least an argument and the command's help.
./hello_world say
wrong number of arguments (given 0 expected 1)
Usage: hello_world say [OPTIONS] <message>
Say hello
Arguments:
  message   An awesome message
Options:
      --help       Print this help
  -t, --template   Message template (Default: "Hello <%= @message %>!!!")
      --repeat     Print message n times (Default: 1)
Finally, execute the command passing the message World.
./hello_world say World                                                                                    
Hello World!!!
You can try different option combinations, see the video bellow.
Next time I'll detail argument and option macros and show how to build a single binary using Elixir Burrito.
    
Top comments (3)
Looks useful, but the name is a bit unfortunate due to sans-serif fonts. vocabulary.com/dictionary/Dolt ;-)
Sorry, the name is DoIt... with the pronum
it, maybe I have to start writing separately... Do It... The font tricked on me! ;-)Yeah, writing it separately, or maybe with a dash or underscore, would make it a lot clearer.