clin 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/timcolonel/clin.svg?branch=master)](https://travis-ci.org/timcolonel/clin)
|
3
3
|
[![Coverage Status](https://coveralls.io/repos/timcolonel/clin/badge.svg?branch=master)](https://coveralls.io/r/timcolonel/clin?branch=master)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/timcolonel/clin/badges/gpa.svg)](https://codeclimate.com/github/timcolonel/clin)
|
5
|
-
|
5
|
+
[![Inline docs](http://inch-ci.org/github/timcolonel/clin.svg?branch=master)](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
|