Module: Dotanuki

Defined in:
lib/dotanuki.rb,
lib/dotanuki/version.rb

Overview

Module intented to be included into classes which execute system commands

Author:

  • Martin Englund

Defined Under Namespace

Classes: ExecError, ExecResult

Constant Summary collapse

DEFAULT_OPTIONS =

Default options for executing commands

{:on_error => :exception}
VERSION =

gem version

"0.3.1"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.clear_guardObject

TODO this is not thread safe



180
181
182
183
184
# File 'lib/dotanuki.rb', line 180

def clear_guard
  result = @guard
  @guard = nil
  result
end

.execute(commands, options = {}) ⇒ ExecResult

TODO:

pass an environment too

Execute one or more commands

Parameters:

  • commands (String, Array)

    string or array containing the command to be executed

  • options (Hash) (defaults to: {})

    (see #guard)

Returns:



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/dotanuki.rb', line 125

def execute(commands, options={})
  validate_options(options)

  result = ExecResult.new

  [commands].flatten.each do |command|
    begin
      if POSIX_SPAWN
        child = POSIX::Spawn::Child.new(command)
        stdout = child.out.strip
        stderr = child.err.strip
        status = child.status
      else
        status = Open4::popen4(command) do |pid, stdin, out, err|
          stdout = out.read.strip
          stderr = err.read.strip
        end
      end
      result.add(stdout, stderr, status.exitstatus)

      if status.exitstatus != 0
        if options[:on_error] == :exception || @guard
          @guard << result if @guard
          raise ExecError, stderr
        end
        break
      end
    rescue Errno::ENOENT
      result.add(nil, nil, nil)
      if options[:on_error] == :exception
        @guard << result if @guard
        raise ExecError, "#{command}: command not found"
      end
      break
    end
  end

  @guard << result if @guard

  return result
end

.guard(options = {}, &block) ⇒ ExecResult

TODO:

pass an environment too

Note:

this method isn’t thread safe

Execute commands wrapped in a block

Examples:

guard do
  execute "uname -a"
  execute "ls /does/not/exist"
end

Parameters:

  • options (Hash) (defaults to: {})

    (see #guard)

Returns:



105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/dotanuki.rb', line 105

def guard(options={}, &block)
  # if guard is called as a module function @defaults is not set
  opts = (@defaults || {}).merge(options)
  validate_options(opts)
  # TODO this is not thread safe
  @guard = ExecResult.new
  yield
  clear_guard
rescue ExecError => e
  result = clear_guard
  raise e if opts[:on_error] == :exception
  result
end

.validate_options(options) ⇒ Object

Validates options for Dotanuki#execute or Dotanuki#guard

Raises:

  • (ArgumentError)

    if an unknown option is given



170
171
172
173
174
175
176
177
# File 'lib/dotanuki.rb', line 170

def validate_options(options)
  options.each do |option, value|
    if option == :on_error && ! [:exception, :silent].include?(value)
      raise ArgumentError, "illegal value for option #{option}: #{value}"
    end
    raise ArgumentError, "illegal option: #{option}" if option != :on_error
  end
end

Instance Method Details

#initialize(options = {}) ⇒ Object

Parameters:

  • options (Hash) (defaults to: {})

    the options for error handling

Options Hash (options):

  • :on_error (Symbol)

    How to handle errors, can be either ‘:exception` or `:silent`



90
91
92
# File 'lib/dotanuki.rb', line 90

def initialize(options={})
  @defaults = DEFAULT_OPTIONS.merge(options)
end