Class: CommandUtils

Inherits:
Object
  • Object
show all
Defined in:
lib/command_utils.rb,
lib/command_utils/version.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

Constant Summary collapse

VERSION =
'0.4.6'

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



103
104
105
# File 'lib/command_utils.rb', line 103

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



68
69
70
# File 'lib/command_utils.rb', line 68

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



128
129
130
# File 'lib/command_utils.rb', line 128

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.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/command_utils.rb', line 76

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
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/command_utils.rb', line 29

def each_output &block # :yields: stream, data
  spawn
  begin
    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
        buffer = ''
        loop do
          begin
            buffer += io.read_nonblock(io.stat.blksize)
          rescue EOFError
            io.close
            break
          rescue IO::EAGAINWaitReadable
            break
          end
        end
        yield label, buffer
      end
    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.



116
117
118
119
120
121
122
# File 'lib/command_utils.rb', line 116

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