How to Build Command-Line Applications (CLI) with Ruby

Many people forget that Ruby can do things that aren’t web applications. In this article, I want to show you how to build a command-line application to help remedy that!

Here are some command-line applications you may be familiar with:

  • psql
  • rails
  • bundler
  • gem
  • git

There are many ways to build a command-line application & in this article we are going to focus on three of them.

You’re going to learn about:

  • The ARGV array
  • The OptParse library
  • The Thor gem

Let’s get started!

The Ruby ARGV Constant

Command-line applications usually take multiple options or ‘flags’.

For example:

psql --help

How can you access these options in Ruby?

Using the ARGV array.

If you have the following code in a file named argv.rb:

p ARGV

And if you run this code using ruby argv.rb test abc 1 2 3, you’ll get this:

["test", "abc", "1", "2", "3"]

It’s an array with all the options!

You can check if a specific option has been passed by implementing an option parser.

Here’s an example:

def process_argv(option)
  case option
  when "-h"
    puts "This is the help menu."
    puts "  -v Enable verbose mode"
    puts "  -c Enable syntax highlighting"
    exit
  when "-v"
    @options[:verbose] = true
  when "-c"
    @options[:syntax_highlighting] = true
  end
end

@options = {}

ARGV.each { |option| process_argv(option) }

p @options

If you run it like this:

ruby argv.rb -v -c

You’ll see:

{:verbose=>true, :syntax_highlighting=>true}

This works for simple things, but if you want to write a bigger application you may want to consider other solutions.

How to Use The Option Parser Library

Ruby comes with the OptionParser class that you can use to parse command-line options.

Here is an example:

require 'optparse'

@options = {}

OptionParser.new do |opts|
  opts.on("-v", "--verbose", "Show extra information") do
    @options[:verbose] = true
  end

  opts.on("-c", "--color", "Enable syntax highlighting") do
    @options[:syntax_highlighting] = true
  end
end.parse!

p @options

You get several benefits when using optparse over your own custom solution.

For example:

  • You can have the short -v & the long version --verbose of every flag without extra work
  • Every option has a description, which will be part of the help menu
  • The help menu is automatically built for you, so you don’t have to manually update it every time you add or remove options

Here’s what the menu looks like:

Ruby Optparse

The best part?

All of this is built into Ruby so there is nothing to install!

How to Use The Thor Gem

If you are looking for a different approach to option parsing you should take a look at the Thor gem. This is what Rails uses.

In Rails you do things like:

  • rails new
  • rails generate
  • rails console

To (partially) recreate the rails command you can do something like this:

require 'thor'

class RailsCLI < Thor
  class_option :verbose, :type => :boolean, :aliases => "-v"

  desc "new DIRECTORY", "Create a new rails app"

  def new
    # ...
  end

  desc "generate THING PARAMETERS", "Generate controller / model / migration"

  def generate
    # ...
  end

  desc "console", "Start a rails console"

  def console
    # ...
  end
end

RailsCLI.start(ARGV)

The help menu looks like this:

Ruby Thor Help

This is a very different style compared to OptionParser

…and it may not be the best choice for your app if it does one thing with a few variable options.

But if you have a command like rails, which is used for many different tasks, then Thor is a great choice!

The Ruby Readline Library

Would you like to build an application with an interactive interface like pry or psql?

Check out the Readline module, which helps you do this.

Here is an example:

prompt = "> "

while buf = Readline.readline(prompt, true)
  puts "Your input was: '#{buf}'"
end

This will give you a prompt, and echo back whatever you write after you press enter.

You can end the program by pressing CTRL+C.

Readline will keep a history of everything you type, and it will allow you to search your history using ctrl+r, or Readline::HISTORY.to_a inside your code.

With Readline you can also implement things like auto-completion, have a look at this link for an example.

Watch Video Tutorial

Conclusion

Even if you are a GUI kind of person, command-line applications can be very powerful and fun to build.

Give it a try & start building your own today 😃

3 thoughts on “How to Build Command-Line Applications (CLI) with Ruby”

  1. Is there any method or library to write something not to display or put autocompletion but use keyboard to select an option in a list ? Imagine do ls -ali on a folder, get a cursor and select one pressing “Enter”. Readline can do completion and access but is there another thing to manipulate keys ?

Comments are closed.