mamertes 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|