DEV Community

Rodrigo Zampieri Castilho
Rodrigo Zampieri Castilho

Posted on • Edited on

Do It - Elixir Command Line Interface Library

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Initialize the DoIt configuration and package the CLI with the mix tasks below.

mix do_it.init.config
mix escript.build
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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)

Enter fullscreen mode Exit fullscreen mode

Finally, execute the command passing the message World.

./hello_world say World                                                                                    
Hello World!!!
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
davearonson profile image
Dave Aronson

Looks useful, but the name is a bit unfortunate due to sans-serif fonts. vocabulary.com/dictionary/Dolt ;-)

Collapse
 
rzcastilho profile image
Rodrigo Zampieri Castilho • Edited

Sorry, the name is DoIt... with the pronum it, maybe I have to start writing separately... Do It... The font tricked on me! ;-)

Collapse
 
davearonson profile image
Dave Aronson

Yeah, writing it separately, or maybe with a dash or underscore, would make it a lot clearer.