Optout

Optout helps you write code that will call exec and system like functions. It allows you to map hash keys to command line arguments and define validation rules that must be met before the command line arguments are created.

Overview

require "optout"

# Create options for `gem`
optout = Optout.options do
  on :gem, "install", :required => true
  on :os, "--platform", %w(mswin cygwin mingw)
  on :version, "-v", /\A\d+(\.\d+)*\z/
  on :user, "--user-install"
  on :location, "-i", Optout::Dir.exists.under(ENV["HOME"])
end

options = {
  :gem => "rake",
  :os => "mswin",
  :version => "0.9.2",
  :user => truep	
}

exec "gem", *optout.argv(options)
# Returns: ["install", "rake", "--platform", "mswin", "-v", "0.9.2", "--user-install"]

`gem #{optout.shell(options)}`
# Returns: "'install' 'rake' --platform 'mswin' -v '0.9.2' --user-install"

Install

gem install optout

Defining Options

Inorder to turn the incoming option hash into something useful you must tell Optout a bit about your options. This is done by calling Optout#on and passing it the name of a key in the option hash. The simplest case is an option with no switch:

optout = Optout.options do 
  on :path
end

optout.shell(:path => "/home/sshaw")
# Returns: '/home/sshaw'

Key names can be a Symbol or a String, Optout will check for both in the option hash.

If the option has a switch it can be given after the option’s key:

optout = Optout.options do 
  on :path, "-p"
end

optout.shell(:path => "/home/sshaw")
# Returns: -p '/home/sshaw'

Some programs can be finicky about the space between the switch and the value, or require options in a different format. Optout accepts various configuration options that can remdy this:

optout = Optout.options do 
  on :path, "-p", :arg_separator => ""
end

optout.shell(:path => "/home/sshaw")
# Returns: -p'/home/sshaw'

optout = Optout.options do 
  on :path, "--path", :arg_separator => "=", :required => true
end

optout.shell(:path => "/home/sshaw")
# Returns: --path='/home/sshaw'

optout.shell({})
# Raises: Optout::OptionRequired

Options can be grouped into required and optional:

Optout.options :arg_separator => "=" do 
  required do 
    on :in, "if"
    on :out, "of"
  end

  optional do 
    on :size, "size"
    on :count, "count"
  end
end

optout.shell(:in => "/dev/zero", :out => "/var/log/secure")
# Returns: in='/dev/zero' out='/var/log/secure'

Validating Options

Optout can validate your options too. Just specify the validation rule after the option’s key or switch:

optout = Optout.options do 
  # Must match [a-z]
  on :path, "-p", /[a-z]/
end

optout = Optout.options do 
  # Must be true, false, or nil (add :required => true to allow only true or false)
  on :path, "-p", Optout::Boolean
end

optout = Optout.options do 
  # Must be in the given set
  on :path, %w(/home/sshaw /Users/gatinha /Users/fofinha)
end

optout = Optout.options do 
  # Must be a diretory under "/home" and have user read and write permissions
  on :path, Optout::Dir.under("/home").permissions("rw")
end

optout.shell(:path => "/root")
# Raises: Optout::OptionInvalid

TODOs

  • Proper cmd.exe quoting

  • Mutually exclusive options

  • Split options i.e., :jvm => %w[A B C] would be created as -XA -XB -XC

More Info

RDoc

rubydoc.info/github/sshaw/optout/frames (with RDoc -> YARD incompatibilities :)

Bugs

github.com/sshaw/optout/issues

Author

Skye Shaw [sshaw AT lucas.cis.temple.edu]

License

Copyright © 2011-2012 Skye Shaw

Released under the MIT License: www.opensource.org/licenses/MIT