optout 0.0.1 → 0.0.2

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 (4) hide show
  1. data/README.rdoc +31 -8
  2. data/lib/optout.rb +238 -62
  3. data/spec/optout_spec.rb +369 -217
  4. metadata +9 -9
@@ -20,7 +20,7 @@ arguments and define validation rules that must be met before the command line a
20
20
  :gem => "rake",
21
21
  :os => "mswin",
22
22
  :version => "0.9.2",
23
- :user => true
23
+ :user => truep
24
24
  }
25
25
 
26
26
  exec "gem", *optout.argv(options)
@@ -68,13 +68,30 @@ in a different format. +Optout+ accepts various configuration options that can r
68
68
  optout = Optout.options do
69
69
  on :path, "--path", :arg_separator => "=", :required => true
70
70
  end
71
-
71
+
72
72
  optout.shell(:path => "/home/sshaw")
73
73
  # Returns: --path='/home/sshaw'
74
74
 
75
75
  optout.shell({})
76
76
  # Raises: Optout::OptionRequired
77
77
 
78
+ Options can be grouped into required and optional:
79
+
80
+ Optout.options :arg_separator => "=" do
81
+ required do
82
+ on :in, "if"
83
+ on :out, "of"
84
+ end
85
+
86
+ optional do
87
+ on :size, "size"
88
+ on :count, "count"
89
+ end
90
+ end
91
+
92
+ optout.shell(:in => "/dev/zero", :out => "/var/log/secure")
93
+ # Returns: in='/dev/zero' out='/var/log/secure'
94
+
78
95
  == Validating Options
79
96
 
80
97
  +Optout+ can validate your options too. Just specify the validation rule after the option's key or switch:
@@ -85,7 +102,7 @@ in a different format. +Optout+ accepts various configuration options that can r
85
102
  end
86
103
 
87
104
  optout = Optout.options do
88
- # Must be true, false, or nil
105
+ # Must be true, false, or nil (add :required => true to allow only true or false)
89
106
  on :path, "-p", Optout::Boolean
90
107
  end
91
108
 
@@ -95,20 +112,24 @@ in a different format. +Optout+ accepts various configuration options that can r
95
112
  end
96
113
 
97
114
  optout = Optout.options do
98
- # Must be a diretory under "/sshaw" and have user write permission
99
- on :path, Optout::Dir.under("/home").permissions("w")
115
+ # Must be a diretory under "/home" and have user read and write permissions
116
+ on :path, Optout::Dir.under("/home").permissions("rw")
100
117
  end
101
118
 
102
119
  optout.shell(:path => "/root")
103
120
  # Raises: Optout::OptionInvalid
104
121
 
105
- There are plenty of other features, see {the RDoc}[http://rubydoc.info/github/sshaw/optout/frames].
122
+ == TODOs
123
+
124
+ * Proper <code>cmd.exe</code> quoting
125
+ * Mutually exclusive options
126
+ * Split options i.e., <code>:jvm => %w[A B C]</code> would be created as <code>-XA -XB -XC</code>
106
127
 
107
128
  == More Info
108
129
 
109
130
  === RDoc
110
131
 
111
- http://rubydoc.info/github/sshaw/optout/frames
132
+ http://rubydoc.info/github/sshaw/optout/frames (with RDoc -> YARD incompatibilities :)
112
133
 
113
134
  === Bugs
114
135
 
@@ -120,4 +141,6 @@ Skye Shaw [sshaw AT lucas.cis.temple.edu]
120
141
 
121
142
  == License
122
143
 
123
- Released under the MIT License: http://www.opensource.org/licenses/MIT
144
+ Copyright (c) 2011-2012 Skye Shaw
145
+
146
+ Released under the MIT License: http://www.opensource.org/licenses/MIT
@@ -2,7 +2,7 @@ require "rbconfig"
2
2
  require "pathname"
3
3
 
4
4
  class Optout
5
- VERSION = "0.0.1"
5
+ VERSION = "0.0.2"
6
6
 
7
7
  class OptionError < StandardError
8
8
  attr :key
@@ -32,20 +32,26 @@ class Optout
32
32
 
33
33
  class << self
34
34
  ##
35
- # Define a set of options to validate and create.
35
+ # Define a set of options.
36
+ # After the options are defined call Optout#argv or Optout#shell to create them.
37
+ #
38
+ # optz = Optout.options config do
39
+ # on :key, "-switch", ValidationRule, :multiple => false, :required => true
40
+ # # ...
41
+ # end
36
42
  #
37
43
  # === Parameters
38
44
  #
39
45
  # [config (Hash)] Configuration options
40
- # [definition (Proc)] Option definitions
46
+ # [block (Proc)] Option definitions
41
47
  #
42
48
  # === Configuration Options
43
49
  #
44
- # [:arg_separator] Set the default for all subsequent options defined via +on+. See Optout#on@Options.
45
- # [:check_keys] If +true+ an <code>Optout::OptionUnknown</code> error will be raised when the incoming option hash contains a key that has not been associated with an option.
50
+ # [:arg_separator] Set the default argument seperator (i.e., the char used to seperate a switch from its value) for all subsequent options defined via Optout#on.
51
+ # [:check_keys] If +true+ an +OptionUnknown+ error will be raised when the incoming option hash contains a key that has not been associated with an option via Optout#on.
46
52
  # Defaults to +true+.
47
- # [:multiple] Set the default for all subsequent options defined via +on+. See Optout#on@Options.
48
- # [:required] Set the default for all subsequent options defined via +on+. See Optout#on@Options.
53
+ # [:multiple] Set the default for all subsequent options defined via +on+. See Optout#on.
54
+ # [:required] Set the default for all subsequent options defined via +on+. See Optout#on.
49
55
  #
50
56
  # === Errors
51
57
  #
@@ -59,20 +65,20 @@ class Optout
59
65
  # on :file, Optout::File.under("/home/sshaw"), :default => "/home/sshaw/tmp"
60
66
  # end
61
67
  #
62
- # optz.shell(:all => true, :size => 1024, :file => "/home/sshaw/some file")
63
- # # Creates: "-a -b '1024' '/home/sshaw/some file'
64
- #
65
68
  # optz = Optout.options :required => true, :check_keys => false do
66
- # on :lib, :index => 2
69
+ # on :lib
67
70
  # on :prefix, "--prefix" , %w{/sshaw/lib /sshaw/usr/lib}, :arg_separator => "="
68
71
  # end
69
72
  #
70
- # optz.argv(:lib => "libssl2",
71
- # :prefix => "/sshaw/usr/lib",
72
- # :bad_key => "No error raised because of moi")
73
- # # Creates: ["--prefix='/sshaw/usr/lib'", "libssl2"]
73
+ # # Same as above
74
+ # optz = Optout.options :check_keys => false do
75
+ # required do
76
+ # on :lib
77
+ # on :prefix, "--prefix" , %w{/sshaw/lib /sshaw/usr/lib}, :arg_separator => "="
78
+ # end
79
+ # end
74
80
  #
75
-
81
+
76
82
  def options(config = {}, &block)
77
83
  optout = new(config)
78
84
  optout.instance_eval(&block) if block_given?
@@ -85,7 +91,8 @@ class Optout
85
91
  def initialize(args = {})
86
92
  @options = {}
87
93
  @check_keys = args.include?(:check_keys) ? args[:check_keys] : true
88
- #@opt_seperator = args[:opt_seperator]
94
+ @required_context = option_context(:required => true)
95
+ @optional_context = option_context(:required => false)
89
96
  @default_opt_options = {
90
97
  :required => args[:required],
91
98
  :multiple => args[:multiple],
@@ -98,45 +105,103 @@ class Optout
98
105
  #
99
106
  # === Parameters
100
107
  #
101
- # [key (Symbol)] The key of the option in the option hash that will passed to +shell+ or +argv+.
108
+ # [key (Symbol)] The key of the option in the option hash passed to +shell+ or +argv+.
102
109
  # [switch (String)] Optional. The option's command line switch. If no switch is given only the option's value is output.
103
- # [rule (Object)] Optional. Validation rule, see {Validating}[rdoc-ref:#on@Validating].
104
- # [options (Hash)] Additional option configuration, see {Options}[rdoc-ref:#on@Options].
110
+ # [rule (Object)] Optional. Validation rule, see Optout#on@Validating.
111
+ # [options (Hash)] Additional option configuration, see Optout#on@Options.
105
112
  #
106
113
  # === Options
107
114
  #
108
- # [:arg_separator] The +String+ used to separate the option's switch from its value. Defaults to <code>" "</code> (space).
115
+ # [:arg_separator] The +String+ used to separate the option's switch from its value. Defaults to <code>" "</code> (space). This can be set globally via Optout::options.
109
116
  # [:default] The option's default value. This will be used if the option is +nil+ or +empty?+.
110
- # [:index] The index of the option in the resulting +String+ or +Array+.
111
- # [:multiple] If +true+ the option will accept multiple values. If +false+ an <code>Optout::OptionInvalid</code> error will be raised if the option
112
- # contains multiple values. If +true+ multiple values are joined on a comma, you can set this to a +String+
113
- # to join on that string instead. Defaults to +false+.
114
- # [:required] If +true+ the option must contian a value i.e., it must not be +false+ or +nil+ else an <code>Optout::OptionRequired</code> error will be raised.
115
- # Defaults to +false+.
116
- # [:validator] An additional validation rule, see Validating.
117
+ # [:multiple] If +true+ the option will accept multiple values. If +false+ an <code>Optout::OptionInvalid</code> error will be raised if the option contains multiple values. By default multiple values are joined on a comma, you can set this to a +String+ to join on that string instead. Defaults to +false+. This can be set globally via Optout::options.
118
+ # [:required] If +true+ the option must contian a value i.e., it must not be +false+ or +nil+ otherwise an <code>Optout::OptionRequired</code> exception will be raised.
119
+ # Defaults to +false+. This can be set globally via Optout::options or for a set of options via Optout#required or Optout#optional.
120
+ #
121
+ # === Errors
122
+ #
123
+ # [ArgumentError] An +ArgumentError+ is raised if +key+ is +nil+ or has already been defined
117
124
  #
118
125
  # === Validating
119
126
  #
120
- # A Validator will only be applied if there's a value. If the option is required pass <code>:required => true</code>
121
- # to +on+ when defining the option. Validation rules can be in one of the following forms:
127
+ # An option's value can be restricted by a validation rule. If validation fails an Optout::OptionInvalid exception is raised.
122
128
  #
123
- # [Regular Expresion] A pattern to match the option's value against.
124
- # [An Array] Restrict the option's value(s) to item(s) contained in the given array.
125
- # [Class] Restrict the option's value to instances of the given class.
126
- # [Optout::Boolean] Restrict the option's value to something boolean, i.e., +true+, +false+, or +nil+.
127
- # [Optout::File] The option's value must be a file. Note that the file does not have to exist. <code>Optout::File</code> has several methods that can be used to tune validation, see Optout::File.
128
- # [Optout::Dir] The option's value must be a directory. <code>Optout::Dir</code> has several methods that can be used to tune validation, see Optout::Dir.
129
- #
130
- # === Errors
129
+ # Validation rules will only be applied if the option hash contains a non-nil value for the given option's key.
130
+ # If the option is required you must either define it in a Optout#required block or set the +:required+ option to +true+ when calling Optout#on.
131
131
  #
132
- # [ArgumentError] An +ArgumentError+ is raised if +key+ is +nil+ or +key+ has already been defined
133
-
132
+ # Validation rules can be in one of the following forms:
133
+ #
134
+ # ==== Regex
135
+ #
136
+ # A pattern to match the option's value against.
137
+ #
138
+ # on :key, /\d+/
139
+ # on :key, "-switch", /\d+/
140
+ #
141
+ # ==== Array
142
+ #
143
+ # Only accept value(s) contained in the given array.
144
+ #
145
+ # on :key, %w(item_a item_b item_c)
146
+ # on :key, "-switch", %w(item_a item_b item_c)
147
+ #
148
+ # ==== Class
149
+ #
150
+ # Must be an instance of the given class.
151
+ #
152
+ # on :key, Fixnum
153
+ # on :key, "-switch", Fixnum
154
+ #
155
+ # ==== Optout::Boolean
156
+ #
157
+ # Must be +true+ or +false+.
158
+ #
159
+ # on :key, Optout::Boolean
160
+ # on :key, "-switch", Optout::Boolean
161
+ #
162
+ # ==== Optout::File
163
+ #
164
+ # Must be a file. Note that the file does not have to exist.
165
+ #
166
+ # on :key, Optout::File
167
+ # on :key, "-switch", Optout::File
168
+ #
169
+ # <code>Optout::File</code> has several methods that can be used to tune validation:
170
+ #
171
+ # on :key, "-switch", Optout::File.named(/-\d{2}$/).under("/home/sshaw")
172
+ #
173
+ # In this case the file's basename must match the given regexp and exist under the given directory. See Optout::File for more info.
174
+ #
175
+ # ==== Optout::Dir
176
+ #
177
+ # Like <code>Optout::File</code> except for directories. <code>Optout::Dir</code> has several methods that can be used to tune validation, see Optout::Dir.
178
+ #
179
+ # on :key, Optout::Dir
180
+ # on :key, "-switch", Optout::Dir
181
+ #
182
+ # ==== Custom Validator
183
+ #
184
+ # A class that responds to +validate!+ and accepts a single argument containing the option (as an instance of Optout::Option).
185
+ #
186
+ # class MyValidator
187
+ # def validate!(option)
188
+ # if option.empty? || option.value.size % 2 != 1
189
+ # raise Optout::OptionInvalid.new(option.key, "bad option!")
190
+ # end
191
+ # end
192
+ # end
193
+ #
194
+ # on :key, MyValidator.new
195
+ # on :key, "-switch", MyValidator.new
196
+
134
197
  def on(*args)
135
198
  key = args.shift
136
199
 
137
200
  # switch is optional, this could be a validation rule
138
201
  switch = args.shift if String === args[0]
139
202
  raise ArgumentError, "option key required" if key.nil?
203
+
204
+ key = key.to_sym
140
205
  raise ArgumentError, "option already defined: '#{key}'" if @options[key]
141
206
 
142
207
  opt_options = Hash === args.last ? @default_opt_options.merge(args.pop) : @default_opt_options.dup
@@ -146,41 +211,120 @@ class Optout
146
211
  @options[key] = Option.create(key, switch, opt_options)
147
212
  end
148
213
 
214
+ ##
215
+ # Create a set of options that are optional. This can also be set on a per option basis, see Optout#on.
216
+ #
217
+ # === Examples
218
+ #
219
+ # optz = Optout.options do
220
+ # optional do
221
+ # on :ignore, "-i"
222
+ # on :recurse, "-r"
223
+ # end
224
+ # end
225
+ #
226
+ # optz.optional { on :path, Optout::File }
227
+
228
+ def optional(&block)
229
+ @optional_context.instance_eval(&block)
230
+ end
231
+
232
+ ##
233
+ # Create a set of options that are required.
234
+ #
235
+ # If any +required+ option is missing from the option hash passed to Optout#argv or Optout#shell an
236
+ # <code>Optout::OptionRequired</code> exception is raised.
237
+ #
238
+ # This can also be set on a per option basis, see Optout#on.
239
+ #
240
+ # === Examples
241
+ #
242
+ # optz = Optout.options do
243
+ # required do
244
+ # on :ignore, "-i"
245
+ # on :recurse, "-r"
246
+ # end
247
+ # end
248
+ #
249
+ # optz.required { on :path, Optout::File }
250
+ #
251
+
252
+ def required(&block)
253
+ @required_context.instance_eval(&block)
254
+ end
255
+
149
256
  ##
150
257
  # Create an argument string that can be to passed to a +system+ like function.
258
+ # Options must first be defined via Optout#on.
151
259
  #
152
260
  # === Parameters
261
+ #
153
262
  # [options (Hash)] The option hash used to construct the argument string.
154
263
  #
155
264
  # === Returns
265
+ #
156
266
  # [String] The argument string.
157
267
  #
158
268
  # === Errors
269
+ #
159
270
  # See Optout#argv@Errors
271
+ #
272
+ # === Examples
273
+ #
274
+ # Create <code>"-a -b '1024' '/home/sshaw/some file'"</code>
275
+ #
276
+ # optz = Optout.options do
277
+ # on :all, "-a"
278
+ # on :size, "-b", /\A\d+\z/, :required => true
279
+ # on :file, Optout::File.under("/home/sshaw"), :default => "/home/sshaw/tmp"
280
+ # end
281
+ #
282
+ # optz.shell(:all => true, :size => 1024, :file => "/home/sshaw/some file")
283
+
160
284
  def shell(options = {})
161
285
  create_options(options).map { |opt| opt.to_s }.join " "
162
286
  end
163
287
 
164
288
  ##
165
289
  # Create an +argv+ array that can be to passed to an +exec+ like function.
290
+ # Options must first be defined via Optout#on.
166
291
  #
167
292
  # === Parameters
293
+ #
168
294
  # [options (Hash)] The options hash used to construct the +argv+ array.
169
295
  #
170
296
  # === Returns
297
+ #
171
298
  # [Array] The +argv+ array, each element is a +String+
172
299
  #
173
300
  # === Errors
301
+ #
302
+ # [ArgumentError] If options are not a +Hash+
174
303
  # [Optout::OptionRequired] The option hash is missing a required value.
175
304
  # [Optout::OptionUnknown] The option hash contains an unknown key.
176
305
  # [Optout::OptionInvalid] The option hash contains a value the does not conform to the defined specification.
177
-
306
+ #
307
+ # === Examples
308
+ #
309
+ # Create <code>["--prefix='/sshaw/usr/lib'", "libssl2"]</code>
310
+ #
311
+ # optz = Optout.options do
312
+ # on :all, "-a"
313
+ # on :size, "-b", /\A\d+\z/, :required => true
314
+ # on :file, Optout::File.under("/home/sshaw"), :default => "/home/sshaw/tmp"
315
+ # end
316
+ #
317
+ # optz.argv(:lib => "libssl2",
318
+ # :prefix => "/sshaw/usr/lib")
319
+
178
320
  def argv(options = {})
179
321
  create_options(options).map { |opt| opt.to_a }.flatten
180
322
  end
181
323
 
182
324
  private
183
- def create_options(options = {})
325
+ def create_options(options = {})
326
+ raise ArgumentError, "options must be a Hash" unless Hash === options
327
+
184
328
  argv = []
185
329
  options = options.dup
186
330
 
@@ -199,12 +343,24 @@ class Optout
199
343
  sort_by { |opt| opt.index }
200
344
  end
201
345
 
346
+ def option_context(forced_options)
347
+ klass = self
348
+ Class.new do
349
+ define_method(:on) do |*args|
350
+ options = Hash === args.last ? args.pop.dup : {}
351
+ options.merge!(forced_options)
352
+ args << options
353
+ klass.on *args
354
+ end
355
+ end.new
356
+ end
357
+
202
358
  class Option
203
359
  attr :key
204
360
  attr :value
205
361
  attr :index
206
362
 
207
- ##
363
+ ##
208
364
  # Creates a subclass of +Option+
209
365
  #
210
366
  # === Parameters
@@ -246,7 +402,7 @@ class Optout
246
402
 
247
403
  ##
248
404
  # Turn the option into a string that can be to passed to a +system+ like function.
249
- # This _does not_ validate the option. You must call <code>validate!</code>.
405
+ # This _does_ _not_ validate the option. You must call <code>validate!</code>.
250
406
  #
251
407
  # === Examples
252
408
  #
@@ -300,7 +456,7 @@ class Optout
300
456
  #
301
457
  # [OptionRequired] The option is missing a required value
302
458
  # [OptionUnknown] The option contains an unknown key
303
- # [OptionInvalid] The option contains a value the does not conform to the defined specification
459
+ # [OptionInvalid] The option contains a value that does not conform to the defined specification
304
460
  #
305
461
  def validate!
306
462
  @validators.each { |v| v.validate!(self) }
@@ -324,28 +480,29 @@ class Optout
324
480
  end
325
481
 
326
482
  def unix?
327
- RbConfig::CONFIG["host_os"] !~ /mswin|mingw/i
483
+ RbConfig::CONFIG["host_os"] !~ /mswin|mingw|msys/i
328
484
  end
329
-
485
+
330
486
  def normalize(value)
331
487
  value.respond_to?(:entries) ? value.entries.join(@joinon) : value.to_s.strip
332
488
  end
333
489
  end
334
-
490
+
335
491
  module Validator #:nodoc: all
336
492
  def self.for(setting)
337
493
  if setting.respond_to?(:validate!)
338
494
  setting
339
495
  else
340
496
  # Load validator based on the setting's name or the name of its class
341
- validator = setting.class.name
497
+ # Note that on 1.9 calling class.name on anonymous classes (i.e., Class.new.new) returns nil
498
+ validator = setting.class.name.to_s
342
499
  if validator == "Class"
343
- name = setting.name.split("::", 2)
500
+ name = setting.name.to_s.split("::", 2)
344
501
  validator = name[1] if name[1] && name[0] == "Optout"
345
502
  end
346
503
 
347
- # Support 1.8 and 1.9, avoid String/Symbol and const_defined? differences
348
- if !constants.include?(validator) && !constants.include?(validator.to_sym)
504
+ # Support 1.8 and 1.9, avoid String/Symbol and const_defined? differences
505
+ if validator.empty? || !constants.include?(validator) && !constants.include?(validator.to_sym)
349
506
  raise ArgumentError, "don't know how to validate with #{setting}"
350
507
  end
351
508
 
@@ -355,7 +512,7 @@ class Optout
355
512
 
356
513
  Base = Struct.new :setting
357
514
 
358
- # Check for multiple values
515
+ # Checks for multiple values
359
516
  class Multiple < Base
360
517
  def validate!(opt)
361
518
  if !opt.empty? && opt.value.respond_to?(:entries) && opt.value.entries.size > 1 && !multiple_values_allowed?
@@ -384,6 +541,8 @@ class Optout
384
541
 
385
542
  class Array < Base
386
543
  def validate!(opt)
544
+ return if opt.empty?
545
+
387
546
  values = [opt.value].flatten
388
547
  values.each do |e|
389
548
  if !setting.include?(e)
@@ -403,7 +562,7 @@ class Optout
403
562
 
404
563
  class Class < Base
405
564
  def validate!(opt)
406
- if !(setting === opt.value)
565
+ if !opt.empty? && !(setting === opt.value)
407
566
  raise OptionInvalid.new(opt.key, "value '#{opt.value}' must be type #{setting}")
408
567
  end
409
568
  end
@@ -412,6 +571,7 @@ class Optout
412
571
  class Boolean < Base
413
572
  def validate!(opt)
414
573
  if !(opt.value == true || opt.value == false || opt.value.nil?)
574
+ # TODO: Better message
415
575
  raise OptionInvalid.new(opt.key, "does not accept an argument")
416
576
  end
417
577
  end
@@ -485,6 +645,7 @@ class Optout
485
645
  @file.parent.expand_path.to_s == ::File.expand_path(@under))
486
646
  end
487
647
 
648
+ # TODO: Should probably make correct_type? a separate check
488
649
  def creatable?
489
650
  @file.exist? && correct_type? ||
490
651
  !@file.exist? && @file.parent.exist? && @file.parent.writable?
@@ -501,22 +662,24 @@ class Optout
501
662
 
502
663
 
503
664
  #
504
- # These are shortcuts and/or marker classes used by the public interface so Validator.for()
505
- # can load the equivalent validation class
665
+ # The following are shortcuts and/or marker classes used by Optout's public. They enable Validator.for()
666
+ # to load the appropriate validation class.
506
667
  #
507
668
 
508
669
  ##
509
670
  # <code>Optout::File</code> is a validaton rule that can be used to check that an option's value is a path to a file.
510
671
  # By default <code>Optout::File</code> *does* *not* *check* that the file exists. Instead, it checks that the file's parent directory
511
672
  # exists. This is done so that you can validate a path that _will_ be created by the program the options are for.
512
- # If you _do_ want the file to exist just call the +exists+ method.
673
+ # If you do want the file to exist just call the +exists+ method.
513
674
  #
514
675
  # Validation rules can be combined:
515
676
  #
516
677
  # Optout.options do
517
678
  # on :path, "--path", Optout::File.exists.under("/home").named(/\.txt$/)
518
679
  # end
519
- #
680
+ #
681
+ # To validate directories use Optout::Dir.
682
+ #
520
683
  class File
521
684
  class << self
522
685
  Validator::File::RULES.each do |r|
@@ -554,11 +717,15 @@ class Optout
554
717
  # :call-seq:
555
718
  # permissions(symbolic_mode)
556
719
  #
557
- # The option's user permissions must match the given permission(s).
720
+ # The option's *user* *permissions* must match the given permission(s).
721
+ #
558
722
  #
559
723
  # === Parameters
560
724
  #
561
- # A +String+ denoting the desired permission. Any combination of <code>"r"</code>, <code>"w"</code> and <code>"x"</code> is supported.
725
+ # A <code>chmod(1)</code> symbolic mode +String+ denoting the desired permission(s).
726
+ # Any combination of <code>"r"</code>, <code>"w"</code> and <code>"x"</code> is supported.
727
+ #
728
+ # Note that permissions are system dependent, certain modes might not be supported by your OS.
562
729
 
563
730
  ##
564
731
  #
@@ -576,7 +743,9 @@ class Optout
576
743
 
577
744
  ##
578
745
  # <code>Optout::Dir</code> is a validaton rule that can be used to check that an option's value is a path to a directory.
579
- # Validation rules can be combined:
746
+ # This class proivdes the same functionality for directories that Optout::File provides for files. See Optout::File for more info.
747
+ #
748
+ # Validation rules can be combined:
580
749
  #
581
750
  # Optout.options do
582
751
  # on :path, "--path", Optout::Dir.exists.under("/tmp").named(/\d$/)
@@ -590,7 +759,14 @@ class Optout
590
759
  end
591
760
  end
592
761
 
593
- class Boolean #:nodoc:
762
+ ##
763
+ # <code>Optout::Boolean</code> is a validaton rule that can be used to check that an option's value is +true+ or +false+.
764
+ #
765
+ # Optout.options do
766
+ # on :force, "-f", Optout::Boolean
767
+ # end
768
+
769
+ class Boolean
594
770
  end
595
771
  end
596
772