Command Line Interface for Crystal
A simple Command line interface builder which aims to be easy to use.
Add the dependency to your shard.yml
:
dependencies:
clicr:
github: j8r/clicr
This library uses generics, thanks to Crystal's powerful type-inference, and few macros, to provide this following advantages:
- Compile time validation - methods must accept all possible options and arguments
- No possible double commands/options at compile-time
- Declarative
NamedTuple
configuration - Customizable configuration - supports all languages (See Clicr.new parameters)
- Fast execution, limited runtime
require "clicr"
Clicr.new(
label: "This is my app.",
commands: {
talk: {
label: "Talk",
action: {"CLI.say": "t"},
arguments: %w(directory),
options: {
name: {
label: "Your name",
default: "foo",
},
no_confirm: {
short: 'y',
label: "Print the name",
},
},
},
},
).run
module CLI
def self.say(arguments, name, no_confirm)
puts arguments, name, no_confirm
end
end
Example of commands:
$ myapp --help
Usage: myapp COMMANDS [OPTIONS]
Myapp can do everything
COMMANDS
t, talk Talk
OPTIONS
--name=foo Your name
-y, --no-confirm Print the name
'myapp --help' to show the help.
$ myapp talk /tmp name=bar
no, bar in /tmp
$ myapp talk home name=bar -y
yes, bar in home
$ myapp talk test
no, foo in test
See the one in the spec test
It's also possible to merge several commands or options together.
other = {
pp: {
label: "It pp",
action: "pp"
}
}
Clicr.new(
label: "Test app",
commands: {
puts: {
alias: 'p',
label: "It puts",
action: "puts",
}.merge(other)
}
)
Help output:
Usage: myapp COMMAND
Test app
COMMAND
p, puts It puts
pp It pp
'myapp --help' to show the help.
Example: s
, start
commands: {
short: {
action: { "say": "s" },
label: "Starts the server",
description: <<-E.to_s,
This is a full multi-line description
explaining the command
E,
}
}
action
is aNamedTuple
with as key the method to call, and as a value a command alia, which can be empty for none.- in
action
, parentheses can be added to determine the arguments placement, likeFile.new().file
label
is supposed to be short, one-line descriptiondescription
can be a multi-line description of the command. If not set,label
will be used.
Example: command FooBar
, command mysource mytarget
arguments: %w(directory names)
arguments: {"source", "target"}
- if a
Tuple
is given, the arguments number must be exactly theTuple
size. - if an
Array
is given, the arguments number must be at least, or more, theArray
size
Example: -y
, --no-confirm
options: {
no_confirm: {
short: 'y',
label: "No confirmations",
}
}
short
creates a short alias of one character - must be aChar
- concatenating single characters arguments like
-Ry1
is possible - dashes
-
, being invalid named arguments, will be replaced by_
when calling the action method.
Special case: the help_option
, which is set to "help"
with the options -h, --help
by default,
shows the help of the current (sub)command
Example: --name=foo
, or --name foo
options: {
name: {
label: "This is your name",
default: "Foobar",
}
}
- an optional
default
value can be set. - if a
default
is not set, atype
can be defined to cast from a given type, instead of a rawString
. For example,type: Int32
will callInt32.new
. - can only be
String
(because arguments passed asARGV
areArray(String)
) - if others type are needed, the cast must be done after theaction
method call
Copyright (c) 2020 Julien Reichardt - ISC License