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

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 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",
          :bad_key  => "No error raised because of moi")


292
293
294
# File 'lib/optout.rb', line 292

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

options (Hash)

Additional option configuration, see Options.

Options

:arg_separator

The String used to separate the option's switch from its value. Defaults to " " (space).

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

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

Validating

An option's value can be restricted by a validation rule. If validation fails a 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, false, or nil.

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

Errors

ArgumentError

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

Raises:

  • (ArgumentError)


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

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



217
218
219
# File 'lib/optout.rb', line 217

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

#required(&block) ⇒ Object

Create a set of options that are required



222
223
224
# File 'lib/optout.rb', line 222

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

#shell(options = {}) ⇒ Object



255
256
257
# File 'lib/optout.rb', line 255

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