Class: Mattock::CommandLine::CommandRunResult

Inherits:
Object
  • Object
show all
Defined in:
lib/mattock/command-line/command-run-result.rb

Direct Known Subclasses

MockCommandResult

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pid, command) ⇒ CommandRunResult

Returns a new instance of CommandRunResult.



4
5
6
7
8
9
10
11
12
# File 'lib/mattock/command-line/command-run-result.rb', line 4

def initialize(pid, command)
  @command = command
  @pid = pid

  #####
  @process_status = nil
  @streams = {}
  @consume_timeout = nil
end

Instance Attribute Details

#consume_timeoutObject

Returns the value of attribute consume_timeout.



14
15
16
# File 'lib/mattock/command-line/command-run-result.rb', line 14

def consume_timeout
  @consume_timeout
end

#pidObject (readonly)

Returns the value of attribute pid.



13
14
15
# File 'lib/mattock/command-line/command-run-result.rb', line 13

def pid
  @pid
end

#process_statusObject (readonly)

Returns the value of attribute process_status.



13
14
15
# File 'lib/mattock/command-line/command-run-result.rb', line 13

def process_status
  @process_status
end

#streamsObject

Returns the value of attribute streams.



14
15
16
# File 'lib/mattock/command-line/command-run-result.rb', line 14

def streams
  @streams
end

Instance Method Details

#consume_buffers(readable) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/mattock/command-line/command-run-result.rb', line 110

def consume_buffers(readable)
  if not(readable.nil? or readable.empty?)
    readable.each do |io|
      begin
        while chunk = io.read_nonblock(4096)
          if @buffered_echo.nil?
            @command.report chunk, false
          else
            @buffered_echo << chunk
          end
          @accumulators[io] <<  chunk
        end
      rescue IO::WaitReadable => ex
      rescue EOFError => ex
        @live_ioes.delete(io)
      end
    end
  end
end

#exit_codeObject Also known as: exit_status



24
25
26
# File 'lib/mattock/command-line/command-run-result.rb', line 24

def exit_code
  @process_status.exitstatus
end

#format_streamsObject



36
37
38
39
# File 'lib/mattock/command-line/command-run-result.rb', line 36

def format_streams
  "stdout:#{stdout.nil? || stdout.empty? ? "[empty]\n" : "\n#{stdout}"}" +
  "stderr:#{stderr.nil? || stderr.empty? ? "[empty]\n" : "\n#{stderr}"}---"
end

#must_succeed!Object



41
42
43
44
45
46
47
48
# File 'lib/mattock/command-line/command-run-result.rb', line 41

def must_succeed!
  case exit_code
  when 0
    return exit_code
  else
    fail "Command #{@command.inspect} failed with exit status #{exit_code}: \n#{format_streams}"
  end
end

#stderrObject



20
21
22
# File 'lib/mattock/command-line/command-run-result.rb', line 20

def stderr
  @streams[2]
end

#stdoutObject



16
17
18
# File 'lib/mattock/command-line/command-run-result.rb', line 16

def stdout
  @streams[1]
end

#succeeded?Boolean

Returns:

  • (Boolean)


29
30
31
32
33
34
# File 'lib/mattock/command-line/command-run-result.rb', line 29

def succeeded?
  must_succeed!
  return true
rescue
  return false
end

#waitObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/mattock/command-line/command-run-result.rb', line 50

def wait
  @accumulators = {}
  waits = {}
  @buffered_echo = []

  ioes = streams.values
  ioes.each do |io|
    @accumulators[io] = []
    waits[io] = 3
  end
  begin_echoing = Time.now + (@consume_timeout || 3)

  @live_ioes = ioes.dup

  until @live_ioes.empty? do
    newpid, @process_status = Process.waitpid2(pid, Process::WNOHANG)

    unless @process_status.nil?
      consume_buffers(@live_ioes)
      break
    end

    timeout = 0

    if !@buffered_echo.nil?
      timeout = begin_echoing - Time.now
      if timeout < 0
        @command.report ""
        @command.report "Long running command output:"
        @command.report @buffered_echo.join
        @buffered_echo = nil
      end
    end

    if timeout > 0
      result = IO::select(@live_ioes, [], @live_ioes, timeout)
    else
      result = IO::select(@live_ioes, [], @live_ioes, 1)
    end

    unless result.nil? #timeout
      readable, _writeable, errored = *result
      unless errored.empty?
        raise "Error on IO: #{errored.inspect}"
      end

      consume_buffers(readable)
    end
  end

  if @process_status.nil?
    newpid, @process_status = Process.waitpid2(pid)
  end

  ioes.each do |io|
    io.close
  end
  @streams = Hash[ioes.each_with_index.map{|io, index| [index + 1, @accumulators[io].join]}]
end