CLI Ruby Gem Basic Setup

By February 9, 2019 Tutorial

This week I wrote a Ruby Gem called stock_info and published it on Rubygems.org. The gem pulls information on stocks from finviz.com. This post will describe the basic steps to set up a gem project so you can create a CLI gem like mine.

Start by initializing the gem structure with bundler. If you don’t have bundler installed you can install it with:

“gem install bundler”

The bundle command to create the gem is:

“bundle gem [gem_name]”

Be careful when using this command to use underscores in the gem name, not hyphens, as bundler will create a separate nested folder for each hyphen in the name. Once the file structure has been created, you must create an executable. The executable file should be named t The executable file must first inform the interpreter to use Ruby to read the code. You can achieve this with the line:

“!#~/usr/bin/env ruby”

Now we need to create an executable file. Create the file in the bin directory of your project folder. You should name your file the same command that you will use to run it. In my case, “stock_info”, the file should not have any file extension. Your executable should “require” a file that will further the rest of our files, it then calls the “call” method on a new instance of the CLI class, which should be namespaced within my main gem module named “StockInfo”. This module has already been created by our bundle gem command. At this point your executable file should look something like this:

#!/usr/bin/env ruby

require_relative “../lib/stock_info”

[YourGemName]::CLI.new.call

Now we can start writing some code in our /lib directory. We haven’t added anything to our stock_info.rb file yet, but we are doing something called “writing the code we wish we had”. This essentially means we are setting things up in preparation for our final code. Now that we have our executable set up let’s open our [gem_name].rb file. This file must require all of our lib files and other gem dependencies. In the case of my gem they are:

require_relative ‘./stock_info/version’
require_relative ‘./stock_info/cli’
require_relative ‘./stock_info/stock’
require_relative ‘./stock_info/news’
require ‘nokogiri’
require ‘pry’
require ‘open-uri’
Although this code seems to contain our module definition, our gem module is also defined in ./[gem_name]/version.rb, so we can delete the module from this file. Next, we want to create a new file in the [gem_name] folder called cli.rb, which will contain the code for our CLI. In order to fulfill the promise we made in our executable file we need to define a class here and give it a call method which will start our program like so:
class [GemName]::CLI
    def call
    end
end
Now we have everything all set up to start coding! But wait! There’s one more step to make sure everything will run smoothly once we try to package our gem into a pretty ‘.gem’ file that others can install from rubygems.org. We have to open our [gem_name}.gempec and set some variables so that bundler knows how to put our gem together. First, we need to tell it where our executable file is. Currently our gemspec is looking for ‘.exe’ files, so we need to change the ‘spec.bindir’, and ‘spec.executable’ values so bundler knows where to look. The bindir should be set to ‘bin’ and executables should ‘shovel’ (<<) in ‘gem_name’.  Next we’re going to need to tell it what dependencies we’re using that aren’t part of the standard ruby library. In our case, this is just ‘nokogiri’. We should also add a ‘development dependency’ so we can use ‘pry’ to test our code. The end of our specfile should now look something like this:
spec.bindir = ‘bin’
spec.executables << ‘stock_info’
spec.require_paths = [‘lib’]
spec.add_development_dependency ‘pry’, ‘~> 0.12’
spec.add_dependency ‘nokogiri’, ‘~> 1.10’
We’re also going to want to change anything that says TO-DO in this file so that gem has proper meta information about it and its awesome author. This is really just the beginning! Now that our framework is in place we are ready to build an awesome gem!

Leave a Reply