Class: CommandUtils

Inherits:
Object
  • Object
show all
Defined in:
lib/command_utils.rb,
lib/command_utils/line_buffer.rb

Overview

Class to assist calling external commands, while processing its output and return code.

Defined Under Namespace

Classes: LineBuffer, NonZeroExit, Signaled, StatusError, Stopped, Unknown

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) {|_self| ... } ⇒ CommandUtils

call-seq:

new([env,] command...)

Takes command in same format supported by Process#spawn.

Yields:

  • (_self)

Yield Parameters:

  • _self (CommandUtils)

    the object that the method was called on



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/command_utils.rb', line 13

def initialize *args
  first = args.first
  if first.respond_to? :to_hash
    @env = args.shift.to_hash
    @command = args
  else
    @env = nil
    @command = args
  end
  yield self if block_given?
end

Instance Attribute Details

#pidObject (readonly)

PID of currently running process.



7
8
9
# File 'lib/command_utils.rb', line 7

def pid
  @pid
end

Class Method Details

.each_line(*args, &block) ⇒ Object

call-seq:

each_line([env,] command...) { |stream, data| ... }

Wrapper for CommandUtils#each_line



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

def self.each_line *args, &block # :yields: stream, data
  self.new(*args).each_line(&block)
end

.each_output(*args, &block) ⇒ Object

call-seq:

each_output([env,] command...) { |stream, data| ... }

Wrapper for CommandUtils#each_output



55
56
57
# File 'lib/command_utils.rb', line 55

def self.each_output *args, &block # :yields: stream, data
  self.new(*args).each_output(&block)
end

.logger_exec(*args, options) ⇒ Object

call-seq:

logger_exec([env,] command..., options)

Wrapper for CommandUtils@logger_exec



115
116
117
# File 'lib/command_utils.rb', line 115

def self.logger_exec *args, options
  self.new(*args).logger_exec(options)
end

Instance Method Details

#each_line(&block) ⇒ Object

Execute command, yielding to given block, each time there is a new line available (does line buffering):

stream

either :stdout or :stderr.

data

data read from respective stream.

Raises CommandUtils::StatusError class exception if command execution is not successfull.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/command_utils.rb', line 63

def each_line &block # :yields: stream, data
  stdout_lb = LineBuffer.new(
    proc do |data|
      block.call :stdout, data
    end
    )
  stderr_lb = LineBuffer.new(
    proc do |data|
      block.call :stderr, data
    end
    )
  each_output do |stream, data|
    case stream
    when :stdout
      stdout_lb.write data
    when :stderr
      stderr_lb.write data
    end
  end
  stdout_lb.flush
  stderr_lb.flush
end

#each_output(&block) ⇒ Object

Execute command, yielding to given block, each time there is output available (not line buffered):

stream

either :stdout or :stderr.

data

data read from respective stream.

Raises CommandUtils::StatusError class exception if command execution is not successfull.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/command_utils.rb', line 29

def each_output &block # :yields: stream, data
  spawn
  loop do
    io_list = [@stdout_read, @stderr_read].keep_if{|io| not io.closed?}
    break if io_list.empty?
    IO.select(io_list).first.each do |io|
      if io.eof?
        io.close
        next
      end
      label = case io
      when @stdout_read
        :stdout
      when @stderr_read
        :stderr
      end
      yield label, io.read
    end
  end
  process_status
end

#logger_exec(options) ⇒ Object

Execute command, logging its output, line buffered, to given Logger object. Must receive a hash, containing at least:

:logger

Logger instance.

:stdout_level

Logger level to log stdout.

:stderr_level

Logger level to log stderr.

and optionally:

:stdout_prefix

Prefix to use for all stdout messages.

:stderr_prefix

Prefix to use for all stderr messages.

Raises CommandUtils::StatusError class exception if command execution is not successfull.



103
104
105
106
107
108
109
# File 'lib/command_utils.rb', line 103

def logger_exec options
  each_line do |stream, data|
    level = options["#{stream}_level".to_sym]
    prefix = options["#{stream}_prefix".to_sym]
    options[:logger].send(level, "#{prefix}#{data}")
  end
end