bovem 3.0.5 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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