The command_line_boss gem

Gem Version
Documentation
Change Log
Build Status
Conventional<br>
Commits"></a><br>
<a href=Slack

command_line_boss makes it easy to build, test, and maintain complex command line
interfaces. It is built on top of Ruby’s OptionParser class and works best for
traditional options-based command-line interfaces that you would build with
OptionParser.

To use command_line_boss you are expected to already know how to define options
with OptionParser.

For defining command-line interfaces with multiple commands and subcommands (aka a
git-like interface), we recommend using a gem like thor.
Other good alternatives also exist.

Installation

To install this gem, add to the following line to your application’s gemspec OR
Gemfile:

gemspec:

  spec.add_development_dependency "command_line_boss", '~&gt; 0.1'

Gemfile:

gem "command_line_boss", "~&gt; 0.1", groups: [:development, :test]

and then run bundle install.

If bundler is not being used to manage dependencies, install the gem by executing:

gem install command_line_boss

Usage

More detailed examples are given in the examples directory.

  • examples/readme_example - a super-simple example of using this gem. The remainder of this section is a walkthrough of this example was constructed.
  • examples/create_spreadsheet - a more complicated example complete with tests.

This section provides a step-by-step guide to building a super simple command line
using this gem. A parser this simple would probably be easier to implement with
OptionParser directly without this gem. This example is meant to show how you
can get started.

This gem really starts to shine as your command-line interface grows beyond
something this simple.

Getting started

The end result of this guide can be found in this project in the file
examples/readme_example/create-spreadsheet.

Find a suitable directory to create your code in. For this example, all the code
will live in ONE script file that you create and set its executable permission bit
via chmod.

Make sure you have the command_line_boss gem installed.

Design your command line

Design the command line following the Google developer documentation style guide for
command line syntax
.

Here is what a simple example might look like that creates a spreadsheet with named
sheets:

Usage:
create_spreadsheet SPREADSHEET_NAME --sheet=SHEET_NAME [--sheet=SHEET_NAME ...]

Start your command line parser class

The first step will be to create your own command line parsing class. This class
must inherit from CommandLineBoss.

Add the attributess representing the items you want to capture from the command
line. Set default values for these attributes in a method called set_defaults.

#!/usr/bin/env ruby

require 'command_line_boss'

class CreateSpreadsheetCli &lt; CommandLineBoss
  attr_reader :spreadsheet_name, :sheet_names

  private

  def set_defaults
      @spreadsheet_name = nil
      @sheet_names = []
  end
end

Define options

Define private methods whose names follow the pattern define_*_option. Methods
MUST be private or they won’t be called.

Report any errors by calling add_error_message with the text of the error
message.

The return value of these methods is ignored.

Continuing the example, add the following code to the CreateSpreadsheetCli class:

class CreateSpreadsheetCli &lt; CommandLineBoss
  # ...

  private

  def define_sheet_option
    parser.on('--sheet=SHEET_NAME', 'Name of a sheet to create') do |name|
      add_error_message('Sheet names must be unique!') if sheet_names.include?(name)
      sheet_names &lt;&lt; name
    end
  end
end

Define additional validations

Define private methods whose names follow the pattern validate_*. Methods MUST
be private or they won’t be called.

Report any errors by calling add_error_message with the text of the error
message.

The return value of these methods is ignored.

Continuing the example, add the following code to the CreateSpreadsheetCli class:

class CreateSpreadsheetCli &lt; CommandLineBoss
  # ...

  private

  def validate_spreadsheet_name_given
    add_error_message('A spreadsheet name is required') if spreadsheet_name.nil?
  end

  def validate_at_least_one_sheet_name_given
    add_error_message('At least one sheet name is required') if sheet_names.empty?
  end
end

Process any remaining non-option arguments

Implement parse_arguments to deal the remaining non-option arguments from the
command line. Within this method, the args method returns the remaining
non-option arguments.

For example, in the command line create-spreadsheet "Yearly Sales" --sheet Summary,
args would return an array ['Yearly Sales'].

Remove any values from args that will be used. By default, if args is not
empty after parse_arguments returns, an error will result.

Report any errors by calling add_error_message with the text of the error
message.

The return value of this method is ignored.

Continuing the example, add the following code to the CreateSpreadsheetCli class:

class CreateSpreadsheetCli &lt; CommandLineBoss
  # ...

  private

  def parse_arguments
    @spreadsheet_name = args.shift
  end
end

Optional: define help output

Include the CommandLineBoss::HelpOption module add a help option (-h and
--help) and structure the help output.

Help output is divided into sections that is output as follows:

BANNER
HEADER
OPTIONS
FOOTER

The OPTIONS section is generated by OptionsParser.

You may provide the content for the other sections by implementing any or all of the
methods: banner, header, and footer. These methods are expected to return a
string with the content.

If you do not provide content for the banner section, it is generated by
OptionsParser. The default banner looks something like this:

Usage: create-spreadsheet [options]

If you do not provide content for the header or footer sections, they are
omitted from the help output.

Continuing the example, add the following code to the CreateSpreadsheetCli class:

class CreateSpreadsheetCli &lt; CommandLineBoss
  include CommandLineBoss::HelpOption

  # ...

  private

  include CommandLineBoss::HelpOption

  def banner = &lt;&lt;~BANNER
    Create a spreadsheet

    Usage:
      create_spreadsheet SPREADSHEET_NAME --sheet=SHEET_NAME [--sheet=SHEET_NAME ...]

  BANNER
end

The CreateSpreadsheetCli class is complete!

Use the parser

Now that the command line parser is fully defined, you just need to use it,
report errors, and (if successful) do something with the parsed values.

Place the following code at the end of your script file, after the
CreateSpreadsheetCli class:

# Parse the command line arguments

options = CreateSpreadsheetCli.new.parse(ARGV)

# Report errors

if options.failed?
  warn options.error_messages.join("\n")
  exit 1
end

# Do something with the result
# In this case just output the command line values

require 'pp'

puts \
  "Creating spreadsheet #{options.spreadsheet_name.pretty_inspect.chomp} " \
  "with sheets #{options.sheet_names.map(&amp;:pretty_inspect).map(&amp;:chomp).join(', ')}"

Run the command line

Should you have a problem running your script, you can compare your script against
the expected result which can be found in this project in the file
examples/readme_example/create-spreadsheet.

Test your script by running it from the command line. Here are some examples:

Show help output:

$ ./create-spreadsheet --help
Create a spreadsheetasdf

Usage:
  create_spreadsheet SPREADSHEET_NAME --sheet=SHEET_NAME [--sheet=SHEET_NAME ...]

Options:
        --sheet=SHEET_NAME           Name of a sheet to create
    -h, --help                       Show this message

$

A happy-path example:

$ ./create-spreadsheet 'Yearly Sales' --sheet=Summary --sheet=Details
Creating spreadsheet "Yearly Sales" with sheets "Summary", "Details"
$

An example with errors:

$ ./create-spreadsheet
ERROR: A spreadsheet name is required
ERROR: At least one sheet name is required
$

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake
spec
to run the tests. You can also run bin/console for an interactive prompt that
will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install.

Contributing

Bug reports and pull requests are welcome on GitHub at
https://github.com/main_branch/command_line_boss. This project is intended to be a
safe, welcoming space for collaboration, and contributors are expected to adhere to
the code of
conduct
.

Commit message guidelines

All commit messages must follow the Conventional Commits
standard
. This helps us maintain a
clear and structured commit history, automate versioning, and generate changelogs
effectively.

To ensure compliance, this project includes:

  • A git commit-msg hook that validates your commit messages before they are accepted.

To activate the hook, you must have node installed and run npm install.

  • A GitHub Actions workflow that will enforce the Conventional Commit standard as part of the continuous integration pipeline.

Any commit message that does not conform to the Conventional Commits standard will
cause the workflow to fail and not allow the PR to be merged.

Pull request guidelines

All pull requests must be merged using rebase merges. This ensures that commit
messages from the feature branch are preserved in the release branch, keeping the
history clean and meaningful.

License

The gem is available as open source under the terms of the MIT
License
.

Code of Conduct

Everyone interacting in the CommandLineBoss project’s codebases, issue trackers, chat
rooms and mailing lists is expected to follow the code of
conduct
.