mamertes 2.4.1
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 +15 -0
- data/.DS_Store +0 -0
- data/.gitignore +6 -0
- data/.travis-gemfile +15 -0
- data/.travis.yml +10 -0
- data/.yardopts +1 -0
- data/Gemfile +21 -0
- data/README.md +126 -0
- data/Rakefile +29 -0
- data/doc/Mamertes.html +155 -0
- data/doc/Mamertes/Application.html +3057 -0
- data/doc/Mamertes/Command.html +7031 -0
- data/doc/Mamertes/CommandMethods.html +125 -0
- data/doc/Mamertes/CommandMethods/Children.html +1286 -0
- data/doc/Mamertes/CommandMethods/Help.html +209 -0
- data/doc/Mamertes/Error.html +631 -0
- data/doc/Mamertes/Localizer.html +376 -0
- data/doc/Mamertes/Option.html +6671 -0
- data/doc/Mamertes/Parser.html +276 -0
- data/doc/Mamertes/ParserMethods.html +125 -0
- data/doc/Mamertes/ParserMethods/General.html +134 -0
- data/doc/Mamertes/ParserMethods/General/ClassMethods.html +574 -0
- data/doc/Mamertes/Version.html +189 -0
- data/doc/_index.html +276 -0
- data/doc/class_list.html +54 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +57 -0
- data/doc/css/style.css +338 -0
- data/doc/file.README.html +198 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +28 -0
- data/doc/index.html +198 -0
- data/doc/js/app.js +214 -0
- data/doc/js/full_list.js +178 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +509 -0
- data/doc/top-level-namespace.html +112 -0
- data/lib/mamertes.rb +18 -0
- data/lib/mamertes/application.rb +206 -0
- data/lib/mamertes/command.rb +529 -0
- data/lib/mamertes/option.rb +236 -0
- data/lib/mamertes/parser.rb +317 -0
- data/lib/mamertes/version.rb +24 -0
- data/locales/en.yml +40 -0
- data/locales/it.yml +40 -0
- data/mamertes.gemspec +30 -0
- data/spec/coverage_helper.rb +20 -0
- data/spec/mamertes/application_spec.rb +181 -0
- data/spec/mamertes/command_spec.rb +526 -0
- data/spec/mamertes/option_spec.rb +274 -0
- data/spec/mamertes/parser_spec.rb +126 -0
- data/spec/spec_helper.rb +15 -0
- metadata +115 -0
@@ -0,0 +1,236 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# This file is part of the mamertes gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
|
4
|
+
# Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Mamertes
|
8
|
+
# List of valid option types.
|
9
|
+
#
|
10
|
+
# Values are the default values for that type.
|
11
|
+
#
|
12
|
+
# For any unknown type, the default value is `false`, it means that any unknown type is managed as a Boolean value with no argument.
|
13
|
+
OPTION_TYPES = {String => "", Integer => 0, Float => 0.0, Array => []}
|
14
|
+
OPTION_TYPES.default = false
|
15
|
+
|
16
|
+
# This class represents an option for a command.
|
17
|
+
#
|
18
|
+
# @attribute name
|
19
|
+
# @return [String] The name of this option.
|
20
|
+
# @attribute short
|
21
|
+
# @return [String] The short form (i.e.: `-h`) for this option.
|
22
|
+
# @attribute long
|
23
|
+
# @return [String] The long form (i.e.: `--help`) for this option.
|
24
|
+
# @attribute type
|
25
|
+
# @return [Class] The type of this option.
|
26
|
+
# @attribute required
|
27
|
+
# @return [Boolean] If this option is required.
|
28
|
+
# @attribute default
|
29
|
+
# @return [Object] The default value of this option.
|
30
|
+
# @attribute meta
|
31
|
+
# @return [String] The META argument for this option, used only when showing the help.
|
32
|
+
# @attribute help
|
33
|
+
# @return [String] An help message for this option.
|
34
|
+
# @attribute value
|
35
|
+
# @return [Object] The current value of this option.
|
36
|
+
# @attribute action
|
37
|
+
# @return [Proc] The action associated to this option.
|
38
|
+
# @attribute validator
|
39
|
+
# @return [Array|Regexp] or A constraint for valid values. Can be an Array of valid values or a Regexp.
|
40
|
+
# @attribute parent
|
41
|
+
# @return [Command] The parent of this option.
|
42
|
+
class Option
|
43
|
+
attr_accessor :name
|
44
|
+
attr_accessor :short
|
45
|
+
attr_accessor :long
|
46
|
+
attr_accessor :type
|
47
|
+
attr_accessor :required
|
48
|
+
attr_accessor :default
|
49
|
+
attr_accessor :meta
|
50
|
+
attr_accessor :help
|
51
|
+
attr_accessor :value
|
52
|
+
attr_accessor :action
|
53
|
+
attr_accessor :validator
|
54
|
+
attr_accessor :parent
|
55
|
+
|
56
|
+
# Creates a new option.
|
57
|
+
#
|
58
|
+
# @param name [String] The name of this option. Must be unique.
|
59
|
+
# @param forms [Array] An array of short and long forms for this option. Missing forms will be inferred by the name.
|
60
|
+
# @param options [Hash] The settings for this option.
|
61
|
+
# @param action [Proc] The action of this option.
|
62
|
+
def initialize(name, forms = [], options = {}, &action)
|
63
|
+
@name = name.ensure_string
|
64
|
+
@provided = false
|
65
|
+
setup_forms(forms)
|
66
|
+
setup_options(options)
|
67
|
+
setup_action(action)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Sets the short form of this option.
|
71
|
+
#
|
72
|
+
# @param value [String] The short form of this option.
|
73
|
+
def short=(value)
|
74
|
+
value = @name[0, 1] if !value.present?
|
75
|
+
|
76
|
+
# Clean value
|
77
|
+
final_value = value.to_s.match(/^-{0,2}([a-z0-9])(.*)$/i)[1]
|
78
|
+
|
79
|
+
@short = final_value if final_value.present?
|
80
|
+
end
|
81
|
+
|
82
|
+
# Sets the long form of this option.
|
83
|
+
#
|
84
|
+
# @param value [String] The short form of this option.
|
85
|
+
def long=(value)
|
86
|
+
value = @name if !value.present?
|
87
|
+
|
88
|
+
# Clean value
|
89
|
+
final_value = value.to_s.match(/^-{0,2}(.+)$/)[1]
|
90
|
+
|
91
|
+
@long = final_value if final_value.present?
|
92
|
+
end
|
93
|
+
|
94
|
+
# Sets the long form of this option. Can be a Object, an Array or a Regexp.
|
95
|
+
#
|
96
|
+
# @param value [String] The validator of this option.
|
97
|
+
def validator=(value)
|
98
|
+
value = nil if value.blank? || (value.is_a?(Regexp) && value.source.blank?)
|
99
|
+
value = value.ensure_array(nil, true, true, true, :ensure_string) if !value.nil? && !value.is_a?(Regexp)
|
100
|
+
@validator = value
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns the short form with a dash prepended.
|
104
|
+
#
|
105
|
+
# @return [String] The short form with a dash prepended.
|
106
|
+
def complete_short
|
107
|
+
"-#{@short}"
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns the long form with two dashes prepended.
|
111
|
+
#
|
112
|
+
# @return [String] The short form with two dashes prepended.
|
113
|
+
def complete_long
|
114
|
+
"--#{@long}"
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns a label for this option, combining short and long forms.
|
118
|
+
#
|
119
|
+
# @return [String] A label for this option.
|
120
|
+
def label
|
121
|
+
[complete_short, complete_long].compact.join("/")
|
122
|
+
end
|
123
|
+
|
124
|
+
# Returns the meta argument for this option.
|
125
|
+
#
|
126
|
+
# @return [String|NilClass] Returns the current meta argument for this option (the default value is the option name uppercased) or `nil`, if this option doesn't require a meta argument.
|
127
|
+
def meta
|
128
|
+
requires_argument? ? (@meta.present? ? @meta : @name.upcase) : nil
|
129
|
+
end
|
130
|
+
|
131
|
+
# Get the current default value for this option.
|
132
|
+
#
|
133
|
+
# @return [Object] The default value for this option.
|
134
|
+
def default
|
135
|
+
@default || ::Mamertes::OPTION_TYPES[@type]
|
136
|
+
end
|
137
|
+
|
138
|
+
# Check if the current option has a default value.
|
139
|
+
#
|
140
|
+
# @return [Boolean] If the current option has a default value.
|
141
|
+
def has_default?
|
142
|
+
!@default.nil?
|
143
|
+
end
|
144
|
+
|
145
|
+
# Sets the value of this option and also make sure that it is validated.
|
146
|
+
#
|
147
|
+
# @param value [Object] The new value of this option.
|
148
|
+
# @param raise_error [Boolean] If raise an ArgumentError in case of validation errors.
|
149
|
+
# @return [Boolean] `true` if operation succeeded, `false` otherwise.
|
150
|
+
def set(value, raise_error = true)
|
151
|
+
vs = @validator.present? ? (@validator.is_a?(Array) ? :array : :regexp) : false # Check we have a validator
|
152
|
+
rv = vs ? @validator.send(vs == :array ? "include?" : "match", value) : true
|
153
|
+
|
154
|
+
if rv then
|
155
|
+
@value = value
|
156
|
+
@provided = true
|
157
|
+
elsif raise_error then # Validation failed
|
158
|
+
handle_set_failure(vs)
|
159
|
+
else
|
160
|
+
false
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Executes the action associated to this option.
|
165
|
+
def execute_action
|
166
|
+
if @action.present? then
|
167
|
+
@provided = true
|
168
|
+
@action.call(parent, self)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
# Checks if this option requires an argument.
|
173
|
+
#
|
174
|
+
# @return [Boolean] `true` if this option requires an argument, `false` otherwise.
|
175
|
+
def requires_argument?
|
176
|
+
[String, Integer, Float, Array].include?(@type) && @action.blank?
|
177
|
+
end
|
178
|
+
|
179
|
+
# If this option was provided.
|
180
|
+
#
|
181
|
+
# @return [Boolean] `true` if this option was provided, `false` otherwise.
|
182
|
+
def provided?
|
183
|
+
@provided
|
184
|
+
end
|
185
|
+
|
186
|
+
# Check if this command has a help.
|
187
|
+
#
|
188
|
+
# @return [Boolean] `true` if this command has a help, `false` otherwise.
|
189
|
+
def has_help?
|
190
|
+
@help.present?
|
191
|
+
end
|
192
|
+
|
193
|
+
# Get the current value for this option.
|
194
|
+
#
|
195
|
+
# @return [Object] The current value of this option.
|
196
|
+
def value
|
197
|
+
provided? ? @value : default
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
# Setups the forms of the this option.
|
202
|
+
#
|
203
|
+
# @param forms [Array] An array of short and long forms for this option. Missing forms will be inferred by the name.
|
204
|
+
def setup_forms(forms)
|
205
|
+
self.short = forms.length > 0 ? forms[0] : @name[0, 1]
|
206
|
+
self.long = forms.length == 2 ? forms[1] : @name
|
207
|
+
end
|
208
|
+
|
209
|
+
# Setups the settings of the this option.
|
210
|
+
#
|
211
|
+
# @param options [Hash] The settings for this option.
|
212
|
+
def setup_options(options)
|
213
|
+
(options.is_a?(::Hash) ? options : {}).each_pair do |option, value|
|
214
|
+
send("#{option}=", value) if respond_to?("#{option}=")
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# Setups the action of the this option.
|
219
|
+
#
|
220
|
+
# @param action [Proc] The action of this option.
|
221
|
+
def setup_action(action)
|
222
|
+
@action = action if action.present? && action.respond_to?(:call) && action.try(:arity) == 2
|
223
|
+
end
|
224
|
+
|
225
|
+
# Handle failure in setting an option.
|
226
|
+
#
|
227
|
+
# @param vs [Symbol] The type of validator.
|
228
|
+
def handle_set_failure(vs)
|
229
|
+
if vs == :array then
|
230
|
+
raise ::Mamertes::Error.new(self, :validation_failed, @parent.i18n.invalid_value(label, ::Mamertes::Parser.smart_join(@validator)))
|
231
|
+
else
|
232
|
+
raise ::Mamertes::Error.new(self, :validation_failed, @parent.i18n.invalid_for_regexp(label, @validator.inspect))
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
@@ -0,0 +1,317 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# This file is part of the mamertes gem. Copyright (C) 2013 and above Shogun <shogun_panda@me.com>.
|
4
|
+
# Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Mamertes
|
8
|
+
# Methods for the {Parser Parser} class.
|
9
|
+
module ParserMethods
|
10
|
+
# General methods.
|
11
|
+
module General
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
# Class methods
|
15
|
+
module ClassMethods
|
16
|
+
# Joins an array using multiple separators.
|
17
|
+
#
|
18
|
+
# @param array [Array] The array to join.
|
19
|
+
# @param separator [String] The separator to use for all but last join.
|
20
|
+
# @param last_separator [String] The separator to use for the last join.
|
21
|
+
# @param quote [String] If not nil, elements are quoted with that element.
|
22
|
+
# @return [String] The joined array.
|
23
|
+
def smart_join(array, separator = ", ", last_separator = " and ", quote = "\"")
|
24
|
+
separator = separator.ensure_string
|
25
|
+
last_separator = last_separator.ensure_string
|
26
|
+
array = array.ensure_array {|a| quote.present? ? "#{quote}#{a}#{quote}" : a.ensure_string }
|
27
|
+
array.length < 2 ? (array[0] || "") : (array[0, array.length - 1].join(separator) + last_separator + array[-1])
|
28
|
+
end
|
29
|
+
|
30
|
+
# Finds a command which corresponds to an argument.
|
31
|
+
#
|
32
|
+
# @param arg [String] The string to match.
|
33
|
+
# @param command [Command] The command to search subcommand in.
|
34
|
+
# @param args [String] The complete list of arguments passed.
|
35
|
+
# @param separator [String] The separator for joined syntax commands.
|
36
|
+
# @return [Hash|NilClass] An hash with `name` and `args` keys if a valid subcommand is found, `nil` otherwise.
|
37
|
+
def find_command(arg, command, args, separator = ":")
|
38
|
+
args = args.ensure_array.dup
|
39
|
+
|
40
|
+
if command.commands.present? then
|
41
|
+
arg, args = adjust_command(arg, args, separator)
|
42
|
+
|
43
|
+
matching = match_subcommands(arg, command)
|
44
|
+
if matching.length == 1 # Found a command
|
45
|
+
{name: matching[0], args: args}
|
46
|
+
elsif matching.length > 1 # Ambiguous match
|
47
|
+
raise ::Mamertes::Error.new(command, :ambiguous_command, command.i18n.ambigous_command(arg, ::Mamertes::Parser.smart_join(matching)))
|
48
|
+
end
|
49
|
+
else
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Parses a command/application.
|
55
|
+
#
|
56
|
+
# @param command [Command] The command or application to parse.
|
57
|
+
# @param args [Array] The arguments to parse.
|
58
|
+
# @return [Hash|NilClass] An hash with `name` (of a subcommand to execute) and `args` keys if a valid subcommand is found, `nil` otherwise.
|
59
|
+
def parse(command, args)
|
60
|
+
::Mamertes::Parser.new.parse(command, args)
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
# Adjusts a command so that it only specify a single command.
|
65
|
+
#
|
66
|
+
# @param arg [String] The string to match.
|
67
|
+
# @param args [String] The complete list of arguments passed.
|
68
|
+
# @param separator [String] The separator for joined syntax commands.
|
69
|
+
# @return [Array] Adjust command and arguments.
|
70
|
+
def adjust_command(arg, args, separator)
|
71
|
+
if arg.index(separator) then
|
72
|
+
tokens = arg.split(separator, 2)
|
73
|
+
arg = tokens[0]
|
74
|
+
args.insert(0, tokens[1])
|
75
|
+
end
|
76
|
+
|
77
|
+
[arg, args]
|
78
|
+
end
|
79
|
+
|
80
|
+
# Matches a string against a command's subcommands.
|
81
|
+
#
|
82
|
+
# @param arg [String] The string to match.
|
83
|
+
# @param command [Command] The command to search subcommand in.
|
84
|
+
# @return [Array] The matching subcommands.
|
85
|
+
def match_subcommands(arg, command)
|
86
|
+
command.commands.keys.select {|c| c =~ /^(#{Regexp.quote(arg)})/ }.compact
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# The parser for the command line.
|
93
|
+
class Parser
|
94
|
+
include ::Mamertes::ParserMethods::General
|
95
|
+
|
96
|
+
# Parses a command/application.
|
97
|
+
#
|
98
|
+
# @param command [Command] The command or application to parse.
|
99
|
+
# @param args [Array] The arguments to parse.
|
100
|
+
# @return [Hash|NilClass] An hash with `name` (of a subcommand to execute) and `args` keys if a valid subcommand is found, `nil` otherwise.
|
101
|
+
def parse(command, args)
|
102
|
+
args = args.ensure_array.dup
|
103
|
+
forms, parser = create_parser(command)
|
104
|
+
perform_parsing(parser, command, args, forms)
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
# Creates a new option parser.
|
109
|
+
#
|
110
|
+
# @param command [Command] The command or application to parse.
|
111
|
+
# @return [OptionParser] The new parser
|
112
|
+
def create_parser(command)
|
113
|
+
forms = {}
|
114
|
+
parser = OptionParser.new do |opts|
|
115
|
+
# Add every option
|
116
|
+
command.options.each_pair do |_, option|
|
117
|
+
check_unique(command, forms, option)
|
118
|
+
setup_option(command, opts, option)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
[forms, parser]
|
123
|
+
end
|
124
|
+
|
125
|
+
# Perform the parsing
|
126
|
+
#
|
127
|
+
# @param parser [OptionParser] The option parser.
|
128
|
+
# @param command [Command] The command or application to parse.
|
129
|
+
# @param args [Array] The arguments to parse.
|
130
|
+
# @param forms [Hash] The current forms.
|
131
|
+
def perform_parsing(parser, command, args, forms)
|
132
|
+
rv = nil
|
133
|
+
|
134
|
+
begin
|
135
|
+
rv = execute_parsing(parser, command, args)
|
136
|
+
rescue OptionParser::NeedlessArgument, OptionParser::MissingArgument, OptionParser::InvalidOption => oe
|
137
|
+
type = oe.class.to_s.gsub("OptionParser::", "").underscore.to_sym
|
138
|
+
opt = oe.args.first
|
139
|
+
raise ::Mamertes::Error.new(forms[opt], type, command.i18n.send(type, opt))
|
140
|
+
rescue => e
|
141
|
+
raise e
|
142
|
+
end
|
143
|
+
|
144
|
+
rv
|
145
|
+
end
|
146
|
+
|
147
|
+
# Executes the parsing.
|
148
|
+
#
|
149
|
+
# @param parser [OptionParser] The option parser.
|
150
|
+
# @param command [Command] The command or application to parse.
|
151
|
+
# @param args [Array] The arguments to parse.
|
152
|
+
# @return [Command|nil] A command to execute or `nil` if no valid command was found.
|
153
|
+
def execute_parsing(parser, command, args)
|
154
|
+
rv = nil
|
155
|
+
|
156
|
+
if command.options.present? then
|
157
|
+
rv = parse_options(parser, command, args)
|
158
|
+
check_required_options(command)
|
159
|
+
elsif args.present? then
|
160
|
+
rv = find_command_to_execute(command, args)
|
161
|
+
end
|
162
|
+
|
163
|
+
rv
|
164
|
+
end
|
165
|
+
|
166
|
+
# Setups an option for a command.
|
167
|
+
#
|
168
|
+
# @param command [Command] The command or application to parse.
|
169
|
+
# @param opts [Object] The current set options.
|
170
|
+
# @param option [Option] The option to set.
|
171
|
+
def setup_option(command, opts, option)
|
172
|
+
case option.type.to_s
|
173
|
+
when "String" then parse_string(command, opts, option)
|
174
|
+
when "Integer" then parse_number(command, opts, option, :is_integer?, :to_integer, command.i18n.invalid_integer(option.label))
|
175
|
+
when "Float" then parse_number(command, opts, option, :is_float?, :to_float, command.i18n.invalid_float(option.label))
|
176
|
+
when "Array" then parse_array(command, opts, option)
|
177
|
+
else option.action.present? ? parse_action(opts, option) : parse_boolean(opts, option)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Checks if a option is unique.
|
182
|
+
#
|
183
|
+
# @param command [Command] The command or application to parse.
|
184
|
+
# @param forms [Hash] The current forms.
|
185
|
+
# @param option [Option] The option to set.
|
186
|
+
def check_unique(command, forms, option)
|
187
|
+
if forms[option.complete_short] || forms[option.complete_long] then
|
188
|
+
raise ::Mamertes::Error.new(command, :ambiguous_form, command.i18n.conflicting_options(option.label, forms[option.complete_short].label))
|
189
|
+
else
|
190
|
+
forms[option.complete_short] = option.dup
|
191
|
+
forms[option.complete_long] = option.dup
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Parses an action option. A block must be provided to deal with the value.
|
196
|
+
#
|
197
|
+
# @param command [Command] The command or application to parse.
|
198
|
+
# @param opts [Object] The current set options.
|
199
|
+
# @param option [Option] The option to set.
|
200
|
+
def parse_option(command, opts, option)
|
201
|
+
opts.on("#{option.complete_short} #{option.meta || command.i18n.help_arg}", "#{option.complete_long} #{option.meta || command.i18n.help_arg}") do |value|
|
202
|
+
yield(value)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
# Parses an action option.
|
207
|
+
#
|
208
|
+
# @param opts [Object] The current set options.
|
209
|
+
# @param option [Option] The option to set.
|
210
|
+
def parse_action(opts, option)
|
211
|
+
opts.on("-#{option.short}", "--#{option.long}") do |_|
|
212
|
+
option.execute_action
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Parses a string option.
|
217
|
+
#
|
218
|
+
# @param command [Command] The command or application to parse.
|
219
|
+
# @param opts [Object] The current set options.
|
220
|
+
# @param option [Option] The option to set.
|
221
|
+
def parse_string(command, opts, option)
|
222
|
+
parse_option(command, opts, option) { |value| option.set(value) }
|
223
|
+
end
|
224
|
+
|
225
|
+
# Parses a number option.
|
226
|
+
#
|
227
|
+
# @param command [Command] The command or application to parse.
|
228
|
+
# @param opts [Object] The current set options.
|
229
|
+
# @param option [Option] The option to set.
|
230
|
+
# @param check_method [Symbol] The method to execute to check option validity. Must return a boolean.
|
231
|
+
# @param convert_method [Symbol] The method to execute to convert option.
|
232
|
+
# @param invalid_message [String] The string to send in case of invalid arguments.
|
233
|
+
def parse_number(command, opts, option, check_method, convert_method, invalid_message)
|
234
|
+
parse_option(command, opts, option) do |value|
|
235
|
+
raise ::Mamertes::Error.new(option, :invalid_argument, invalid_message) if !value.send(check_method)
|
236
|
+
option.set(value.send(convert_method))
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# Parses an array option.
|
241
|
+
#
|
242
|
+
# @param command [Command] The command or application to parse.
|
243
|
+
# @param opts [Object] The current set options.
|
244
|
+
# @param option [Option] The option to set.
|
245
|
+
def parse_array(command, opts, option)
|
246
|
+
opts.on("#{option.complete_short} #{option.meta || command.i18n.help_arg}", "#{option.complete_long} #{option.meta || command.i18n.help_arg}", Array) do |value|
|
247
|
+
option.set(value.ensure_array)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
# Parses an action option.
|
252
|
+
#
|
253
|
+
# @param opts [Object] The current set options.
|
254
|
+
# @param option [Option] The option to set.
|
255
|
+
def parse_boolean(opts, option)
|
256
|
+
opts.on("-#{option.short}", "--#{option.long}") do |value|
|
257
|
+
option.set(value.to_boolean)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# Parses options of a command.
|
262
|
+
#
|
263
|
+
# @param parser [OptionParser] The option parser.
|
264
|
+
# @param command [Command] The command or application to parse.
|
265
|
+
# @param args [Array] The arguments to parse.
|
266
|
+
# @return [Command|nil] A command to execute or `nil` if no command was found.
|
267
|
+
def parse_options(parser, command, args)
|
268
|
+
rv = nil
|
269
|
+
|
270
|
+
# Parse options
|
271
|
+
parser.order!(args) do |arg|
|
272
|
+
fc = ::Mamertes::Parser.find_command(arg, command, args)
|
273
|
+
|
274
|
+
if fc.present? then
|
275
|
+
rv = fc
|
276
|
+
parser.terminate
|
277
|
+
else
|
278
|
+
command.argument(arg)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
rv
|
283
|
+
end
|
284
|
+
|
285
|
+
# Checks if all options of a command are present.
|
286
|
+
#
|
287
|
+
# @param command [Command] The command or application to parse.
|
288
|
+
def check_required_options(command)
|
289
|
+
# Check if any required option is missing.
|
290
|
+
command.options.each_pair do |name, option|
|
291
|
+
raise ::Mamertes::Error.new(option, :missing_option, command.i18n.missing_option(option.label)) if option.required && !option.provided?
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
# Finds a command to execute
|
296
|
+
#
|
297
|
+
# @param command [Command] The command or application to parse.
|
298
|
+
# @param args [Array] The arguments to parse.
|
299
|
+
# @return [Command|nil] A command to execute or `nil` if no command was found.
|
300
|
+
def find_command_to_execute(command, args)
|
301
|
+
rv = nil
|
302
|
+
|
303
|
+
# Try to find a command into the first argument
|
304
|
+
fc = ::Mamertes::Parser.find_command(args[0], command, args[1, args.length - 1])
|
305
|
+
|
306
|
+
if fc.present? then
|
307
|
+
rv = fc
|
308
|
+
else
|
309
|
+
args.each do |arg|
|
310
|
+
command.argument(arg)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
rv
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|