bovem 3.0.5 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -3
  3. data/.rubocop.yml +82 -0
  4. data/.travis-gemfile +4 -5
  5. data/.travis.yml +8 -6
  6. data/CHANGELOG.md +12 -0
  7. data/Gemfile +9 -8
  8. data/README.md +1 -1
  9. data/Rakefile +22 -6
  10. data/bovem.gemspec +5 -5
  11. data/doc/Bovem.html +10 -10
  12. data/doc/Bovem/Application.html +670 -318
  13. data/doc/Bovem/Command.html +1447 -1125
  14. data/doc/Bovem/CommandMethods.html +4 -4
  15. data/doc/Bovem/CommandMethods/Children.html +173 -179
  16. data/doc/Bovem/CommandMethods/Help.html +9 -9
  17. data/doc/Bovem/Configuration.html +239 -24
  18. data/doc/Bovem/Console.html +267 -128
  19. data/doc/Bovem/ConsoleMethods.html +4 -4
  20. data/doc/Bovem/ConsoleMethods/Interactions.html +57 -70
  21. data/doc/Bovem/ConsoleMethods/Interactions/ClassMethods.html +9 -9
  22. data/doc/Bovem/ConsoleMethods/Logging.html +258 -298
  23. data/doc/Bovem/ConsoleMethods/Logging/ClassMethods.html +8 -8
  24. data/doc/Bovem/ConsoleMethods/Output.html +96 -118
  25. data/doc/Bovem/ConsoleMethods/StyleHandling.html +8 -8
  26. data/doc/Bovem/ConsoleMethods/StyleHandling/ClassMethods.html +26 -39
  27. data/doc/Bovem/Errors.html +4 -4
  28. data/doc/Bovem/Errors/Error.html +4 -4
  29. data/doc/Bovem/Errors/InvalidConfiguration.html +4 -4
  30. data/doc/Bovem/Errors/InvalidLogger.html +4 -4
  31. data/doc/Bovem/I18n.html +175 -0
  32. data/doc/Bovem/Logger.html +95 -83
  33. data/doc/Bovem/Option.html +669 -862
  34. data/doc/Bovem/Parser.html +10 -10
  35. data/doc/Bovem/ParserMethods.html +4 -4
  36. data/doc/Bovem/ParserMethods/General.html +4 -4
  37. data/doc/Bovem/ParserMethods/General/ClassMethods.html +26 -38
  38. data/doc/Bovem/Shell.html +169 -48
  39. data/doc/Bovem/ShellMethods.html +4 -4
  40. data/doc/Bovem/ShellMethods/Directories.html +46 -62
  41. data/doc/Bovem/ShellMethods/Execute.html +51 -99
  42. data/doc/Bovem/ShellMethods/General.html +4 -445
  43. data/doc/Bovem/ShellMethods/Read.html +56 -61
  44. data/doc/Bovem/ShellMethods/Write.html +22 -242
  45. data/doc/Bovem/Version.html +6 -6
  46. data/doc/_index.html +18 -18
  47. data/doc/class_list.html +6 -2
  48. data/doc/css/style.css +1 -0
  49. data/doc/file.README.html +5 -5
  50. data/doc/file_list.html +5 -1
  51. data/doc/frames.html +1 -1
  52. data/doc/index.html +5 -5
  53. data/doc/js/full_list.js +4 -1
  54. data/doc/method_list.html +161 -157
  55. data/doc/top-level-namespace.html +4 -4
  56. data/lib/bovem.rb +3 -4
  57. data/lib/bovem/application.rb +47 -39
  58. data/lib/bovem/command.rb +175 -193
  59. data/lib/bovem/configuration.rb +28 -29
  60. data/lib/bovem/console.rb +244 -171
  61. data/lib/bovem/errors.rb +1 -1
  62. data/lib/bovem/i18n.rb +18 -0
  63. data/lib/bovem/logger.rb +26 -26
  64. data/lib/bovem/option.rb +49 -58
  65. data/lib/bovem/parser.rb +174 -222
  66. data/lib/bovem/shell.rb +272 -320
  67. data/lib/bovem/version.rb +2 -2
  68. data/locales/en.yml +39 -38
  69. data/locales/it.yml +39 -38
  70. data/spec/bovem/application_spec.rb +6 -5
  71. data/spec/bovem/command_spec.rb +23 -23
  72. data/spec/bovem/console_spec.rb +101 -102
  73. data/spec/bovem/i18n_spec.rb +21 -0
  74. data/spec/bovem/logger_spec.rb +4 -4
  75. data/spec/bovem/option_spec.rb +43 -43
  76. data/spec/bovem/parser_spec.rb +13 -13
  77. data/spec/bovem/shell_spec.rb +106 -115
  78. data/spec/spec_helper.rb +19 -6
  79. metadata +14 -13
  80. data/doc/Bovem/Localizer.html +0 -376
  81. data/lib/bovem/localizer.rb +0 -27
  82. data/spec/coverage_helper.rb +0 -20
@@ -42,4 +42,4 @@ module Bovem
42
42
  end
43
43
  end
44
44
  end
45
- end
45
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This file is part of the bovem gem. Copyright (C) 2013 and above Shogun <shogun@cowtech.it>.
4
+ # Licensed under the MIT license, which can be found at http://www.opensource.org/licenses/mit-license.php.
5
+ #
6
+
7
+ module Bovem
8
+ # Extension of Lazier::I18n to support method based access.
9
+ class I18n < ::Lazier::I18n
10
+ private
11
+
12
+ def method_missing(method, *args)
13
+ rv = send(:t, method)
14
+ rv = sprintf(rv, *args) if rv.index(/%([\d.]*)[sdf]/) && args.present?
15
+ rv
16
+ end
17
+ end
18
+ end
@@ -12,6 +12,9 @@ module Bovem
12
12
  class Logger < ::Logger
13
13
  attr_reader :device
14
14
 
15
+ # List of valid logger levels.
16
+ LEVEL_NAMES = {"DEBUG" => :cyan, "INFO" => :green, "WARN" => :yellow, "ERROR" => :red, "FATAL" => :magenta}.freeze
17
+
15
18
  # Creates a new logger.
16
19
  #
17
20
  # @see http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html
@@ -19,7 +22,7 @@ module Bovem
19
22
  # @param logdev [String|IO] The log device. This is a filename (String) or IO object (typically STDOUT, STDERR, or an open file).
20
23
  # @param shift_age [Fixnum] Number of old log files to keep, or frequency of rotation (daily, weekly or monthly).
21
24
  # @param shift_size [Fixnum] Maximum logfile size (only applies when shift_age is a number).
22
- def initialize(logdev, shift_age = 0, shift_size = 1048576)
25
+ def initialize(logdev, shift_age = 0, shift_size = 1_048_576)
23
26
  @device = logdev
24
27
  super(logdev, shift_age, shift_size)
25
28
  end
@@ -30,15 +33,13 @@ module Bovem
30
33
  # @param level [Fixnum] The minimum severity to log. See http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html for valid levels.
31
34
  # @param formatter [Proc] The formatter to use for logging.
32
35
  # @return [Logger] The new logger.
33
- def self.create(file = nil, level = Logger::INFO, formatter = nil)
34
- begin
35
- rv = new(get_real_file(file || default_file))
36
- rv.level = level.to_integer
37
- rv.formatter = formatter || default_formatter
38
- rv
39
- rescue
40
- raise Bovem::Errors::InvalidLogger
41
- end
36
+ def self.create(file = nil, level: Logger::INFO, formatter: nil)
37
+ rv = new(get_real_file(file || default_file))
38
+ rv.level = level.to_integer
39
+ rv.formatter = formatter || default_formatter
40
+ rv
41
+ rescue
42
+ raise Bovem::Errors::InvalidLogger
42
43
  end
43
44
 
44
45
  # Translates a file to standard input or standard output in some special cases.
@@ -47,9 +48,9 @@ module Bovem
47
48
  # @return [String|IO] The translated file name.
48
49
  def self.get_real_file(file)
49
50
  case file
50
- when "STDOUT" then $stdout
51
- when "STDERR" then $stderr
52
- else file
51
+ when "STDOUT" then $stdout
52
+ when "STDERR" then $stderr
53
+ else file
53
54
  end
54
55
  end
55
56
 
@@ -62,19 +63,18 @@ module Bovem
62
63
  # The default formatter for logging.
63
64
  # @return [Proc] The default formatter for logging.
64
65
  def self.default_formatter
65
- @default_formatter ||= ::Proc.new {|severity, datetime, _, msg|
66
- color = case severity
67
- when "DEBUG" then :cyan
68
- when "INFO" then :green
69
- when "WARN" then :yellow
70
- when "ERROR" then :red
71
- when "FATAL" then :magenta
72
- else :white
73
- end
66
+ @default_formatter ||= ::Proc.new do |severity, datetime, _, msg|
67
+ color = LEVEL_NAMES.fetch(severity, :white)
74
68
 
75
- header = Bovem::Console.replace_markers("{mark=bright-#{color}}[%s T+%0.5f] %s:{/mark}" %[datetime.strftime("%Y/%b/%d %H:%M:%S"), [datetime.to_f - start_time.to_f, 0].max, severity.rjust(5)])
76
- "%s %s\n" % [header, msg]
77
- }
69
+ header = Bovem::Console.replace_markers(
70
+ sprintf(
71
+ "{mark=bright-#{color}}[%s T+%0.5f] %s:{/mark}", datetime.strftime("%Y/%b/%d %H:%M:%S"),
72
+ [datetime.to_f - start_time.to_f, 0].max, severity.rjust(5)
73
+ )
74
+ )
75
+
76
+ sprintf("%s %s\n", header, msg)
77
+ end
78
78
  end
79
79
 
80
80
  # The log time of the first logger. This allows to show a `T+0.1234` information into the log.
@@ -83,4 +83,4 @@ module Bovem
83
83
  @start_time ||= ::Time.now
84
84
  end
85
85
  end
86
- end
86
+ end
@@ -10,8 +10,7 @@ module Bovem
10
10
  # Values are the default values for that type.
11
11
  #
12
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, Fixnum => 0, Bignum => 0, Float => 0.0, Array => []}
14
- OPTION_TYPES.default = false
13
+ OPTION_TYPES = {String => "", Integer => 0, Fixnum => 0, Bignum => 0, Float => 0.0, Array => []}.freeze
15
14
 
16
15
  # This class represents an option for a command.
17
16
  #
@@ -71,7 +70,7 @@ module Bovem
71
70
  #
72
71
  # @param value [String] The short form of this option.
73
72
  def short=(value)
74
- value = @name[0, 1] if !value.present?
73
+ value = @name[0, 1] unless value.present?
75
74
 
76
75
  # Clean value
77
76
  final_value = value.to_s.match(/^-{0,2}([a-z0-9])(.*)$/i)[1]
@@ -83,7 +82,7 @@ module Bovem
83
82
  #
84
83
  # @param value [String] The short form of this option.
85
84
  def long=(value)
86
- value = @name if !value.present?
85
+ value = @name unless value.present?
87
86
 
88
87
  # Clean value
89
88
  final_value = value.to_s.match(/^-{0,2}(.+)$/)[1]
@@ -96,7 +95,7 @@ module Bovem
96
95
  # @param value [String] The validator of this option.
97
96
  def validator=(value)
98
97
  value = nil if value.blank? || (value.is_a?(Regexp) && value.source.blank?)
99
- value = value.ensure_array(nil, true, true, true) if !value.nil? && !value.is_a?(Regexp) && !value.is_a?(Proc)
98
+ value = value.ensure_array(no_duplicates: true, compact: true, flatten: true) if !value.nil? && !value.is_a?(Regexp) && !value.is_a?(Proc)
100
99
  @validator = value
101
100
  end
102
101
 
@@ -123,22 +122,24 @@ module Bovem
123
122
 
124
123
  # Returns the meta argument for this option.
125
124
  #
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.
125
+ # @return [String|NilClass] Returns the current meta argument for this option (the default value is the option name uppercased) or `nil`,
126
+ # if this option doesn't require a meta argument.
127
127
  def meta
128
- requires_argument? ? (@meta.present? ? @meta : @name.upcase) : nil
128
+ return nil unless requires_argument?
129
+ @meta.present? ? @meta : @name.upcase
129
130
  end
130
131
 
131
132
  # Get the current default value for this option.
132
133
  #
133
134
  # @return [Object] The default value for this option.
134
135
  def default
135
- @default || Bovem::OPTION_TYPES[@type]
136
+ @default || Bovem::OPTION_TYPES[@type] || false
136
137
  end
137
138
 
138
139
  # Check if the current option has a default value.
139
140
  #
140
141
  # @return [Boolean] If the current option has a default value.
141
- def has_default?
142
+ def default?
142
143
  !@default.nil?
143
144
  end
144
145
 
@@ -151,7 +152,7 @@ module Bovem
151
152
  vs = get_validator_method(@validator)
152
153
  rv = vs ? @validator.send(vs, value) : true
153
154
 
154
- if rv then
155
+ if rv
155
156
  @value = value
156
157
  @provided = true
157
158
  else # Validation failed
@@ -164,10 +165,9 @@ module Bovem
164
165
 
165
166
  # Executes the action associated to this option.
166
167
  def execute_action
167
- if @action.present? then
168
- @provided = true
169
- @action.call(parent, self)
170
- end
168
+ return nil unless @action.present?
169
+ @provided = true
170
+ @action.call(parent, self)
171
171
  end
172
172
 
173
173
  # Checks if this option requires an argument.
@@ -187,7 +187,7 @@ module Bovem
187
187
  # Check if this command has a help.
188
188
  #
189
189
  # @return [Boolean] `true` if this command has a help, `false` otherwise.
190
- def has_help?
190
+ def help?
191
191
  @help.present?
192
192
  end
193
193
 
@@ -199,56 +199,47 @@ module Bovem
199
199
  end
200
200
 
201
201
  private
202
- # Setups the forms of the this option.
203
- #
204
- # @param forms [Array] An array of short and long forms for this option. Missing forms will be inferred by the name.
205
- def setup_forms(forms)
206
- self.short = forms.length > 0 ? forms[0] : @name[0, 1]
207
- self.long = forms.length == 2 ? forms[1] : @name
208
- end
209
202
 
210
- # Setups the settings of the this option.
211
- #
212
- # @param options [Hash] The settings for this option.
213
- def setup_options(options)
214
- (options.is_a?(::Hash) ? options : {}).each_pair do |option, value|
215
- send("#{option}=", value) if respond_to?("#{option}=")
216
- end
217
- end
203
+ # :nodoc:
204
+ def setup_forms(forms)
205
+ self.short = !forms.empty? ? forms[0] : @name[0, 1]
206
+ self.long = forms.length == 2 ? forms[1] : @name
207
+ end
218
208
 
219
- # Setups the action of the this option.
220
- #
221
- # @param action [Proc] The action of this option.
222
- def setup_action(action)
223
- @action = action if action.present? && action.respond_to?(:call) && action.try(:arity) == 2
209
+ # :nodoc:
210
+ def setup_options(options)
211
+ (options.is_a?(::Hash) ? options : {}).each_pair do |option, value|
212
+ send("#{option}=", value) if respond_to?("#{option}=")
224
213
  end
214
+ end
225
215
 
226
- # Handle failure in setting an option.
227
- #
228
- # @param vs [Symbol] The type of validator.
229
- def handle_set_failure(vs)
230
- locale = @parent.i18n
216
+ # :nodoc:
217
+ def setup_action(action)
218
+ @action = action if action.present? && action.respond_to?(:call) && action.try(:arity) == 2
219
+ end
220
+
221
+ # :nodoc:
222
+ def handle_set_failure(vs)
223
+ locale = @parent.i18n
231
224
 
232
- message = case vs
233
- when "match" then locale.invalid_for_regexp(label, @validator.inspect)
234
- when "call" then locale.invalid_for_proc(label)
235
- else locale.invalid_value(label, Bovem::Parser.smart_join(@validator.ensure_array, ", ", locale.join_separator).html_safe)
225
+ message =
226
+ case vs
227
+ when "match" then locale.invalid_for_regexp(label, @validator.inspect)
228
+ when "call" then locale.invalid_for_proc(label)
229
+ else locale.invalid_value(label, Bovem::Parser.smart_join(@validator.ensure_array, separator: ", ", last_separator: locale.join_separator).html_safe)
236
230
  end
237
231
 
238
- raise Bovem::Errors::Error.new(self, :validation_failed, message)
239
- end
232
+ raise Bovem::Errors::Error.new(self, :validation_failed, message)
233
+ end
240
234
 
241
- # Gets the method required to verify a validator.
242
- #
243
- # @param validator [Object] The type of the validator.
244
- # @return [String] A method to call to verify the validator.
245
- def get_validator_method(validator)
246
- case validator.class.to_s
247
- when "Array" then "include?"
248
- when "Regexp" then "match"
249
- when "Proc" then "call"
250
- else false
251
- end
235
+ # :nodoc:
236
+ def get_validator_method(validator)
237
+ case validator.class.to_s
238
+ when "Array" then "include?"
239
+ when "Regexp" then "match"
240
+ when "Proc" then "call"
241
+ else false
252
242
  end
243
+ end
253
244
  end
254
- end
245
+ end
@@ -20,11 +20,11 @@ module Bovem
20
20
  # @param last_separator [String] The separator to use for the last join.
21
21
  # @param quote [String] If not nil, elements are quoted with that element.
22
22
  # @return [String] The joined array.
23
- def smart_join(array, separator = ", ", last_separator = " and ", quote = "\"")
23
+ def smart_join(array, separator: ", ", last_separator: " and ", quote: "\"")
24
24
  separator = separator.ensure_string
25
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])
26
+ array = array.ensure_array { |a| quote.present? ? "#{quote}#{a}#{quote}" : a.ensure_string }
27
+ perform_smart_join(array, last_separator, separator)
28
28
  end
29
29
 
30
30
  # Finds a command which corresponds to an argument.
@@ -34,18 +34,16 @@ module Bovem
34
34
  # @param args [String] The complete list of arguments passed.
35
35
  # @param separator [String] The separator for joined syntax commands.
36
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
- if command.commands.present? then
39
- arg, args = adjust_command(arg, args, separator)
40
-
41
- matching = match_subcommands(arg, command)
42
- if matching.length == 1 # Found a command
43
- {name: matching[0], args: args}
44
- elsif matching.length > 1 # Ambiguous match
45
- raise Bovem::Errors::Error.new(command, :ambiguous_command, command.i18n.ambigous_command(arg, format_alternatives(matching, command)))
46
- end
47
- else
48
- nil
37
+ def find_command(arg, command, args: {}, separator: ":")
38
+ return nil unless command.commands.present?
39
+
40
+ arg, args = adjust_command(arg, args, separator)
41
+
42
+ matching = match_subcommands(arg, command)
43
+ if matching.length == 1 # Found a command
44
+ {name: matching[0], args: args}
45
+ elsif matching.length > 1 # Ambiguous match
46
+ raise Bovem::Errors::Error.new(command, :ambiguous_command, command.i18n.ambigous_command(arg, format_alternatives(matching, command)))
49
47
  end
50
48
  end
51
49
 
@@ -59,41 +57,34 @@ module Bovem
59
57
  end
60
58
 
61
59
  private
62
- # Adjusts a command so that it only specify a single command.
63
- #
64
- # @param arg [String] The string to match.
65
- # @param args [String] The complete list of arguments passed.
66
- # @param separator [String] The separator for joined syntax commands.
67
- # @return [Array] Adjust command and arguments.
68
- def adjust_command(arg, args, separator)
69
- args = args.ensure_array.dup
70
-
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
60
 
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
61
+ # :nodoc:
62
+ def adjust_command(arg, args, separator)
63
+ args = args.ensure_array.dup
88
64
 
89
- # Formats alternatives for printing.
90
- #
91
- # @param matching [Array] The alternatives to format.
92
- # @param command [Command] The command which alternatives refers to.
93
- # @return [String] The formatted alternatives.
94
- def format_alternatives(matching, command)
95
- Bovem::Parser.smart_join(matching, ", ", command.i18n.join_separator).html_safe
65
+ if arg.index(separator)
66
+ tokens = arg.split(separator, 2)
67
+ arg = tokens[0]
68
+ args.insert(0, tokens[1])
96
69
  end
70
+
71
+ [arg, args]
72
+ end
73
+
74
+ # :nodoc:
75
+ def match_subcommands(arg, command)
76
+ command.commands.keys.select { |c| c =~ /^(#{Regexp.quote(arg)})/ }.compact
77
+ end
78
+
79
+ # :nodoc:
80
+ def format_alternatives(matching, command)
81
+ Bovem::Parser.smart_join(matching, separator: ", ", last_separator: command.i18n.join_separator).html_safe
82
+ end
83
+
84
+ # :nodoc:
85
+ def perform_smart_join(array, last_separator, separator)
86
+ array.length < 2 ? (array[0] || "") : (array[0, array.length - 1].join(separator) + last_separator + array[-1])
87
+ end
97
88
  end
98
89
  end
99
90
  end
@@ -114,213 +105,174 @@ module Bovem
114
105
  end
115
106
 
116
107
  private
117
- # Creates a new option parser.
118
- #
119
- # @param command [Command] The command or application to parse.
120
- # @return [OptionParser] The new parser
121
- def create_parser(command)
122
- forms = {}
123
- parser = OptionParser.new do |opts|
124
- # Add every option
125
- command.options.each_pair do |_, option|
126
- check_unique(command, forms, option)
127
- setup_option(command, opts, option)
128
- end
129
- end
130
108
 
131
- [forms, parser]
109
+ # :nodoc:
110
+ def create_parser(command)
111
+ forms = {}
112
+ parser = OptionParser.new do |opts|
113
+ # Add every option
114
+ command.options.each_pair do |_, option|
115
+ check_unique(command, forms, option)
116
+ setup_option(command, opts, option)
117
+ end
132
118
  end
133
119
 
134
- # Perform the parsing
135
- #
136
- # @param parser [OptionParser] The option parser.
137
- # @param command [Command] The command or application to parse.
138
- # @param args [Array] The arguments to parse.
139
- # @param forms [Hash] The current forms.
140
- def perform_parsing(parser, command, args, forms)
141
- rv = nil
142
-
143
- begin
144
- rv = execute_parsing(parser, command, args)
145
- rescue OptionParser::NeedlessArgument, OptionParser::MissingArgument, OptionParser::InvalidOption => oe
146
- type = oe.class.to_s.gsub("OptionParser::", "").underscore.to_sym
147
- opt = oe.args.first
148
- raise Bovem::Errors::Error.new(forms[opt], type, command.i18n.send(type, opt))
149
- rescue => e
150
- raise e
151
- end
120
+ [forms, parser]
121
+ end
122
+
123
+ # :nodoc:
124
+ def perform_parsing(parser, command, args, forms)
125
+ rv = nil
152
126
 
153
- rv
127
+ begin
128
+ rv = execute_parsing(parser, command, args)
129
+ rescue OptionParser::NeedlessArgument, OptionParser::MissingArgument, OptionParser::InvalidOption => e
130
+ fail_invalid_option(command, forms, e)
131
+ rescue => e
132
+ raise e
154
133
  end
155
134
 
156
- # Executes the parsing.
157
- #
158
- # @param parser [OptionParser] The option parser.
159
- # @param command [Command] The command or application to parse.
160
- # @param args [Array] The arguments to parse.
161
- # @return [Command|nil] A command to execute or `nil` if no valid command was found.
162
- def execute_parsing(parser, command, args)
163
- rv = nil
164
-
165
- if command.options.present? then
166
- rv = parse_options(parser, command, args)
167
- check_required_options(command)
168
- elsif args.present? then
169
- rv = find_command_to_execute(command, args)
170
- end
135
+ rv
136
+ end
171
137
 
172
- rv
173
- end
138
+ # :nodoc:
139
+ def fail_invalid_option(command, forms, oe)
140
+ type = oe.class.to_s.gsub("OptionParser::", "").underscore.to_sym
141
+ opt = oe.args.first
142
+ raise Bovem::Errors::Error.new(forms[opt], type, command.i18n.send(type, opt))
143
+ end
174
144
 
175
- # Setups an option for a command.
176
- #
177
- # @param command [Command] The command or application to parse.
178
- # @param opts [Object] The current set options.
179
- # @param option [Option] The option to set.
180
- def setup_option(command, opts, option)
181
- case option.type.to_s
182
- when "String" then parse_string(command, opts, option)
183
- when "Integer", "Fixnum", "Bignum" then parse_number(command, opts, option, :is_integer?, :to_integer, command.i18n.invalid_integer(option.label))
184
- when "Float" then parse_number(command, opts, option, :is_float?, :to_float, command.i18n.invalid_float(option.label))
185
- when "Array" then parse_array(command, opts, option)
186
- else option.action.present? ? parse_action(opts, option) : parse_boolean(opts, option)
187
- end
188
- end
145
+ # :nodoc:
146
+ def execute_parsing(parser, command, args)
147
+ rv = nil
189
148
 
190
- # Checks if a option is unique.
191
- #
192
- # @param command [Command] The command or application to parse.
193
- # @param forms [Hash] The current forms.
194
- # @param option [Option] The option to set.
195
- def check_unique(command, forms, option)
196
- if forms[option.complete_short] || forms[option.complete_long] then
197
- raise Bovem::Errors::Error.new(command, :ambiguous_form, command.i18n.conflicting_options(option.label, forms[option.complete_short].label))
198
- else
199
- forms[option.complete_short] = option.dup
200
- forms[option.complete_long] = option.dup
201
- end
149
+ if command.options.present?
150
+ rv = parse_options(parser, command, args)
151
+ check_required_options(command)
152
+ elsif args.present?
153
+ rv = find_command_to_execute(command, args)
202
154
  end
203
155
 
204
- # Parses an action option. A block must be provided to deal with the value.
205
- #
206
- # @param command [Command] The command or application to parse.
207
- # @param opts [Object] The current set options.
208
- # @param option [Option] The option to set.
209
- def parse_option(command, opts, option)
210
- opts.on("#{option.complete_short} #{option.meta || command.i18n.help_arg}", "#{option.complete_long} #{option.meta || command.i18n.help_arg}") do |value|
211
- yield(value)
212
- end
213
- end
156
+ rv
157
+ end
214
158
 
215
- # Parses an action option.
216
- #
217
- # @param opts [Object] The current set options.
218
- # @param option [Option] The option to set.
219
- def parse_action(opts, option)
220
- opts.on("-#{option.short}", "--#{option.long}") do |_|
221
- option.execute_action
222
- end
159
+ # :nodoc:
160
+ def setup_option(command, opts, option)
161
+ case option.type.to_s
162
+ when "String" then parse_string(command, opts, option)
163
+ when "Integer", "Fixnum", "Bignum" then setup_int_option(command, option, opts)
164
+ when "Float" then parse_number(command, opts, option, :float?, :to_float, command.i18n.invalid_float(option.label))
165
+ when "Array" then parse_array(command, opts, option)
166
+ else option.action.present? ? parse_action(opts, option) : parse_boolean(opts, option)
223
167
  end
168
+ end
169
+
170
+ # :nodoc:
171
+ def setup_int_option(command, option, opts)
172
+ parse_number(command, opts, option, :integer?, :to_integer, command.i18n.invalid_integer(option.label))
173
+ end
224
174
 
225
- # Parses a string 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
- def parse_string(command, opts, option)
231
- parse_option(command, opts, option) { |value| option.set(value) }
175
+ # :nodoc:
176
+ def check_unique(command, forms, option)
177
+ if forms[option.complete_short] || forms[option.complete_long]
178
+ fail_non_unique_option(command, forms, option)
179
+ else
180
+ forms[option.complete_short] = option.dup
181
+ forms[option.complete_long] = option.dup
232
182
  end
183
+ end
233
184
 
234
- # Parses a number option.
235
- #
236
- # @param command [Command] The command or application to parse.
237
- # @param opts [Object] The current set options.
238
- # @param option [Option] The option to set.
239
- # @param check_method [Symbol] The method to execute to check option validity. Must return a boolean.
240
- # @param convert_method [Symbol] The method to execute to convert option.
241
- # @param invalid_message [String] The string to send in case of invalid arguments.
242
- def parse_number(command, opts, option, check_method, convert_method, invalid_message)
243
- parse_option(command, opts, option) do |value|
244
- raise Bovem::Errors::Error.new(option, :invalid_argument, invalid_message) if !value.send(check_method)
245
- option.set(value.send(convert_method))
246
- end
185
+ # :nodoc:
186
+ def fail_non_unique_option(command, forms, option)
187
+ raise Bovem::Errors::Error.new(command, :ambiguous_form, command.i18n.conflicting_options(option.label, forms[option.complete_short].label))
188
+ end
189
+
190
+ # :nodoc:
191
+ def parse_option(command, opts, option)
192
+ opts.on("#{option.complete_short} #{option.meta || command.i18n.help_arg}", "#{option.complete_long} #{option.meta || command.i18n.help_arg}") do |value|
193
+ yield(value)
247
194
  end
195
+ end
248
196
 
249
- # Parses an array option.
250
- #
251
- # @param command [Command] The command or application to parse.
252
- # @param opts [Object] The current set options.
253
- # @param option [Option] The option to set.
254
- def parse_array(command, opts, option)
255
- opts.on("#{option.complete_short} #{option.meta || command.i18n.help_arg}", "#{option.complete_long} #{option.meta || command.i18n.help_arg}", Array) do |value|
256
- option.set(value.ensure_array)
257
- end
197
+ # :nodoc:
198
+ def parse_action(opts, option)
199
+ opts.on("-#{option.short}", "--#{option.long}") do |_|
200
+ option.execute_action
258
201
  end
202
+ end
259
203
 
260
- # Parses an action option.
261
- #
262
- # @param opts [Object] The current set options.
263
- # @param option [Option] The option to set.
264
- def parse_boolean(opts, option)
265
- opts.on("-#{option.short}", "--#{option.long}") do |value|
266
- option.set(value.to_boolean)
267
- end
204
+ # :nodoc:
205
+ def parse_string(command, opts, option)
206
+ parse_option(command, opts, option) { |value| option.set(value) }
207
+ end
208
+
209
+ # :nodoc:
210
+ def parse_number(command, opts, option, check_method, convert_method, invalid_message)
211
+ parse_option(command, opts, option) do |value|
212
+ raise Bovem::Errors::Error.new(option, :invalid_argument, invalid_message) unless value.send(check_method)
213
+ option.set(value.send(convert_method))
268
214
  end
215
+ end
269
216
 
270
- # Parses options of a command.
271
- #
272
- # @param parser [OptionParser] The option parser.
273
- # @param command [Command] The command or application to parse.
274
- # @param args [Array] The arguments to parse.
275
- # @return [Command|nil] A command to execute or `nil` if no command was found.
276
- def parse_options(parser, command, args)
277
- rv = nil
278
-
279
- # Parse options
280
- parser.order!(args) do |arg|
281
- fc = Bovem::Parser.find_command(arg, command, args)
282
-
283
- if fc.present? then
284
- rv = fc
285
- parser.terminate
286
- else
287
- command.argument(arg)
288
- end
289
- end
217
+ # :nodoc:
218
+ def parse_array(command, opts, option)
219
+ meta = option.meta || command.i18n.help_arg
290
220
 
291
- rv
221
+ opts.on("#{option.complete_short} #{meta}", "#{option.complete_long} #{meta}", Array) do |value|
222
+ option.set(value.ensure_array)
292
223
  end
224
+ end
293
225
 
294
- # Checks if all options of a command are present.
295
- #
296
- # @param command [Command] The command or application to parse.
297
- def check_required_options(command)
298
- # Check if any required option is missing.
299
- command.options.each_pair do |name, option|
300
- raise Bovem::Errors::Error.new(option, :missing_option, command.i18n.missing_option(option.label)) if option.required && !option.provided?
301
- end
226
+ # :nodoc:
227
+ def parse_boolean(opts, option)
228
+ opts.on("-#{option.short}", "--#{option.long}") do |value|
229
+ option.set(value.to_boolean)
302
230
  end
231
+ end
303
232
 
304
- # Finds a command to execute
305
- #
306
- # @param command [Command] The command or application to parse.
307
- # @param args [Array] The arguments to parse.
308
- # @return [Command|nil] A command to execute or `nil` if no command was found.
309
- def find_command_to_execute(command, args)
310
- rv = nil
233
+ # :nodoc:
234
+ def parse_options(parser, command, args)
235
+ rv = nil
311
236
 
312
- # Try to find a command into the first argument
313
- fc = Bovem::Parser.find_command(args[0], command, args[1, args.length - 1])
237
+ # Parse options
238
+ parser.order!(args) do |arg|
239
+ fc = Bovem::Parser.find_command(arg, command, args: args)
314
240
 
315
- if fc.present? then
241
+ if fc.present?
316
242
  rv = fc
243
+ parser.terminate
317
244
  else
318
- args.each do |arg|
319
- command.argument(arg)
320
- end
245
+ command.argument(arg)
321
246
  end
247
+ end
248
+
249
+ rv
250
+ end
322
251
 
323
- rv
252
+ # :nodoc:
253
+ def check_required_options(command)
254
+ # Check if any required option is missing.
255
+ command.options.each_pair do |_, option|
256
+ raise Bovem::Errors::Error.new(option, :missing_option, command.i18n.missing_option(option.label)) if option.required && !option.provided?
324
257
  end
258
+ end
259
+
260
+ # :nodoc:
261
+ def find_command_to_execute(command, args)
262
+ rv = nil
263
+
264
+ # Try to find a command into the first argument
265
+ fc = Bovem::Parser.find_command(args[0], command, args: args[1, args.length - 1])
266
+
267
+ if fc.present?
268
+ rv = fc
269
+ else
270
+ args.each do |arg|
271
+ command.argument(arg)
272
+ end
273
+ end
274
+
275
+ rv
276
+ end
325
277
  end
326
- end
278
+ end