A CLI application is gem package. We have multiple ways to craft a gem package, directly using gem or creating by Bundler.
The majority of people select using the Bundler to build a gem package because it can easily manage dependencies and has a scaffold to create the gemspec, license, test, tec. files for our automatically.
Creating a gem project by Bundler
1. Installing Bundler
1 2
gem install bundler bundle -v # check version
If necessary, you can update to the latest version of Bundler.
1
gem update bundler
2. Generating a gem project
1
bundle gem wand # app name
3. Writing unit tests [optional]
Installing rspec
We use rspec to test our project. It’s a development dependency, so we add this line inside the Gem::Specification in the file wand.gemspec.
1
spec.add_development_dependency "rspec", "~> 3.2"
Creating the test directory
Running bundle install to install all gem dependencies.
Creating a spec folder in the project directory as our test directory.
Writing a wand_spec.rb file in the spec directory.
Look up the documentation of spec to write unit tests.
1 2 3 4 5
describe Wand::Echodo it "echo messages"do expect(Wand::Echo.echo("Hello")).to eql("Hello") end end
Creating a Ruby class
Defining a class in lib/wand/echo like this:
1 2 3 4 5 6 7
moduleWand classEcho defself.echo(msg) puts msg end end end
To load this file, we’ll need to add a require line to lib/wand.rb for it:
1
require'wand/echo'
We will also need to require the lib/wand.rb at the top of spec/wand_spec.rb:
1
require`wand`
Then, we run bundle exec rspec spec to test our codes.
4. Crafting a CLI
There are many gems can help us to craft a CLI. We select the Thor to cover this.
Install Thor
Adding the dependency to our gemspec file.
1
spec.add_dependency "thor"
Running bundle install to install the dependencies.
Writing our first CLI
First, we need to create a cli file in lib/wand/cli.rb.
Creating a CLI class into the file like this:
1 2 3 4 5 6 7 8 9 10 11
require`thor` require`wand`
moduleWand classCLI < Thor desc "echo message", "prints whatever you inputted" defecho(msg) Wand::Echo.echo(msg) end end end
Test our CLI code
The easiest approach to test our code directly is to create a cli.rb file in our project directory and run ruby ./cli.rb to test it.
The content of the cli.rb file:
1 2 3
require`wand/cli`
Wand::CLI.start
If you run bundle exec ruby cli.rb echo Hello, the terminal will output the text Hello equaling to your input.
5. Testing a CLI
The test way above is just for our development convenience, not unit tests. We need a tool to execute unit tests for our CLI. The prevalent tools for CLI unit test are cucumber and aruba.
Creating a features folder and a file features/wand.feature in it
Filling the file with this code:
1 2 3 4 5 6
Feature: Wand Doing something Scenario: Echo message When I run `wand echo hello` Then the output should contain "hello"
Setting up the cucumber
You need to create a setup file features/support/setup.rb and fill it with this code:
1
require`aruba/cucumber`
Creating the executable file for unit tests.
Creating a file exe/wand without any file extension.
Running chmod +x exe/wand to give the file executable permission.
Copying our cli.rb file’s code to the executable file. The file’s content:
1 2 3
require`wand/cli`
Wand::CLI.start
Executing bundle exec cucumber features to run CLI unit tests.
6. Releasing our CLI
Committing our code
First, we need to commit our code because the wand.gemspec file uses git ls-files to detect which files should be added to the gem when we release it.
1 2
git add . git commit -m 'Initializing wand'
Building gem files
Before releasing our gem, we need to compile our code to a gem file.
1
rake build
The command finished and then you will find a wand-0.1.0.gem file was generated in the pkg folder.
We can run gem install pkg/wand-0.1.0.gem to install the gem directly. Then you can run wand echo hello in the terminal to use your first CLI.
Releasing to gems
If you want to share you CLI to others, you need to publish it to the http://rubygems.org. Next time you want to use your CLI in other devices, you can use gem install wand install it directly.
Using rake to release a gem is easy.
1
rake release
Simplifying your releasing process
Every time you want to update your CLI, you need to update the VERSION in the file version.rb, commit the modification and then run rake release again.
There is a tool gem-release can easily your work.
1
gem install gem-release
The common usages of the gem-release
1 2 3
$ gem bump --version minor # bumps to the next minor version $ gem bump --version major # bumps to the next major version $ gem bump --version 1.1.1 # bumps to the specified version
Installing a gem from github directly
Sometimes we don’t want releasing a public gem. Maybe the gem contains some personal privacy or the company’s code we cannot leak.
The gem provides an approach to install a gem from our private git repository.
We can specify the branch or use the default branch. If your repository’s root directory doesn’t have the .gemspec file, you need to specify the file’s path via the glob argument.