cli~amberframework
Crystal CLI
Yet another library for building command-line interface applications written in Crystal.
Installation
Add this to your application's shard.yml
:
dependencies:
cli:
github: mosop/cli
Features
Option Parser (Integrated with optarg)
class Command < Cli::Command
class Options
string "--hello"
end
def run
puts "Hello, #{options.hello}!"
end
end
Command.run %w(--hello world) # prints "Hello, world!"
Argument Access
class Command < Cli::Command
class Options
string "--option"
end
def run
puts "#{options.option} #{args[0]} #{unparsed_args[0]}"
end
end
Command.run %w(--option foo bar -- baz) # prints "foo bar baz"
With Handler
class Command < Cli::Command
class Options
on("--go") { command.go(with: "the Wind") }
end
def go(with some)
puts "Gone with #{some}"
exit
end
end
Command.run %w(--go) # prints "Gone with the Wind"
Subcommand
class Polygon < Cli::Supercommand
command "triangle", default: true
command "square"
command "hexagon"
module Commands
class Triangle < Cli::Command
def run
puts 3
end
end
class Square < Cli::Command
def run
puts 4
end
end
class Hexagon < Cli::Command
def run
puts 6
end
end
end
end
Polygon.run %w(triangle) # prints "3"
Polygon.run %w(square) # prints "4"
Polygon.run %w(hexagon) # prints "6"
Polygon.run %w() # prints "3"
Inheritance
class Role < Cli::Command
class Options
string "--name"
end
end
class Chase < Cli::Supercommand
command "mouse"
command "cat"
module Commands
class Mouse < Role
def run
puts "#{options.name} runs away."
end
end
class Cat < Role
def run
puts "#{options.name} runs into a wall."
end
end
end
end
Chase.run %w(mouse --name Jerry) # prints "Jerry runs away."
Chase.run %w(cat --name Tom) # prints "Tom runs into a wall."
Help
class Say < Cli::Command
class Help
title "#{global_name} [OPTIONS]"
header "Says something to someone."
footer "(C) 20XX mosop"
end
class Options
string "--to", var: "WHO", desc: "set someone who you say to", default: "world"
bool "--hello", not: "--Hello", desc: "say hello", default: true
on("--help", desc: "show this help") { command.help! }
end
end
Say.run %w(--help)
# say [OPTIONS]
#
# Says something to someone.
#
# Options:
# --hello say hello
# (enabled as default)
# --Hello disable --hello
# --to WHO set someone who you say to
# (default: world)
# --help show this help
#
# (C) 20XX mosop
Help for Subcommands
class Package < Cli::Supercommand
command "install", default: true
command "update"
command "remove"
class Help
title "#{global_name} [SUBCOMMAND] | [OPTIONS]"
end
class Options
on("--help", desc: "shows this help") { command.help! }
end
class Base < Cli::Command
class Help
title { "#{global_name} [OPTIONS] PACKAGE_NAME" }
end
class Options
on("--help", desc: "shows this help") { command.help! }
end
end
module Commands
class Install < Base
class Options
string "-v", var: "VERSION", desc: "specify package's version"
end
class Help
caption "install package"
end
end
class Update < Base
class Help
caption "update package"
end
class Options
bool "--break", desc: "update to breaking version if any"
end
end
class Remove < Base
class Help
caption "remove package"
end
class Options
bool "-f", desc: "force to remove"
end
end
end
end
Package.run %w(--help)
# package [SUBCOMMAND] | [OPTIONS]
#
# Subcommands:
# install (default) install package
# remove remove package
# update update package
#
# Options:
# --help show this help
Package.run %w(install --help)
# package install [OPTIONS] PACKAGE_NAME
#
# Options:
# -v VERSION specify package's version
# --help show this help
end
Package.run %w(update --help)
# package update [OPTIONS] PACKAGE_NAME
#
# Options:
# --major update major version if any
# --help show this help
end
Package.run %w(remove --help)
# package remove [OPTIONS] PACKAGE_NAME
#
# Options:
# -f force to remove
# --help show this help
Usage
require "cli"
and see Features.
API Basics
Crystal CLI provides 4 fundamental classes, Command
, Supercommand
, Options
and Help
.
Both Command
and Supercommand
inherit the CommandBase
class that has several features commonly used.
Once you make a class inherit Command
or Supercommand
, then Options
and Help
is automatically defined into the class.
class AncientCommand < Cli::Command
end
This code seems that it simply defines the AncientCommand
class. But, actually, it also makes AncientCommand::Options
and AncientCommand::Help
defined internally.
Parsing Options
The Options
class is used for parsing command-line options. Options
inherits the Optarg::Model
class provided from the optarg library. So you can define options in it.
class AncientCommand < Cli::Command
class Options
string "--message"
end
end
Running a Command
The virtual CommandBase#run
method is the entry point for running your command.
Your command's class will be instantiated and its #run
method will be invoked after calling the static .run
method.
The following code prints a single lovely message.
class AncientCommand < Cli::Command
def run
puts "We the Earth"
end
end
AncientCommand.run
The command's instance is also accessible with the command
method in option parser's scopes.
class AncientCommand < Cli::Command
class Options
on("--understand") { command.understand }
end
def understand
puts "We know"
end
def run
puts "We the Earth"
end
end
AncientCommand.run(%w(--understand))
# prints as:
# We know
# We the Earth
Formatting Help
The Help
class is used for formatting help texts.
class AncientCommand < Cli::Command
class Help
title "ancient [OPTIONS]"
footer "(C) 1977 mosop"
end
end
[WIP]
Development
[WIP]
Contributing
- Fork it ( https://github.com/mosop/cli/fork )
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create a new Pull Request
Contributors
- mosop - creator, maintainer