boson 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,8 @@
1
+ == 1.2.1
2
+ * Fix only option being invalid and not deleted
3
+ * Fix handling option parse errors in Runner
4
+ * Fix argument error handling for commands with optional args
5
+
1
6
  == 1.2.0
2
7
  * Add help subcommand for executables
3
8
  * Allow Runner help methods to be extended
data/README.md CHANGED
@@ -117,6 +117,9 @@ Now for pros thor has over boson. Thor
117
117
  * Change your requires and subclass from Boson::Runner instead of Thor.
118
118
  * Delete the first argument from `desc`. Usage is automatically created in boson.
119
119
  * Rename `method_option` to `option`
120
+ * For options with a type option, make sure it maps to a symbol i.e. :array or :boolean.
121
+ If left a string, the option will be interpreted to be a string option with that
122
+ string as a default.
120
123
  * `class_option` doesn't exist yet but you can emulate it for now by defining
121
124
  your class option in a class method and then calling your class method before
122
125
  every command. See [vimdb](http://github.com/cldwalker/vimdb) for an example.
@@ -58,8 +58,8 @@ module Boson
58
58
  def allowed_argument_error?(err, cmd, args)
59
59
  msg = RUBY_ENGINE == 'rbx' && err.class == ArgumentError ?
60
60
  /given \d+, expected \d+/ : /wrong number of arguments/
61
- (err.message[msg] && (cmd_obj = Command.find(cmd)) &&
62
- cmd_obj.arg_size != args.size)
61
+ err.message[msg] && (cmd_obj = Command.find(cmd)) &&
62
+ cmd_obj.incorrect_arg_size?(args)
63
63
  end
64
64
 
65
65
  def option_parser
@@ -136,6 +136,18 @@ module Boson
136
136
  !!(args && @args[-1] && @args[-1][0][/^\*/])
137
137
  end
138
138
 
139
+ # Indicates if arg size can handle a numerical comparison
140
+ def numerical_arg_size?
141
+ !has_splat_args? && arg_size
142
+ end
143
+
144
+ # Determines if incorrect # of args given i.e. too little or too much
145
+ def incorrect_arg_size?(args)
146
+ return false if has_splat_args?
147
+ required_arg_size = args.take_while {|e| e[1].nil? }.size
148
+ args.size < required_arg_size || args.size > arg_size
149
+ end
150
+
139
151
  # Number of arguments
140
152
  def arg_size
141
153
  unless instance_variable_defined?("@arg_size")
@@ -51,7 +51,7 @@ module Boson
51
51
  Boson.in_shell ? args = new_args : args += new_args
52
52
  # add default options
53
53
  elsif @command.options.nil? || @command.options.empty? ||
54
- (!@command.has_splat_args? && args.size <= (@command.arg_size - 1).abs) ||
54
+ (@command.numerical_arg_size? && args.size <= (@command.arg_size - 1).abs) ||
55
55
  (@command.has_splat_args? && !args[-1].is_a?(Hash))
56
56
  global_opt, parsed_options = parse_options([])[0,2]
57
57
  # merge default options with given hash of options
@@ -77,8 +77,8 @@ module Boson
77
77
 
78
78
  # modifies args for edge cases
79
79
  def modify_args(args)
80
- if @command.default_option && @command.arg_size <= 1 &&
81
- !@command.has_splat_args? &&
80
+ if @command.default_option && @command.numerical_arg_size? &&
81
+ @command.arg_size <= 1 &&
82
82
  !args[0].is_a?(Hash) && args[0].to_s[/./] != '-' && !args.join.empty?
83
83
  args[0] = "--#{@command.default_option}=#{args[0]}"
84
84
  end
@@ -86,7 +86,7 @@ module Boson
86
86
 
87
87
  # raises CommandArgumentError if argument size is incorrect for given args
88
88
  def check_argument_size(args)
89
- if args.size != @command.arg_size && !@command.has_splat_args?
89
+ if @command.numerical_arg_size? && args.size != @command.arg_size
90
90
  command_size, args_size = args.size > @command.arg_size ?
91
91
  [@command.arg_size, args.size] :
92
92
  [@command.arg_size - 1, args.size - 1]
@@ -97,7 +97,7 @@ module Boson
97
97
 
98
98
  # Adds default args as original method would
99
99
  def add_default_args(args, obj)
100
- if @command.args && args.size < @command.args.size - 1
100
+ if @command.args && args.size < @command.arg_size - 1
101
101
  # leave off last arg since its an option
102
102
  @command.args.slice(0..-2).each_with_index {|arr,i|
103
103
  next if args.size >= i + 1 # only fill in once args run out
@@ -118,6 +118,13 @@ module Boson
118
118
  trailing, unparseable = split_trailing
119
119
  global_options = parse_global_options @command.option_parser.leading_non_opts +
120
120
  trailing
121
+
122
+ # delete invalid options not deleted since no other options present
123
+ if @command.numerical_arg_size? &&
124
+ @command.option_parser.leading_non_opts.size > @command.arg_size - 1
125
+ option_parser.delete_leading_invalid_opts
126
+ end
127
+
121
128
  new_args = option_parser.non_opts.dup + unparseable
122
129
  [global_options, parsed_options, new_args]
123
130
  rescue OptionParser::Error
@@ -331,6 +331,10 @@ module Boson
331
331
  Hash.new {|hash,key| hash[key.to_sym] if String === key }
332
332
  end
333
333
 
334
+ def delete_leading_invalid_opts
335
+ delete_invalid_opts @leading_non_opts
336
+ end
337
+
334
338
  private
335
339
  def all_options_with_fields(fields)
336
340
  aliases = @opt_aliases.invert
@@ -417,9 +421,9 @@ module Boson
417
421
  send("validate_#{type}", peek) if respond_to?("validate_#{type}", true)
418
422
  end
419
423
 
420
- def delete_invalid_opts
424
+ def delete_invalid_opts(arr=@trailing_non_opts)
421
425
  stop = nil
422
- @trailing_non_opts.delete_if do |e|
426
+ arr.delete_if do |e|
423
427
  stop ||= STOP_STRINGS.include?(e)
424
428
  invalid = e.start_with?('-') && !stop
425
429
  warn "Deleted invalid option '#{e}'" if invalid
@@ -33,6 +33,8 @@ module Boson
33
33
 
34
34
  def self.execute_command(cmd, args, options)
35
35
  Command.find(cmd) ? super(cmd, args) : no_command_error(cmd)
36
+ rescue OptionParser::Error => err
37
+ abort_with err.message
36
38
  end
37
39
 
38
40
  def self.display_command_help(cmd)
@@ -1,3 +1,3 @@
1
1
  module Boson
2
- VERSION = '1.2.0'
2
+ VERSION = '1.2.1'
3
3
  end
@@ -17,7 +17,7 @@ class MyRunner < Boson::Runner
17
17
  end
18
18
 
19
19
  option :tags, :type => :array
20
- option :blurg, :type => :boolean
20
+ option :blurg, :type => :boolean, :required => true
21
21
  desc 'This is splot'
22
22
  def splot(*args)
23
23
  p args
@@ -36,6 +36,10 @@ class MyRunner < Boson::Runner
36
36
  def quiet
37
37
  end
38
38
 
39
+ def explode(arg=nil)
40
+ {}.update
41
+ end
42
+
39
43
  def boom
40
44
  nil.boom
41
45
  end
@@ -88,12 +92,13 @@ Usage: my_command [OPTIONS] COMMAND [ARGS]
88
92
  Available commands:
89
93
  boom
90
94
  broken
91
- help Displays help for a command
92
- medium This is a medium
93
- mini This is a mini
95
+ explode
96
+ help Displays help for a command
97
+ medium This is a medium
98
+ mini This is a mini
94
99
  quiet
95
- small This is a small
96
- splot This is splot
100
+ small This is a small
101
+ splot This is splot
97
102
  test
98
103
 
99
104
  Options:
@@ -176,6 +181,12 @@ STR
176
181
  my_command('medium 1 --spicy').chomp.should == '["1", {:spicy=>true}]'
177
182
  end
178
183
 
184
+ it "calls command with additional invalid option" do
185
+ capture_stderr {
186
+ my_command('medium 1 -z').chomp.should == '["1", {}]'
187
+ }.should == "Deleted invalid option '-z'\n"
188
+ end
189
+
179
190
  it "calls command with quoted arguments correctly" do
180
191
  my_command("medium '1 2'").chomp.should == '["1 2", {}]'
181
192
  end
@@ -199,6 +210,13 @@ STR
199
210
  Boson.in_shell = nil
200
211
  end
201
212
 
213
+ it "prints error for command with option parse error" do
214
+ MyRunner.expects(:abort).with <<-STR.chomp
215
+ my_command: no value provided for required option 'blurg'
216
+ STR
217
+ my_command('splot 1')
218
+ end
219
+
202
220
  it "executes custom global option" do
203
221
  # setup goes here to avoid coupling to other runner
204
222
  ExtendedRunner::GLOBAL_OPTIONS[:version] = {
@@ -226,10 +244,14 @@ STR
226
244
  assert_error(NoMethodError) { my_command('boom') }
227
245
  end
228
246
 
229
- it "allows no method error in command" do
247
+ it "allows argument error in command" do
230
248
  assert_error(ArgumentError) { my_command('broken') }
231
249
  end
232
250
 
251
+ it "allows argument error in command with optional args" do
252
+ assert_error(ArgumentError) { my_command('explode') }
253
+ end
254
+
233
255
  it "prints error message for private method" do
234
256
  MyRunner.expects(:abort).with %[my_command: Could not find command "no_run"]
235
257
  my_command('no_run').should == ''
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: boson
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-18 00:00:00.000000000 Z
12
+ date: 2012-03-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mocha
16
- requirement: &70095971880980 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: 0.10.4
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70095971880980
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.10.4
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: bacon
27
- requirement: &70095971880140 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: 1.1.0
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *70095971880140
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.1.0
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: mocha-on-bacon
38
- requirement: &70095971878980 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ! '>='
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: '0'
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *70095971878980
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: bacon-bits
49
- requirement: &70095971878240 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ! '>='
@@ -54,10 +69,15 @@ dependencies:
54
69
  version: '0'
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *70095971878240
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: bahia
60
- requirement: &70095971877400 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ! '>='
@@ -65,7 +85,12 @@ dependencies:
65
85
  version: 0.5.0
66
86
  type: :development
67
87
  prerelease: false
68
- version_requirements: *70095971877400
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 0.5.0
69
94
  description: Boson is a modular command/task framework. Thanks to its rich set of
70
95
  plugins, it differentiates itself from rake and thor by being usable from irb and
71
96
  the commandline, having optional automated views generated by hirb and allowing
@@ -140,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
165
  version: 1.3.6
141
166
  requirements: []
142
167
  rubyforge_project:
143
- rubygems_version: 1.8.11
168
+ rubygems_version: 1.8.19
144
169
  signing_key:
145
170
  specification_version: 3
146
171
  summary: A command/task framework similar to rake and thor that opens your ruby universe