Class: Maze::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/maze/runner.rb

Overview

Runs scripts and commands, applying relevant environment variables as necessary

Class Method Summary collapse

Class Method Details

.environmentHash

Allows access to a hash of environment variables applied to command and script runs.



137
138
139
# File 'lib/maze/runner.rb', line 137

def environment
  @environment ||= {}
end

.interactive_sessionObject



100
101
102
103
104
# File 'lib/maze/runner.rb', line 100

def interactive_session
  raise 'No interactive session is running!' unless interactive_session?

  @interactive_session
end

.interactive_session?Boolean



96
97
98
# File 'lib/maze/runner.rb', line 96

def interactive_session?
  !@interactive_session.nil?
end

.kill_running_scriptsObject

Stops all script processes previously started by this class.



123
124
125
126
127
128
129
130
131
132
# File 'lib/maze/runner.rb', line 123

def kill_running_scripts
  stop_interactive_session if interactive_session?

  pids.each do |p|
    Process.kill('KILL', p)
  rescue Errno::ESRCH
    # ignored
  end
  pids.clear
end

.pidsArray

Allows access to the process ids created by the runner.



144
145
146
# File 'lib/maze/runner.rb', line 144

def pids
  @pids ||= []
end

.run_command(cmd, blocking: true, success_codes: [0]) ⇒ Array, Thread

Runs a command, applying previously set environment variables. The output from the command is always printed in debug mode - just so the caller can verify something about the output.



22
23
24
25
26
27
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
# File 'lib/maze/runner.rb', line 22

def run_command(cmd, blocking: true, success_codes: [0])
  executor = lambda do
    $logger.debug "Executing: #{cmd}"

    Open3.popen2e(environment, cmd) do |_stdin, stdout_and_stderr, wait_thr|
      # Add the pid to the list of pids to kill at the end
      pids << wait_thr.pid unless blocking

      output = []
      stdout_and_stderr.each do |line|
        output << line
        $logger.debug line.chomp
      end

      exit_status = wait_thr.value.to_i
      $logger.debug "Exit status: #{exit_status}"

      # if the command fails we log the output at warn level too
      if !success_codes.nil? && !success_codes.include?(exit_status) && $logger.level != Logger::DEBUG
        output.each { |line| $logger.warn(cmd) { line.chomp } }
      end

      return [output, exit_status]
    end
  end

  if blocking
    executor.call
  else
    Thread.new(&executor)
  end
end

.run_script(script_name, blocking: false, success_codes: [0], command: nil) ⇒ Array

Runs a script in the script directory indicated by the SCRIPT_PATH environment variable.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/maze/runner.rb', line 63

def run_script(script_name, blocking: false, success_codes: [0], command: nil)
  script_path = File.join(SCRIPT_PATH, script_name)
  script_path = File.join(Dir.pwd, script_name) unless File.exist? script_path
  if command
    script_path = "#{command} #{script_path}"
  elsif Gem.win_platform?
    # Windows does not support the shebang that we use in the scripts so it
    # needs to know how to execute the script. Passing `cmd /c` tells windows
    # to use its known file associations to execute this path. If Ruby is
    # installed on Windows then it will know that `rb` files should be executed
    # using Ruby etc.
    script_path = "cmd /c #{script_path}"
  end
  run_command(script_path, blocking: blocking, success_codes: success_codes)
end

.start_interactive_session(*args) ⇒ InteractiveCLI

Creates a new interactive session. Can only be called if no session already exists. Check with interactive_session? if necessary.



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/maze/runner.rb', line 83

def start_interactive_session(*args)
  raise 'An interactive session is already running!' if interactive_session?

  wait = Maze::Wait.new(interval: 0.3, timeout: 3)

  interactive_session = InteractiveCLI.new(*args)

  success = wait.until { interactive_session.running? }
  raise 'Shell session did not start in time!' unless success

  @interactive_session = interactive_session
end

.stop_interactive_sessionBoolean

Stops the interactive session, allowing a new one to be started



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/maze/runner.rb', line 109

def stop_interactive_session
  raise 'No interactive session is running!' unless interactive_session?

  success = @interactive_session.stop

  # Make sure the process is killed if it did not stop
  pids << @interactive_session.pid if @interactive_session.running?

  @interactive_session = nil

  success
end