clin 0.1.0 → 0.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/.gitignore +2 -1
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +7 -0
- data/README.md +1 -1
- data/examples/dispatcher.rb +22 -50
- data/examples/list_option.rb +27 -0
- data/examples/nested_dispatcher.rb +28 -27
- data/examples/simple.rb +1 -1
- data/examples/test.rb +8 -1
- data/lib/clin/argument.rb +28 -11
- data/lib/clin/command.rb +25 -72
- data/lib/clin/command_dispatcher.rb +2 -1
- data/lib/clin/command_options_mixin.rb +33 -3
- data/lib/clin/command_parser.rb +115 -0
- data/lib/clin/common/help_options.rb +0 -1
- data/lib/clin/errors.rb +7 -2
- data/lib/clin/general_option.rb +5 -5
- data/lib/clin/option.rb +70 -16
- data/lib/clin/option_list.rb +25 -0
- data/lib/clin/version.rb +1 -1
- data/lib/clin.rb +14 -11
- data/spec/clin/command_parser_spec.rb +165 -0
- data/spec/clin/command_spec.rb +112 -0
- data/spec/clin/option_list_spec.rb +32 -0
- data/spec/{cli → clin}/option_spec.rb +10 -2
- data/spec/examples/list_option_spec.rb +20 -0
- data/spec/examples/nested_dispatcher_spec.rb +28 -0
- metadata +26 -14
- data/spec/cli/command_spec.rb +0 -225
- /data/spec/{cli → clin}/argument_spec.rb +0 -0
- /data/spec/{cli → clin}/command_dispacher_spec.rb +0 -0
- /data/spec/{cli → clin}/command_options_mixin_spec.rb +0 -0
- /data/spec/{cli → clin}/common/help_options_spec.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96826af1a7b6e82847b69c692292d7c2a10c69ed
|
4
|
+
data.tar.gz: 28fd292aafc8be55a10af75853283a4def9def65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3690346888ff69f711f292bca3f1e15a4580599ea12f070264b2c6eb6cdedc3f5081ac8113c08d2f391e1a892c6e6e36832d9351367ce83a924ab9ec801392e3
|
7
|
+
data.tar.gz: 05d2c816d4140359ce2a01fca4462417b6c55fca85580fb7ffe7b8692b60498fe33b2dad151b21c783b7673b1a47f8e31a19215e1c63982a072e73a28345f1fd
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
[](https://travis-ci.org/timcolonel/clin)
|
3
3
|
[](https://coveralls.io/r/timcolonel/clin?branch=master)
|
4
4
|
[](https://codeclimate.com/github/timcolonel/clin)
|
5
|
-
|
5
|
+
[](http://inch-ci.org/github/timcolonel/clin)
|
6
6
|
Clin is Command Line Interface library that provide an clean api for complex command configuration.
|
7
7
|
The way Clin is design allow a command defined by the user to be called via the command line as well as directly in the code without any additional configuration
|
8
8
|
## Installation
|
data/examples/dispatcher.rb
CHANGED
@@ -5,8 +5,6 @@ require 'clin'
|
|
5
5
|
class DisplayCommand < Clin::Command
|
6
6
|
arguments 'display <message>'
|
7
7
|
|
8
|
-
general_option Clin::HelpOptions
|
9
|
-
|
10
8
|
self.description = 'Display the given message'
|
11
9
|
|
12
10
|
def run
|
@@ -18,8 +16,6 @@ end
|
|
18
16
|
class PrintCommand < Clin::Command
|
19
17
|
arguments 'print <message>'
|
20
18
|
|
21
|
-
general_option Clin::HelpOptions
|
22
|
-
|
23
19
|
self.description = 'Print the given message'
|
24
20
|
|
25
21
|
def run
|
@@ -27,50 +23,26 @@ class PrintCommand < Clin::Command
|
|
27
23
|
end
|
28
24
|
end
|
29
25
|
|
30
|
-
|
31
|
-
|
32
|
-
puts
|
33
|
-
puts
|
34
|
-
|
35
|
-
|
36
|
-
puts
|
37
|
-
puts
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
puts
|
45
|
-
puts
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
26
|
+
if __FILE__ == $PROGRAM_NAME
|
27
|
+
Clin::CommandDispatcher.parse('display "My Message"').run
|
28
|
+
puts
|
29
|
+
puts '=' * 60
|
30
|
+
puts
|
31
|
+
Clin::CommandDispatcher.parse('print "My Message"').run
|
32
|
+
puts
|
33
|
+
puts '=' * 60
|
34
|
+
puts
|
35
|
+
begin
|
36
|
+
Clin::CommandDispatcher.parse('display -h').run
|
37
|
+
rescue Clin::CommandLineError => e
|
38
|
+
puts e
|
39
|
+
end
|
40
|
+
puts
|
41
|
+
puts '=' * 60
|
42
|
+
puts
|
43
|
+
begin
|
44
|
+
Clin::CommandDispatcher.parse('-h')
|
45
|
+
rescue Clin::CommandLineError => e
|
46
|
+
puts e
|
47
|
+
end
|
50
48
|
end
|
51
|
-
|
52
|
-
# Output:
|
53
|
-
#
|
54
|
-
# $ ruby dispatcher.rb
|
55
|
-
# Display: 'My Message'
|
56
|
-
#
|
57
|
-
# ============================================================
|
58
|
-
#
|
59
|
-
# Print: 'My Message'
|
60
|
-
#
|
61
|
-
# ============================================================
|
62
|
-
#
|
63
|
-
# Usage: command display <message> [Options]
|
64
|
-
#
|
65
|
-
# Options:
|
66
|
-
# -h, --help Show the help.
|
67
|
-
#
|
68
|
-
# Description:
|
69
|
-
# Display the given message
|
70
|
-
#
|
71
|
-
#
|
72
|
-
# ============================================================
|
73
|
-
#
|
74
|
-
# Usage:
|
75
|
-
# command display <message> [Options]
|
76
|
-
# command print <message> [Options]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
$LOAD_PATH.push File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'clin'
|
3
|
+
require 'clin'
|
4
|
+
|
5
|
+
# Simple command Example
|
6
|
+
class ListCommand < Clin::Command
|
7
|
+
list_option :echo, 'Echo some text'
|
8
|
+
list_flag_option :line, 'Print a line in between'
|
9
|
+
general_option Clin::HelpOptions
|
10
|
+
|
11
|
+
def run
|
12
|
+
@params[:echo].each do |msg|
|
13
|
+
puts msg
|
14
|
+
params[:line].times do
|
15
|
+
puts
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
if __FILE__ == $PROGRAM_NAME
|
22
|
+
ListCommand.parse('--echo "Message 1" --echo "Message 2"').run
|
23
|
+
puts
|
24
|
+
puts '=' * 60
|
25
|
+
puts
|
26
|
+
ListCommand.parse('--echo "Message 3" --echo "Message 4" -ll').run
|
27
|
+
end
|
@@ -5,7 +5,9 @@ require 'clin'
|
|
5
5
|
class DispatchCommand < Clin::Command
|
6
6
|
arguments 'you <args>...'
|
7
7
|
dispatch :args, prefix: 'you'
|
8
|
-
|
8
|
+
skip_options true
|
9
|
+
|
10
|
+
flag_option :verbose, 'Verbose the output'
|
9
11
|
|
10
12
|
self.description = 'YOU print the given message'
|
11
13
|
|
@@ -17,8 +19,8 @@ end
|
|
17
19
|
# Simple command Example
|
18
20
|
class DisplayCommand < DispatchCommand
|
19
21
|
arguments 'you display <message>'
|
20
|
-
|
21
|
-
|
22
|
+
option :echo, 'Display more text'
|
23
|
+
option :times, 'Display the text multiple times', type: Integer
|
22
24
|
|
23
25
|
self.description = 'Display the given message'
|
24
26
|
|
@@ -31,8 +33,6 @@ end
|
|
31
33
|
class PrintCommand < DispatchCommand
|
32
34
|
arguments 'you print <message>'
|
33
35
|
|
34
|
-
general_option Clin::HelpOptions
|
35
|
-
|
36
36
|
self.description = 'Print the given message'
|
37
37
|
|
38
38
|
def run
|
@@ -40,27 +40,28 @@ class PrintCommand < DispatchCommand
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
Clin::CommandDispatcher.parse('you display "My Message"').run
|
45
|
-
puts
|
46
|
-
puts '=' * 60
|
47
|
-
puts
|
48
|
-
Clin::CommandDispatcher.parse('you print "My Message"').run
|
49
|
-
puts
|
50
|
-
puts '=' * 60
|
51
|
-
puts
|
52
|
-
begin
|
53
|
-
|
54
|
-
rescue Clin::CommandLineError => e
|
55
|
-
|
56
|
-
end
|
57
|
-
puts
|
58
|
-
puts '=' * 60
|
59
|
-
puts
|
60
|
-
begin
|
61
|
-
|
62
|
-
rescue Clin::CommandLineError => e
|
63
|
-
|
43
|
+
if __FILE__ == $PROGRAM_NAME
|
44
|
+
Clin::CommandDispatcher.parse('you display "My Message"').run
|
45
|
+
puts
|
46
|
+
puts '=' * 60
|
47
|
+
puts
|
48
|
+
Clin::CommandDispatcher.parse('you print "My Message"').run
|
49
|
+
puts
|
50
|
+
puts '=' * 60
|
51
|
+
puts
|
52
|
+
begin
|
53
|
+
Clin::CommandDispatcher.parse('you -h').run
|
54
|
+
rescue Clin::CommandLineError => e
|
55
|
+
puts e
|
56
|
+
end
|
57
|
+
puts
|
58
|
+
puts '=' * 60
|
59
|
+
puts
|
60
|
+
begin
|
61
|
+
Clin::CommandDispatcher.parse('-h')
|
62
|
+
rescue Clin::CommandLineError => e
|
63
|
+
puts e
|
64
|
+
end
|
64
65
|
end
|
65
66
|
|
66
67
|
# Output:
|
@@ -88,4 +89,4 @@ end
|
|
88
89
|
# Usage:
|
89
90
|
# command you <args>... [Options]
|
90
91
|
# command you display <message> [Options]
|
91
|
-
# command you print <message> [Options]
|
92
|
+
# command you print <message> [Options]
|
data/examples/simple.rb
CHANGED
data/examples/test.rb
CHANGED
data/lib/clin/argument.rb
CHANGED
@@ -18,14 +18,16 @@ class Clin::Argument
|
|
18
18
|
@name = check_variable(argument)
|
19
19
|
end
|
20
20
|
|
21
|
+
# Check if the argument is optional(i.e [arg])
|
21
22
|
def check_optional(argument)
|
22
|
-
if
|
23
|
+
if beck_between(argument, '[', ']')
|
23
24
|
@optional = true
|
24
25
|
return argument[1...-1]
|
25
26
|
end
|
26
27
|
argument
|
27
28
|
end
|
28
29
|
|
30
|
+
# Check if the argument is multiple(i.e arg...)
|
29
31
|
def check_multiple(argument)
|
30
32
|
if argument.end_with? '...'
|
31
33
|
@multiple = true
|
@@ -34,8 +36,9 @@ class Clin::Argument
|
|
34
36
|
argument
|
35
37
|
end
|
36
38
|
|
39
|
+
# Check if the argument is variable(i.e <arg>)
|
37
40
|
def check_variable(argument)
|
38
|
-
if
|
41
|
+
if beck_between(argument, '<', '>')
|
39
42
|
@variable = true
|
40
43
|
return argument[1...-1]
|
41
44
|
end
|
@@ -46,21 +49,21 @@ class Clin::Argument
|
|
46
49
|
def parse(argv)
|
47
50
|
return handle_empty if argv.empty?
|
48
51
|
if @multiple
|
49
|
-
|
52
|
+
ensure_fixed(argv) unless @variable
|
50
53
|
[argv, []]
|
51
54
|
else
|
52
|
-
|
55
|
+
ensure_fixed(argv[0]) unless @variable
|
53
56
|
[argv[0], argv[1..-1]]
|
54
57
|
end
|
55
58
|
end
|
56
59
|
|
57
|
-
|
60
|
+
protected
|
58
61
|
|
59
|
-
|
62
|
+
# Ensure the argument are equal to the fix value
|
63
|
+
def ensure_fixed(args)
|
60
64
|
[*args].each do |arg|
|
61
|
-
if arg
|
62
|
-
|
63
|
-
end
|
65
|
+
next if arg == @name
|
66
|
+
fail Clin::FixedArgumentError, @name, arg
|
64
67
|
end
|
65
68
|
end
|
66
69
|
|
@@ -78,10 +81,24 @@ class Clin::Argument
|
|
78
81
|
end
|
79
82
|
end
|
80
83
|
|
81
|
-
|
84
|
+
# Check +argument+ start with +start_char+ and end with +end_char+
|
85
|
+
# @param argument [String]
|
86
|
+
# @param start_char [Char]
|
87
|
+
# @param end_char [Char]
|
88
|
+
# @return [Boolean]
|
89
|
+
# @raise [Clin::Error] if it start but not end with.
|
90
|
+
# ```
|
91
|
+
# beck_between('[arg]', '['. ']') # => true
|
92
|
+
# beck_between('<arg>', '<'. '>') # => true
|
93
|
+
# beck_between('[<arg>]', '['. ']') # => true
|
94
|
+
# beck_between('[<arg>]', '<'. '>') # => false
|
95
|
+
# beck_between('[<arg>', '<'. '>') # => raise Clin::Error
|
96
|
+
# ```
|
97
|
+
def beck_between(argument, start_char, end_char)
|
82
98
|
if argument[0] == start_char
|
83
99
|
if argument[-1] != end_char
|
84
|
-
fail Clin::Error, "Argument format error! Cannot start
|
100
|
+
fail Clin::Error, "Argument format error! Cannot start
|
101
|
+
with #{start_char} and not end with #{end_char}"
|
85
102
|
end
|
86
103
|
return true
|
87
104
|
end
|
data/lib/clin/command.rb
CHANGED
@@ -6,20 +6,19 @@ require 'clin/common/help_options'
|
|
6
6
|
|
7
7
|
# Clin Command
|
8
8
|
class Clin::Command < Clin::CommandOptionsMixin
|
9
|
-
|
10
9
|
class_attribute :args
|
11
10
|
class_attribute :description
|
12
11
|
|
13
|
-
|
14
12
|
# Redispatch will be reset to nil when inheriting a dispatcher command
|
15
13
|
class_attribute :_redispatch_args
|
16
14
|
class_attribute :_abstract
|
17
15
|
class_attribute :_exe_name
|
16
|
+
class_attribute :_skip_options
|
18
17
|
|
19
18
|
self.args = []
|
20
19
|
self.description = ''
|
21
20
|
self._abstract = false
|
22
|
-
|
21
|
+
self._skip_options = false
|
23
22
|
|
24
23
|
# Trigger when a class inherit this class
|
25
24
|
# Rest class_attributes that should not be shared with subclass
|
@@ -27,6 +26,7 @@ class Clin::Command < Clin::CommandOptionsMixin
|
|
27
26
|
def self.inherited(subclass)
|
28
27
|
subclass._redispatch_args = nil
|
29
28
|
subclass._abstract = false
|
29
|
+
subclass._skip_options = false
|
30
30
|
super
|
31
31
|
end
|
32
32
|
|
@@ -46,11 +46,23 @@ class Clin::Command < Clin::CommandOptionsMixin
|
|
46
46
|
# end
|
47
47
|
# Git.usage # => git <command> <args>...
|
48
48
|
# ```
|
49
|
-
def self.exe_name(value=nil)
|
49
|
+
def self.exe_name(value = nil)
|
50
50
|
self._exe_name = value unless value.nil?
|
51
51
|
self._exe_name ||= Clin.exe_name
|
52
52
|
end
|
53
53
|
|
54
|
+
def self.skip_options(value)
|
55
|
+
self._skip_options = value
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.skip_options?
|
59
|
+
_skip_options
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.redispatch?
|
63
|
+
!_redispatch_args.nil?
|
64
|
+
end
|
65
|
+
|
54
66
|
def self.arguments(args)
|
55
67
|
self.args = []
|
56
68
|
[*args].map(&:split).flatten.each do |arg|
|
@@ -70,37 +82,8 @@ class Clin::Command < Clin::CommandOptionsMixin
|
|
70
82
|
# Parse the command and initialize the command object with the parsed options
|
71
83
|
# @param argv [Array|String] command line to parse.
|
72
84
|
def self.parse(argv = ARGV, fallback_help: true)
|
73
|
-
|
74
|
-
|
75
|
-
options_map = parse_options(argv)
|
76
|
-
error = nil
|
77
|
-
begin
|
78
|
-
args_map = parse_arguments(argv)
|
79
|
-
rescue Clin::MissingArgumentError => e
|
80
|
-
error = e
|
81
|
-
rescue Clin::FixedArgumentError => e
|
82
|
-
raise e unless fallback_help
|
83
|
-
error = e
|
84
|
-
end
|
85
|
-
args_map ||= {}
|
86
|
-
|
87
|
-
options = options_map.merge(args_map)
|
88
|
-
return handle_dispatch(options) unless self._redispatch_args.nil?
|
89
|
-
obj = new(options)
|
90
|
-
if error
|
91
|
-
fail Clin::HelpError, option_parser if fallback_help
|
92
|
-
fail error
|
93
|
-
end
|
94
|
-
obj
|
95
|
-
end
|
96
|
-
|
97
|
-
# Parse the options in the argv.
|
98
|
-
# @return [Array] the list of argv that are not options(positional arguments)
|
99
|
-
def self.parse_options(argv)
|
100
|
-
out = {}
|
101
|
-
parser = option_parser(out)
|
102
|
-
parser.parse!(argv)
|
103
|
-
out
|
85
|
+
parser = Clin::CommandParser.new(self, argv, fallback_help: fallback_help)
|
86
|
+
parser.parse
|
104
87
|
end
|
105
88
|
|
106
89
|
# Build the Option Parser object
|
@@ -121,22 +104,6 @@ class Clin::Command < Clin::CommandOptionsMixin
|
|
121
104
|
end
|
122
105
|
end
|
123
106
|
|
124
|
-
def self.execute_general_options(options)
|
125
|
-
general_options.each do |_cls, gopts|
|
126
|
-
gopts.execute(options)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
# Parse the argument. The options must have been strip out first.
|
131
|
-
def self.parse_arguments(argv)
|
132
|
-
out = {}
|
133
|
-
self.args.each do |arg|
|
134
|
-
value, argv = arg.parse(argv)
|
135
|
-
out[arg.name.to_sym] = value
|
136
|
-
end
|
137
|
-
out.delete_if { |_, v| v.nil? }
|
138
|
-
end
|
139
|
-
|
140
107
|
# Redispatch the command to a sub command with the given arguments
|
141
108
|
# @param args [Array<String>|String] New argument to parse
|
142
109
|
# @param prefix [String] Prefix to add to the beginning of the command
|
@@ -149,46 +116,32 @@ class Clin::Command < Clin::CommandOptionsMixin
|
|
149
116
|
self._redispatch_args = [[*args], prefix, commands]
|
150
117
|
end
|
151
118
|
|
152
|
-
# Method called after the argument have been parsed and before creating the command
|
153
|
-
# @param params [List<String>] Parsed params from the command line.
|
154
|
-
def self.handle_dispatch(params)
|
155
|
-
args, prefix, commands = self._redispatch_args
|
156
|
-
commands ||= default_commands
|
157
|
-
dispatcher = Clin::CommandDispatcher.new(commands)
|
158
|
-
args = args.map { |x| params[x] }.flatten
|
159
|
-
args = prefix.split + args unless prefix.nil?
|
160
|
-
begin
|
161
|
-
dispatcher.parse(args)
|
162
|
-
rescue Clin::HelpError
|
163
|
-
raise Clin::HelpError, option_parser
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
119
|
def self.dispatch_doc(opts)
|
168
|
-
return if
|
120
|
+
return if _redispatch_args.nil?
|
169
121
|
opts.separator 'Examples: '
|
170
|
-
commands = (
|
122
|
+
commands = (_redispatch_args[2] || default_commands)
|
171
123
|
commands.each do |cmd_cls|
|
172
124
|
opts.separator "\t#{cmd_cls.usage}"
|
173
125
|
end
|
174
126
|
end
|
175
127
|
|
176
128
|
def self.default_commands
|
177
|
-
# self.constants.map { |c| self.const_get(c) }
|
178
|
-
|
129
|
+
# self.constants.map { |c| self.const_get(c) }
|
130
|
+
# .select { |c| c.is_a?(Class) && (c < Clin::Command) }
|
131
|
+
subcommands
|
179
132
|
end
|
180
133
|
|
181
134
|
# List the subcommands
|
182
135
|
# The subcommands are all the Classes inheriting this one that are not set to abstract
|
183
136
|
def self.subcommands
|
184
|
-
|
137
|
+
subclasses.reject(&:_abstract)
|
185
138
|
end
|
186
139
|
|
187
140
|
general_option 'Clin::HelpOptions'
|
188
141
|
|
189
142
|
attr_accessor :params
|
190
143
|
|
191
|
-
def initialize(params)
|
144
|
+
def initialize(params = {})
|
192
145
|
@params = params
|
193
146
|
self.class.execute_general_options(params)
|
194
147
|
end
|
@@ -3,6 +3,7 @@ require 'clin/command'
|
|
3
3
|
|
4
4
|
# Class charge dispatching the CL to the right command
|
5
5
|
class Clin::CommandDispatcher
|
6
|
+
# Contains the list of commands the dispatch will test.
|
6
7
|
attr_accessor :commands
|
7
8
|
|
8
9
|
# Create a new command dispatcher.
|
@@ -32,7 +33,7 @@ class Clin::CommandDispatcher
|
|
32
33
|
|
33
34
|
# Helper method to parse against all the commands
|
34
35
|
# @see #parse
|
35
|
-
def self.parse(argv=ARGV)
|
36
|
+
def self.parse(argv = ARGV)
|
36
37
|
Clin::CommandDispatcher.new.parse(argv)
|
37
38
|
end
|
38
39
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'clin'
|
2
2
|
require 'clin/option'
|
3
|
+
require 'clin/option_list'
|
3
4
|
|
4
5
|
# Template class for reusable options and commands
|
5
6
|
# It provide the method to add options to a command
|
@@ -9,7 +10,6 @@ class Clin::CommandOptionsMixin
|
|
9
10
|
self.options = []
|
10
11
|
self.general_options = {}
|
11
12
|
|
12
|
-
|
13
13
|
# Add an option
|
14
14
|
# @param args list of arguments.
|
15
15
|
# * First argument must be the name if no block is given.
|
@@ -52,6 +52,21 @@ class Clin::CommandOptionsMixin
|
|
52
52
|
add_option Clin::Option.new(name, description, **config.merge(argument: false), &block)
|
53
53
|
end
|
54
54
|
|
55
|
+
# Add a list option.
|
56
|
+
# @see Clin::OptionList#initialize
|
57
|
+
def self.list_option(name, description, **config)
|
58
|
+
add_option Clin::OptionList.new(name, description, **config)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Add a list options that don't take arguments
|
62
|
+
# Same as .list_option but set +argument+ to false
|
63
|
+
# @see Clin::OptionList#initialize
|
64
|
+
def self.list_flag_option(name, description, **config)
|
65
|
+
add_option Clin::OptionList.new(name, description, **config.merge(argument: false))
|
66
|
+
end
|
67
|
+
|
68
|
+
# Add a new option.
|
69
|
+
# @param option [Clin::Option] option to add.
|
55
70
|
def self.add_option(option)
|
56
71
|
# Need to use += instead of << otherwise the parent class will also be changed
|
57
72
|
self.options += [option]
|
@@ -62,14 +77,14 @@ class Clin::CommandOptionsMixin
|
|
62
77
|
# @param config [Hash] General option config. Check the general option config.
|
63
78
|
def self.general_option(option_cls, config = {})
|
64
79
|
option_cls = option_cls.constantize if option_cls.is_a? String
|
65
|
-
self.general_options =
|
80
|
+
self.general_options = general_options.merge(option_cls => option_cls.new(config))
|
66
81
|
end
|
67
82
|
|
68
83
|
# Remove a general option
|
69
84
|
# Might be useful if a parent added the option but is not needed in this child.
|
70
85
|
def self.remove_general_option(option_cls)
|
71
86
|
option_cls = option_cls.constantize if option_cls.is_a? String
|
72
|
-
self.general_options =
|
87
|
+
self.general_options = general_options.except(option_cls)
|
73
88
|
end
|
74
89
|
|
75
90
|
# To be called inside OptionParser block
|
@@ -85,4 +100,19 @@ class Clin::CommandOptionsMixin
|
|
85
100
|
option.class.register_options(opts, out)
|
86
101
|
end
|
87
102
|
end
|
103
|
+
|
104
|
+
# Call #execute on each of the general options.
|
105
|
+
# This is called during the command initialization
|
106
|
+
# e.g. A verbose general option execute would be:
|
107
|
+
# ```
|
108
|
+
# def execute(params)
|
109
|
+
# MyApp.verbose = true if params[:verbose]
|
110
|
+
# end
|
111
|
+
# ```
|
112
|
+
def self.execute_general_options(options)
|
113
|
+
general_options.each do |_cls, gopts|
|
114
|
+
gopts.execute(options)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
88
118
|
end
|