CLI
Command Line Interface gem allows you to quickly specify command argument parser that will automatically handle usage rendering, casting, default values and other stuff for you.
CLI supports following specifiers:
- switch - (
--verbose
or-v
) binary operators, by default set to nil, when specified set to true - option - (
--name John
or-n John
) switches that take value; default value can be specified, otherwise defaults to nil - options - (
-n John -n Frank
) like option but can be used multiple times on command line; default value or array of values can be given, otherwise defaults to empty array - argument - (
John
) capture single command; default value can be specified; raises error if not given - arguments - (
John Frank
) capture multiple command arguments; defaults to empty array - stdin - if standard input is to be handled it can be mentioned in usage output; also stdin data casting is supported
Each element can have description that will be visible in the usage output.
See examples and specs for more info.
Installing
gem install cli
Usage
Sinatra server example
require 'cli'
require 'ip'
= CLI.new do
description 'Example CLI usage for Sinatra server application'
version "1.0.0"
switch :no_bind, :description => "Do not bind to TCP socket - useful with -s fastcgi option"
switch :no_logging, :description => "Disable logging"
switch :debug, :description => "Enable debugging"
switch :no_optimization, :description => "Disable size hinting and related optimization (loading, prescaling)"
option :bind, :short => :b, :default => '127.0.0.1', :cast => IP, :description => "HTTP server bind address - use 0.0.0.0 to bind to all interfaces"
option :port, :short => :p, :default => 3100, :cast => Integer, :description => "HTTP server TCP port"
option :server, :short => :s, :default => 'mongrel', :description => "Rack server handler like thin, mongrel, webrick, fastcgi etc."
option :limit_memory, :default => 128*1024**2, :cast => Integer, :description => "Image cache heap memory size limit in bytes"
option :limit_map, :default => 256*1024**2, :cast => Integer, :description => "Image cache memory mapped file size limit in bytes - used when heap memory limit is used up"
option :limit_disk, :default => 0, :cast => Integer, :description => "Image cache temporary file size limit in bytes - used when memory mapped file limit is used up"
end.parse!
# use to set sinatra settings
require 'sinatra/base'
sinatra = Sinatra.new
sinatra.set :environment, 'production'
sinatra.set :server, .server
sinatra.set :lock, true
sinatra.set :boundary, "thumnail image data"
sinatra.set :logging, (not .no_logging)
sinatra.set :debug, .debug
sinatra.set :optimization, (not .no_optimization)
sinatra.set :limit_memory, .limit_memory
sinatra.set :limit_map, .limit_map
sinatra.set :limit_disk, .limit_disk
# set up your application
sinatra.run!
To see help message use --help
or -h
anywhere on the command line:
examples/sinatra --help
Example help message:
Usage: sinatra [switches|options]
Example CLI usage for Sinatra server application
Switches:
--no-bind - Do not bind to TCP socket - useful with -s fastcgi option
--no-logging - Disable logging
--debug - Enable debugging
--no-optimization - Disable size hinting and related optimization (loading, prescaling)
--help (-h) - display this help message
--version - display version string
Options:
--bind (-b) [127.0.0.1] - HTTP server bind address - use 0.0.0.0 to bind to all interfaces
--port (-p) [3100] - HTTP server TCP port
--server (-s) [mongrel] - Rack server handler like thin, mongrel, webrick, fastcgi etc.
--limit-memory [134217728] - Image cache heap memory size limit in bytes
--limit-map [268435456] - Image cache memory mapped file size limit in bytes - used when heap memory limit is used up
--limit-disk [0] - Image cache temporary file size limit in bytes - used when memory mapped file limit is used up
To see version string use --version
examples/sinatra --version
Example version output:
sinatra version "0.0.4"
Statistic data processor example
require 'cli'
require 'pathname'
require 'yaml'
= CLI.new do
description 'Generate blog posts in given Jekyll directory from input statistics'
stdin :log_data, :cast => YAML, :description => 'statistic data in YAML format'
option :location, :short => :l, :description => 'location name (ex. Dublin, Singapore, Califorina)'
option :csv_dir, :short => :c, :cast => Pathname, :default => 'csv', :description => 'directory name where CSV file will be storred (relative to jekyll-dir)'
argument :jekyll_dir, :cast => Pathname, :default => '/var/lib/vhs/jekyll', :description => 'directory where site source is located'
end.parse! do ||
fail 'jekyll-dir is not a directory' unless .jekyll_dir.directory?
fail '--csv-dir is not a directory (relative to jekyll-dir)' unless (.jekyll_dir + .csv_dir).directory?
end
p
# do your stuff
Example help message:
Usage: processor [switches|options] [--] jekyll-dir < log-data
Generate blog posts in given Jekyll directory from input statistics
Input:
log-data - statistic data in YAML format
Switches:
--help (-h) - display this help message
Options:
--location (-l) - location name (ex. Dublin, Singapore, Califorina)
--csv-dir (-c) [csv] - directory name where CSV file will be storred (relative to jekyll-dir)
Arguments:
jekyll-dir - directory where site source is located
With this example usage (assuming /var/lib/vhs/jekyll/csv dir exist):
examples/processor --location Singapore <<EOF
:parser:
:successes: 41
:failures: 0
EOF
The options
variable will contain:
#<CLI::Values stdin={:parser=>{:successes=>41, :failures=>0}}, jekyll_dir=#<Pathname:/var/lib/vhs/jekyll>, csv_dir=#<Pathname:csv>, help=nil, location="Singapore">
Output if jekyll-dir does not exist:
Error: jekyll-dir is not a directory
Usage: processor [switches|options] [--] jekyll-dir < log-data
Generate blog posts in given Jekyll directory from input statistics
Input:
log-data - statistic data in YAML format
Switches:
--help (-h) - display this help message
Options:
--location (-l) - location name (ex. Dublin, Singapore, Califorina)
--csv-dir (-c) [csv] - directory name where CSV file will be storred (relative to jekyll-dir)
Arguments:
jekyll-dir [/var/lib/vhs/jekyll] - directory where site source is located
Ls like utility
arguments
specifier can be used to match multiple arguments.
The arguments
specifier matched value will always be an array of casted elements.
Default and mandatory arguments will have priority on matching values (see specs for examples).
options
specifier can be used to allow specifing same option multiple times.
The options
specifier matched value will always be an array of casted elements or empty if option not specified.
require 'cli'
require 'pathname'
values = CLI.new do
description 'Lists content of directories'
switch :long, :short => :l, :description => 'use long listing'
:exclude, :short => :e, :description => 'exclude files from listing'
arguments :directories, :cast => Pathname, :default => '.', :description => 'directories to list content of'
end.parse!
values.directories.each do |dir|
next unless dir.directory?
dir.each_entry do |e|
next if e.to_s == '.' or e.to_s == '..'
e = dir + e
next if values.exclude.include? e.to_s
if values.long
puts "#{e.stat.uid}:#{e.stat.gid} #{e}"
else
puts e
end
end
end
Example help message:
Usage: ls [switches|options] [--] directories*
Lists content of directories
Switches:
--long (-l) - use long listing
--help (-h) - display this help message
Options:
--exclude* (-e) - exclude files from listing
Arguments:
directories* [.] - directories to list content of
Example usage:
examples/ls
Prints:
.document
.git
.gitignore
.README.md.swp
.rspec
cli.gemspec
examples
features
...
Excluding .git and .gitignore:
examples/ls -e .git -e .gitignore
Prints:
.document
.README.md.swp
.rspec
cli.gemspec
examples
features
...
With directory list:
examples/ls *
Prints:
examples/.ls.swp
examples/ls
examples/processor
examples/sinatra
features/cli.feature
features/step_definitions
features/support
lib/cli
lib/cli.rb
pkg/cli-0.0.1.gem
pkg/cli-0.0.2.gem
...
Long printout:
examples/ls -l *
Prints:
501:20 examples/.ls.swp
501:20 examples/ls
501:20 examples/processor
501:20 examples/sinatra
501:20 features/cli.feature
501:20 features/step_definitions
501:20 features/support
501:20 lib/cli
501:20 lib/cli.rb
501:20 pkg/cli-0.0.1.gem
501:20 pkg/cli-0.0.2.gem
...
Contributing to CLI
- Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
- Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
- Fork the project
- Start a feature/bugfix branch
- Commit and push until you are happy with your contribution
- Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
- Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright
Copyright (c) 2011 Jakub Pastuszek. See LICENSE.txt for further details.