/optout

The opposite of getopt(): validate an option hash and turn it into something appropriate for exec() and system()-like functions

Primary LanguageRuby

Optout

<img src=“https://secure.travis-ci.org/sshaw/optout.svg”/>

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 => true
}

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

  • Validate based on the presence of other options

More Info

Author

Skye Shaw [skye.shaw AT gmail]

License

Copyright © 2011-2019 Skye Shaw

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