Class: Optout

Inherits:
Object
  • Object
show all
Defined in:
lib/optout.rb

Defined Under Namespace

Modules: Validator Classes: Boolean, Dir, File, Option, OptionError, OptionInvalid, OptionRequired, OptionUnknown

Constant Summary collapse

VERSION =
"0.0.2"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Optout

Returns a new instance of Optout.



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/optout.rb', line 91

def initialize(args = {})
  @options = {}
  @check_keys = args.include?(:check_keys) ? args[:check_keys] : true
  @required_context = option_context(:required => true)
  @optional_context = option_context(:required => false)  
  @default_opt_options = {
    :required => args[:required],
    :multiple => args[:multiple],
    :arg_separator => args[:arg_separator]
  }
end

Class Method Details

.options(config = {}, &block) ⇒ Object Also known as: keys

Define a set of options. After the options are defined call Optout#argv or Optout#shell to create them.

optz = Optout.options config do 
  on :key, "-switch", ValidationRule, :multiple => false, :required => true
  # ...
end

Parameters

config (Hash)

Configuration options

block (Proc)

Option definitions

Configuration Options

: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.

: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. Defaults to true.

:multiple

Set the default for all subsequent options defined via on. See Optout#on.

:required

Set the default for all subsequent options defined via on. See Optout#on.

Errors

ArgumentError

Calls to on from inside a block can raise an ArgumentError.

Examples

optz = Optout.options do
  on :all,  "-a"
  on :size, "-b", /\A\d+\z/, :required => true
  on :file, Optout::File.under("/home/sshaw"), :default => "/home/sshaw/tmp"
end

optz = Optout.options :required => true, :check_keys => false do
  on :lib
  on :prefix, "--prefix" , %w{/sshaw/lib /sshaw/usr/lib}, :arg_separator => "="
end

# Same as above
optz = Optout.options :check_keys => false do
  required do 
    on :lib
    on :prefix, "--prefix" , %w{/sshaw/lib /sshaw/usr/lib}, :arg_separator => "="
  end
end


82
83
84
85
86
# File 'lib/optout.rb', line 82

def options(config = {}, &block)
  optout = new(config)
  optout.instance_eval(&block) if block_given?
  optout
end

Instance Method Details

#argv(options = {}) ⇒ Object

Create an argv array that can be to passed to an exec like function. Options must first be defined via Optout#on.

Parameters

options (Hash)

The options hash used to construct the argv array.

Returns

Array

The argv array, each element is a String

Errors

ArgumentError

If options are not a Hash

Optout::OptionRequired

The option hash is missing a required value.

Optout::OptionUnknown

The option hash contains an unknown key.

Optout::OptionInvalid

The option hash contains a value the does not conform to the defined specification.

Examples

Create ["--prefix='/sshaw/usr/lib'", "libssl2"]

optz = Optout.options do
  on :all,  "-a"
  on :size, "-b", /\A\d+\z/, :required => true
  on :file, Optout::File.under("/home/sshaw"), :default => "/home/sshaw/tmp"
end  

optz.argv(:lib      => "libssl2",
          :prefix   => "/sshaw/usr/lib")


320
321
322
# File 'lib/optout.rb', line 320

def argv(options = {})
  create_options(options).map { |opt| opt.to_a }.flatten
end

#on(*args) ⇒ Object

Define an option.

Parameters

key (Symbol)

The key of the option in the option hash passed to shell or argv.

switch (String)

Optional. The option’s command line switch. If no switch is given only the option’s value is output.

rule (Object)

Optional. Validation rule, see Optout#on@Validating.

options (Hash)

Additional option configuration, see Optout#on@Options.

Options

:arg_separator

The String used to separate the option’s switch from its value. Defaults to " " (space). This can be set globally via Optout::options.

:default

The option’s default value. This will be used if the option is nil or empty?.

:multiple

If true the option will accept multiple values. If false an Optout::OptionInvalid 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.

:required

If true the option must contian a value i.e., it must not be false or nil otherwise an Optout::OptionRequired exception will be raised.

Defaults to false. This can be set globally via Optout::options or for a set of options via Optout#required or Optout#optional.

Errors

ArgumentError

An ArgumentError is raised if key is nil or has already been defined

Validating

An option’s value can be restricted by a validation rule. If validation fails an Optout::OptionInvalid exception is raised.

Validation rules will only be applied if the option hash contains a non-nil value for the given option’s key.

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.

Validation rules can be in one of the following forms:

Regex

A pattern to match the option’s value against.

on :key, /\d+/
on :key, "-switch", /\d+/

Array

Only accept value(s) contained in the given array.

on :key, %w(item_a item_b item_c)
on :key, "-switch", %w(item_a item_b item_c)

Class

Must be an instance of the given class.

on :key, Fixnum
on :key, "-switch", Fixnum

Optout::Boolean

Must be true or false.

on :key, Optout::Boolean
on :key, "-switch", Optout::Boolean

Optout::File

Must be a file. Note that the file does not have to exist.

on :key, Optout::File
on :key, "-switch", Optout::File

Optout::File has several methods that can be used to tune validation:

on :key, "-switch", Optout::File.named(/-\d{2}$/).under("/home/sshaw")

In this case the file’s basename must match the given regexp and exist under the given directory. See Optout::File for more info.

Optout::Dir

Like Optout::File except for directories. Optout::Dir has several methods that can be used to tune validation, see Optout::Dir.

on :key, Optout::Dir
on :key, "-switch", Optout::Dir

Custom Validator

A class that responds to validate! and accepts a single argument containing the option (as an instance of Optout::Option).

class MyValidator
  def validate!(option)
    if option.empty? || option.value.size % 2 != 1
      raise Optout::OptionInvalid.new(option.key, "bad option!")
    end
  end
end

on :key, MyValidator.new
on :key, "-switch", MyValidator.new

Raises:

  • (ArgumentError)


197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/optout.rb', line 197

def on(*args)
  key = args.shift

  # switch is optional, this could be a validation rule
  switch = args.shift if String === args[0]
  raise ArgumentError, "option key required" if key.nil?

  key = key.to_sym
  raise ArgumentError, "option already defined: '#{key}'" if @options[key]

  opt_options = Hash === args.last ? @default_opt_options.merge(args.pop) : @default_opt_options.dup
  opt_options[:index] ||= @options.size
  opt_options[:validator] = args.shift

  @options[key] = Option.create(key, switch, opt_options)
end

#optional(&block) ⇒ Object

Create a set of options that are optional. This can also be set on a per option basis, see Optout#on.

Examples

optz = Optout.options do 
  optional do 
    on :ignore, "-i"
    on :recurse, "-r"
  end
end

optz.optional { on :path, Optout::File }


228
229
230
# File 'lib/optout.rb', line 228

def optional(&block)
  @optional_context.instance_eval(&block)
end

#required(&block) ⇒ Object

Create a set of options that are required.

If any required option is missing from the option hash passed to Optout#argv or Optout#shell an Optout::OptionRequired exception is raised.

This can also be set on a per option basis, see Optout#on.

Examples

optz = Optout.options do 
  required do 
    on :ignore, "-i"
    on :recurse, "-r"
  end
end

optz.required { on :path, Optout::File }


252
253
254
# File 'lib/optout.rb', line 252

def required(&block)    
  @required_context.instance_eval(&block)
end

#shell(options = {}) ⇒ Object

Create an argument string that can be to passed to a system like function. Options must first be defined via Optout#on.

Parameters

options (Hash)

The option hash used to construct the argument string.

Returns

String

The argument string.

Errors

See Optout#argv@Errors

Examples

Create "-a -b '1024' '/home/sshaw/some file'"

optz = Optout.options do
  on :all,  "-a"
  on :size, "-b", /\A\d+\z/, :required => true
  on :file, Optout::File.under("/home/sshaw"), :default => "/home/sshaw/tmp"
end  

optz.shell(:all => true, :size => 1024, :file => "/home/sshaw/some file")


284
285
286
# File 'lib/optout.rb', line 284

def shell(options = {})
  create_options(options).map { |opt| opt.to_s }.join " "
end