Class: Brut::TUI::Script::ExecStep

Inherits:
Step
  • Object
show all
Defined in:
lib/brut/tui/script/exec_step.rb

Overview

A step whose behavior is to run a command as a child process. Fires Brut::TUI::Script::Events::StepStarted then Brut::TUI::Script::Events::ExecutingCommand before the command is run. The command is then run with Open3.popen3 and the stderr and stdout are streamed as output is available. Each block of bytes read generates a Brut::TUI::Script::Events::CommandStdOut or a Brut::TUI::Script::Events::CommandStdErr event with the bytes reads.

If the command exited nonzero, Brut::TUI::Script::Events::CommandExecutionSucceeded is fired, otherwise Brut::TUI::Script::Events::CommandExecutionFailed is fired, Either way, Brut::TUI::Script::Events::StepCompleted is fired unless there is an unhandled exception.

Constant Summary

Constants inherited from Step

Step::Events

Instance Attribute Summary collapse

Attributes inherited from Step

#description

Instance Method Summary collapse

Constructor Details

#initialize(event_loop, description, command:) ⇒ ExecStep

Returns a new instance of ExecStep.



20
21
22
23
# File 'lib/brut/tui/script/exec_step.rb', line 20

def initialize(event_loop, description, command:)
  super(event_loop, description)
  @command = command
end

Instance Attribute Details

#commandObject (readonly)

Returns the value of attribute command.



19
20
21
# File 'lib/brut/tui/script/exec_step.rb', line 19

def command
  @command
end

Instance Method Details

#deconstruct_keys(keys = nil) ⇒ Object



25
26
27
# File 'lib/brut/tui/script/exec_step.rb', line 25

def deconstruct_keys(keys=nil)
  super.deconstruct_keys(keys).merge({ command: @command, strip_ansi: false })
end

#run!Object



28
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
# File 'lib/brut/tui/script/exec_step.rb', line 28

def run!
  event_loop << Events::StepStarted.new(step: self)
  event_loop << Events::ExecutingCommand.new(step: self)

  wait_thread = Open3.popen3(*@command) do |_stdin,stdout,stderr,wait_thread|
    o = stdout.read_nonblock(10, exception: false)
    e = stderr.read_nonblock(10, exception: false)
    while o || e
      if o
        if o != :wait_readable
          event_loop << Events::CommandStdOut.new(step: self, output: o)
        end
        o = stdout.read_nonblock(10, exception: false)
      end
      if e
        if e != :wait_readable
          event_loop << Events::CommandStdErr.new(step: self, output: e)
        end
        e = stderr.read_nonblock(10, exception: false)
      end
    end
    wait_thread
  end

  if wait_thread.value.success?
    event_loop << Events::CommandExecutionSucceeded.new(step: self)
  else
    event_loop << Events::CommandExecutionFailed.new(step: self)
  end
  event_loop << Events::StepCompleted.new(step: self)
end