cliqr 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +128 -1
- data/README.md +97 -71
- data/examples/README.md +12 -0
- data/examples/hbase +58 -0
- data/examples/my-command +63 -0
- data/examples/numbers +55 -0
- data/examples/vagrant +90 -0
- data/lib/cliqr.rb +17 -2
- data/lib/cliqr/argument_validation/argument_type_validator.rb +2 -2
- data/lib/cliqr/argument_validation/validator.rb +1 -1
- data/lib/cliqr/cli/argument_operator.rb +44 -0
- data/lib/cliqr/cli/argument_operator_context.rb +20 -0
- data/lib/cliqr/cli/command.rb +1 -1
- data/lib/cliqr/cli/command_context.rb +93 -12
- data/lib/cliqr/cli/command_runner_factory.rb +2 -2
- data/lib/cliqr/cli/config.rb +301 -33
- data/lib/cliqr/cli/executor.rb +14 -9
- data/lib/cliqr/cli/interface.rb +22 -7
- data/lib/cliqr/cli/router.rb +6 -2
- data/lib/cliqr/cli/shell_command.rb +69 -0
- data/lib/cliqr/cli/usage_builder.rb +185 -0
- data/lib/cliqr/config_validation/validator_factory.rb +59 -5
- data/lib/cliqr/error.rb +10 -4
- data/lib/cliqr/parser/action_token.rb +23 -0
- data/lib/cliqr/parser/argument_parser.rb +1 -1
- data/lib/cliqr/parser/argument_token.rb +1 -4
- data/lib/cliqr/parser/argument_tree_walker.rb +40 -8
- data/lib/cliqr/parser/option_token.rb +2 -1
- data/lib/cliqr/parser/parsed_input.rb +21 -2
- data/lib/cliqr/parser/parsed_input_builder.rb +11 -7
- data/lib/cliqr/parser/token.rb +3 -9
- data/lib/cliqr/parser/token_factory.rb +1 -1
- data/lib/cliqr/util.rb +135 -0
- data/lib/cliqr/version.rb +1 -1
- data/spec/argument_parser_spec_helper.rb +15 -0
- data/spec/config/action_config_validator_spec.rb +146 -0
- data/spec/config/config_finalize_spec.rb +1 -1
- data/spec/config/config_validator_spec.rb +29 -19
- data/spec/config/option_config_validator_spec.rb +13 -13
- data/spec/dsl/interface_spec.rb +1 -168
- data/spec/dsl/usage_spec.rb +705 -0
- data/spec/executor/action_executor_spec.rb +205 -0
- data/spec/executor/executor_spec.rb +405 -17
- data/spec/executor/help_executor_spec.rb +424 -0
- data/spec/executor/shell_executor_spec.rb +233 -0
- data/spec/fixtures/action_reader_command.rb +12 -0
- data/spec/fixtures/csv_argument_operator.rb +8 -0
- data/spec/fixtures/test_option_type_checker_command.rb +8 -0
- data/spec/parser/action_argument_parser_spec.rb +113 -0
- data/spec/parser/argument_parser_spec.rb +37 -44
- data/spec/spec_helper.rb +1 -0
- data/spec/validation/action_argument_validator_spec.rb +50 -0
- data/spec/validation/{argument_validation_spec.rb → command_argument_validation_spec.rb} +36 -18
- data/spec/validation/error_spec.rb +1 -1
- data/tasks/rdoc.rake +16 -0
- data/tasks/rubucop.rake +14 -0
- data/tasks/yard.rake +21 -0
- data/templates/usage.erb +39 -0
- metadata +48 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9250bde8a2cd431432f1d68618d748b5e6ea378f
|
4
|
+
data.tar.gz: 1d2f297559d079b1b1592c5863f3b2ccb4782037
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aff0bc4667372517b12b61a84c4c4236179ec1aa37157be2676a71861daf6c639182cb11f06a698eb6b76cb1796f0c1b5c8142a4fde63f50b3d2f39ce9cec180
|
7
|
+
data.tar.gz: 5eee04fc1abd977ae5ff3156b02c4d694b33b30b9ec793dff92edd2d2c5f70605e15316aa67c18e8b1bd3cf04f9d88b304f7e4c8be9ab35bce1564288da8fb12
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,30 @@ item in this nested table for further details.
|
|
5
5
|
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc/generate-toc again -->
|
6
6
|
**Table of Contents**
|
7
7
|
|
8
|
+
- [1.2.0 / 2015-06-18](#120--2015-06-18)
|
9
|
+
- [Features](#features)
|
10
|
+
- [Nested actions](#nested-actions)
|
11
|
+
- [Ability to operate on arguments](#ability-to-operate-on-arguments)
|
12
|
+
- [Anonymous Proc for command handling and argument operation](#anonymous-proc-for-command-handling-and-argument-operation)
|
13
|
+
- [Default value for options](#default-value-for-options)
|
14
|
+
- [Default command actions](#default-command-actions)
|
15
|
+
- [Help](#help)
|
16
|
+
- [Version](#version)
|
17
|
+
- [Shell](#shell)
|
18
|
+
- [Forward command from one handler to another](#forward-command-from-one-handler-to-another)
|
19
|
+
- [Improvements](#improvements)
|
20
|
+
- [Use name instead of basename](#use-name-instead-of-basename)
|
21
|
+
- [Reorganize tests](#reorganize-tests)
|
22
|
+
- [Can get value in operator by calling `value`](#can-get-value-in-operator-by-calling-value)
|
23
|
+
- [Run anonymous command handler in the the context of `CommandContext`](#run-anonymous-command-handler-in-the-the-context-of-commandcontext)
|
24
|
+
- [Call `help` action by default](#call-help-action-by-default)
|
25
|
+
- [Add Examples for using `Cliqr`](#add-examples-for-using-cliqr)
|
26
|
+
- [Update `README` to make it more relevant](#update-readme-to-make-it-more-relevant)
|
27
|
+
- [Bug-fixes](#bug-fixes)
|
28
|
+
- [Fix option parsing for option with symbolic name](#fix-option-parsing-for-option-with-symbolic-name)
|
29
|
+
- [Handle errors gracefully](#handle-errors-gracefully)
|
30
|
+
- [Include template in gem](#include-template-in-gem)
|
31
|
+
- [Fix shell in shell issue](#fix-shell-in-shell-issue)
|
8
32
|
- [1.1.0 / 2015-06-05](#110--2015-06-05)
|
9
33
|
- [Features](#features)
|
10
34
|
- [Support for arbitrary arguments in a command](#support-for-arbitrary-arguments-in-a-command)
|
@@ -67,6 +91,109 @@ item in this nested table for further details.
|
|
67
91
|
|
68
92
|
<!-- markdown-toc end -->
|
69
93
|
|
94
|
+
1.2.0 / 2015-06-18
|
95
|
+
==================
|
96
|
+
|
97
|
+
This is a pretty loaded release in terms of features, improvements and
|
98
|
+
bug-fixes. Here is a detailed list.
|
99
|
+
|
100
|
+
## Features
|
101
|
+
|
102
|
+
### Nested actions
|
103
|
+
|
104
|
+
Every command is a action and in this release, we add support for
|
105
|
+
building nested command structure.
|
106
|
+
|
107
|
+
For example:
|
108
|
+
|
109
|
+
``` bash
|
110
|
+
$ vagrant up --provision
|
111
|
+
```
|
112
|
+
|
113
|
+
This command has:
|
114
|
+
|
115
|
+
- Base-command: vagrant
|
116
|
+
- Sub action: up
|
117
|
+
- Option: provision
|
118
|
+
|
119
|
+
### Ability to operate on arguments
|
120
|
+
|
121
|
+
You can now specify a operator that can pre-process the option arguments
|
122
|
+
and, if needed, do validation as well.
|
123
|
+
|
124
|
+
### Anonymous Proc for command handling and argument operation
|
125
|
+
|
126
|
+
No need to define a separate class to handle a command or operate on
|
127
|
+
arguments.
|
128
|
+
|
129
|
+
### Default value for options
|
130
|
+
|
131
|
+
Options can now have a default value. In some cases this is derived from
|
132
|
+
option type attribute.
|
133
|
+
|
134
|
+
### Default command actions
|
135
|
+
|
136
|
+
Several default actions were added to a command.
|
137
|
+
|
138
|
+
#### Help
|
139
|
+
|
140
|
+
Help is added by default to every action. This includes a help action
|
141
|
+
and option.
|
142
|
+
|
143
|
+
#### Version
|
144
|
+
|
145
|
+
If specified, a version action and boolean option is added to the action.
|
146
|
+
|
147
|
+
#### Shell
|
148
|
+
|
149
|
+
Shell is enabled by default if there are any sub-actions for a command.
|
150
|
+
|
151
|
+
### Forward command from one handler to another
|
152
|
+
|
153
|
+
A new method `forward` can be called with arguments that are parsed and
|
154
|
+
executed again.
|
155
|
+
|
156
|
+
## Improvements
|
157
|
+
|
158
|
+
### Use name instead of basename
|
159
|
+
|
160
|
+
The only reason for this was to make things simple and consistent.
|
161
|
+
|
162
|
+
### Reorganize tests
|
163
|
+
|
164
|
+
Divide tests by functionality. In some cases group them together.
|
165
|
+
|
166
|
+
### Can get value in operator by calling `value`
|
167
|
+
|
168
|
+
### Run anonymous command handler in the the context of `CommandContext`
|
169
|
+
|
170
|
+
### Call `help` action by default
|
171
|
+
|
172
|
+
If you call a command without specifying any arguments, its help action
|
173
|
+
will be invoked (assuming it is enabled).
|
174
|
+
|
175
|
+
### Add Examples for using `Cliqr`
|
176
|
+
|
177
|
+
Examples for some popular commands like `vagrant` and `hbase` along with
|
178
|
+
some custom commands were added.
|
179
|
+
|
180
|
+
### Update `README` to make it more relevant
|
181
|
+
|
182
|
+
## Bug-fixes
|
183
|
+
|
184
|
+
### Fix option parsing for option with symbolic name
|
185
|
+
|
186
|
+
### Handle errors gracefully
|
187
|
+
|
188
|
+
Errors do not kill the running script anymore and they do not show stack
|
189
|
+
trace.
|
190
|
+
|
191
|
+
### Include template in gem
|
192
|
+
|
193
|
+
### Fix shell in shell issue
|
194
|
+
|
195
|
+
It should be not allowed to run a shell within another shell.
|
196
|
+
|
70
197
|
1.1.0 / 2015-06-05
|
71
198
|
==================
|
72
199
|
|
@@ -77,7 +204,7 @@ for arbitrary arguments.
|
|
77
204
|
|
78
205
|
### Support for arbitrary arguments in a command
|
79
206
|
|
80
|
-
For the first time you can invoke a command with
|
207
|
+
For the first time you can invoke a command with non-option arguments.
|
81
208
|
|
82
209
|
## Minor Improvements
|
83
210
|
|
data/README.md
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
# cliqr
|
1
|
+
# cliqr [](https://rubygems.org/gems/cliqr)
|
2
2
|
|
3
3
|
[](https://travis-ci.org/anshulverma/cliqr)
|
4
4
|
[](https://codeclimate.com/github/anshulverma/cliqr)
|
5
5
|
[](https://codeclimate.com/github/anshulverma/cliqr)
|
6
6
|
[](https://gemnasium.com/anshulverma/cliqr)
|
7
|
-
[](http://inch-ci.org/github/anshulverma/cliqr)
|
8
|
-
|
9
|
-
[](https://rubygems.org/gems/cliqr)
|
7
|
+
[](http://inch-ci.org/github/anshulverma/cliqr)
|
10
8
|
[](https://rubygems.org/gems/cliqr)
|
11
9
|
|
12
10
|
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc/generate-toc again -->
|
@@ -15,7 +13,7 @@
|
|
15
13
|
- [cliqr](#cliqr)
|
16
14
|
- [Summary](#summary)
|
17
15
|
- [Examples](#examples)
|
18
|
-
|
16
|
+
- [Quickstart](#quickstart)
|
19
17
|
- [Installation](#installation)
|
20
18
|
- [Building](#building)
|
21
19
|
- [Contributing](#contributing)
|
@@ -25,91 +23,119 @@
|
|
25
23
|
|
26
24
|
## Summary
|
27
25
|
|
28
|
-
`cliqr` is a lightweight
|
29
|
-
line application.
|
26
|
+
`cliqr` is a lightweight yet feature rich framework which can be used to
|
27
|
+
build a powerful command line application. It provides a easy to use DSL
|
28
|
+
to define the interface of a application. Some of the features included:
|
30
29
|
|
31
|
-
-
|
32
|
-
-
|
33
|
-
-
|
34
|
-
-
|
30
|
+
- Quick and easy method for defining CLI interface
|
31
|
+
- Command usage generation based on interface definition
|
32
|
+
- Argument parsing
|
33
|
+
- Argument validation
|
34
|
+
- Nested command actions
|
35
|
+
- Multiple command handler based on arguments
|
36
|
+
- Command routing to appropriate handler
|
37
|
+
- Inbuilt shell extension for your command
|
35
38
|
|
36
39
|
## Examples
|
37
40
|
|
38
41
|
The DSL provides several helper methods to build interfaces of different
|
39
|
-
styles.
|
42
|
+
styles. Please refer to the examples folder to find some useful tips on
|
43
|
+
how to use `cliqr`.
|
40
44
|
|
41
|
-
|
45
|
+
## Quickstart
|
42
46
|
|
43
|
-
|
47
|
+
To get things started quickly here is an example of a basic `cliqr`
|
48
|
+
based CLI application (lets call this script `numbers`):
|
44
49
|
|
45
50
|
``` ruby
|
46
|
-
|
51
|
+
#!/usr/bin/env ruby
|
47
52
|
|
48
|
-
|
49
|
-
class MyCommandHandler < Cliqr.command
|
50
|
-
def execute(context)
|
51
|
-
puts 'executing my awesome command'
|
52
|
-
puts "value for option 'an-option' is '#{context.option('an-option').value}'"
|
53
|
-
puts "value for option 'count' is '#{context.option('count').value}'"
|
54
|
-
puts "value for option 'single' is '#{context.option('single').value}'"
|
55
|
-
puts "value for option 'test-1' is '#{context.option('test-1').value}'"
|
56
|
-
puts "has 'count' argument" if context.option?('count')
|
57
|
-
puts "does not have 'test-2' argument" unless context.option?('test-2')
|
58
|
-
end
|
59
|
-
end
|
53
|
+
require 'cliqr'
|
60
54
|
|
61
55
|
cli = Cliqr.interface do
|
62
|
-
|
63
|
-
description '
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
56
|
+
name 'numbers'
|
57
|
+
description 'A simplistic example for quickly getting started with cliqr.'
|
58
|
+
version '0.0.1' # optional; adds a version action to our simple command
|
59
|
+
|
60
|
+
# main command handler
|
61
|
+
handler do
|
62
|
+
puts "Hi #{name}" if name?
|
63
|
+
puts 'Nothing to do here. Please try the sort action.'
|
69
64
|
end
|
70
65
|
|
71
|
-
option
|
72
|
-
|
73
|
-
|
74
|
-
|
66
|
+
option :name do
|
67
|
+
description 'Your name.'
|
68
|
+
operator do
|
69
|
+
value.split(' ').first # only get the first name
|
70
|
+
end
|
75
71
|
end
|
76
72
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
73
|
+
action :sort do
|
74
|
+
description 'Sort a set of random numbers'
|
75
|
+
shell :disable
|
76
|
+
|
77
|
+
handler do
|
78
|
+
fail StandardError, 'count should be a non-zero positive number' unless count > 0
|
79
|
+
result = [].tap { |numbers| count.times { numbers << rand(9999) } }.sort
|
80
|
+
result = result.reverse if order? && order == :descending
|
81
|
+
puts result
|
82
|
+
end
|
83
|
+
|
84
|
+
option :count do
|
85
|
+
short 'c' # optional, but usually a good idea to have it
|
86
|
+
description 'Count of something.'
|
87
|
+
type :numeric # restricts values for this option to numbers
|
88
|
+
end
|
89
|
+
|
90
|
+
option :order do
|
91
|
+
short 'o'
|
92
|
+
description 'Order of sort.'
|
93
|
+
|
94
|
+
# This is how you can make sure that the input is valid.
|
95
|
+
operator do
|
96
|
+
fail StandardError, "Unknown order #{value}" unless [:ascending, :descending].include?(value.to_sym)
|
97
|
+
value.to_sym
|
98
|
+
end
|
99
|
+
end
|
81
100
|
end
|
82
|
-
|
83
|
-
option 'test-1'
|
84
|
-
option 'test-2'
|
85
101
|
end
|
86
102
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
103
|
+
cli.execute(ARGV)
|
104
|
+
```
|
105
|
+
|
106
|
+
Now you can execute this script:
|
107
|
+
|
108
|
+
``` bash
|
109
|
+
$ ./numbers
|
110
|
+
Nothing to do here. Please try the sort action.
|
111
|
+
$ ./numbers --name "Anshul Verma"
|
112
|
+
Hi Anshul
|
113
|
+
Nothing to do here. Please try the sort action.
|
114
|
+
$ ./numbers sort -c 5
|
115
|
+
4519
|
116
|
+
5612
|
117
|
+
6038
|
118
|
+
6872
|
119
|
+
8259
|
120
|
+
$ ./numbers sort -c 5 --order descending
|
121
|
+
8742
|
122
|
+
7995
|
123
|
+
6593
|
124
|
+
2730
|
125
|
+
806
|
126
|
+
```
|
127
|
+
|
128
|
+
A shell command is auto generated for you by `cliqr`. Here is how it works:
|
129
|
+
|
130
|
+
``` bash
|
131
|
+
$ ./numbers shell
|
132
|
+
Starting shell for command "numbers"
|
133
|
+
numbers > sort -c 5
|
134
|
+
1259
|
135
|
+
2031
|
136
|
+
4864
|
137
|
+
8355
|
138
|
+
9824
|
113
139
|
```
|
114
140
|
|
115
141
|
## Installation
|
data/examples/README.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# examples
|
2
|
+
|
3
|
+
Here are some usage examples for `cliqr`. More can be added if needed.
|
4
|
+
|
5
|
+
Please go through the comment at the top of each script. It pretty much
|
6
|
+
explains what the script is.
|
7
|
+
|
8
|
+
To fire off the script and start using it (for `vagrant` example):
|
9
|
+
|
10
|
+
``` bash
|
11
|
+
$ ./vagrant help
|
12
|
+
```
|
data/examples/hbase
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# A fake hbase shell example
|
4
|
+
#
|
5
|
+
# This script mainly features how to build a custom shell
|
6
|
+
|
7
|
+
require 'cliqr'
|
8
|
+
|
9
|
+
cli = Cliqr.interface do
|
10
|
+
name 'hbase'
|
11
|
+
version '0.98.13RC2'
|
12
|
+
arguments :disable
|
13
|
+
|
14
|
+
# from hbase git repository https://github.com/apache/hbase
|
15
|
+
description <<-EOS
|
16
|
+
Apache HBase is an open-source, distributed, versioned, column-oriented
|
17
|
+
store modeled after Google' Bigtable: A Distributed Storage System for
|
18
|
+
Structured Data by Chang et al. Just as Bigtable leverages the distributed
|
19
|
+
data storage provided by the Google File System, HBase provides Bigtable-like
|
20
|
+
capabilities on top of Apache Hadoop.
|
21
|
+
EOS
|
22
|
+
|
23
|
+
option :server do
|
24
|
+
description 'to select the "server" VM'
|
25
|
+
default 'server'
|
26
|
+
end
|
27
|
+
|
28
|
+
TABLES = %w(people address phone_number)
|
29
|
+
action :list do
|
30
|
+
description 'List all tables in hbase.'
|
31
|
+
|
32
|
+
handler do
|
33
|
+
puts 'TABLE'
|
34
|
+
TABLES.each { |item| puts item }
|
35
|
+
puts '3 row(s) in 1.3310 seconds'
|
36
|
+
end
|
37
|
+
arguments :disable
|
38
|
+
end
|
39
|
+
|
40
|
+
action :scan do
|
41
|
+
description 'Scan a table.'
|
42
|
+
|
43
|
+
handler do
|
44
|
+
fail StandardError, 'please specify table name' unless arguments.length > 0
|
45
|
+
fail StandardError, 'too many arguments' if arguments.length > 1
|
46
|
+
table_name = arguments.first
|
47
|
+
fail StandardError, "unknown table \"#{table_name}\"" unless TABLES.include?(table_name)
|
48
|
+
puts <<-EOS
|
49
|
+
ROW COLUMN+CELL
|
50
|
+
my-test:1 column=c1, timestamp=1432748503634, value=0.5
|
51
|
+
my-test:2 column=c1, timestamp=1432748503781, value=1.5
|
52
|
+
2 row(s) in 0.4250 seconds
|
53
|
+
EOS
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
cli.execute(ARGV)
|
data/examples/my-command
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Here is an example on how to use a custom command handler
|
4
|
+
#
|
5
|
+
# This example also shows :boolean and :numeric option types
|
6
|
+
# with their default value settings
|
7
|
+
|
8
|
+
require 'cliqr'
|
9
|
+
|
10
|
+
# a custom command handler for base command
|
11
|
+
class MyCommandHandler < Cliqr.command
|
12
|
+
def execute(context)
|
13
|
+
puts 'executing my awesome command'
|
14
|
+
puts "value for option 'an-option' is '#{context.option('an-option').value}'"
|
15
|
+
puts "value for option 'count' is '#{context.option('count').value}'"
|
16
|
+
puts "value for option 'single' is '#{context.option('single').value}'"
|
17
|
+
puts "value for option 'test-1' is '#{context.option('test-1').value}'"
|
18
|
+
puts "has 'count' argument" if context.option?('count')
|
19
|
+
puts "does not have 'test-2' argument" unless context.option?('test-2')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# another custom command handler for a action
|
24
|
+
class MyActionHandler < Cliqr.command
|
25
|
+
def execute(context)
|
26
|
+
puts "command executed : #{context.command}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
cli = Cliqr.interface do
|
31
|
+
name 'my-command'
|
32
|
+
description 'this is an awesome command...try it out'
|
33
|
+
handler MyCommandHandler
|
34
|
+
|
35
|
+
option 'an-option' do
|
36
|
+
short 'a'
|
37
|
+
description 'this is a option'
|
38
|
+
default :tag => 'qwerty'
|
39
|
+
end
|
40
|
+
|
41
|
+
option 'count' do
|
42
|
+
short 'c'
|
43
|
+
description 'count of something'
|
44
|
+
type :numeric
|
45
|
+
default 10
|
46
|
+
end
|
47
|
+
|
48
|
+
option 'single' do
|
49
|
+
short 's'
|
50
|
+
description 'a boolean option'
|
51
|
+
type :boolean
|
52
|
+
end
|
53
|
+
|
54
|
+
option 'test-1'
|
55
|
+
option 'test-2'
|
56
|
+
|
57
|
+
action 'my-action' do
|
58
|
+
handler MyActionHandler
|
59
|
+
description 'a simple action handler'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
cli.execute(ARGV)
|