Module: TFWrapper::Helpers

Defined in:
lib/tfwrapper/helpers.rb

Overview

generic helper functions for TFWrapper

Class Method Summary collapse

Class Method Details

.check_env_vars(required, allowed_missing) ⇒ Object

Ensure that a given list of environment variables are present and non-empty. Raise StandardError if any aren’t.

Parameters:

  • required (Array)

    list of required environment variables

  • allowed_missing (Array)

    list of environment variables to allow to be empty or missing.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/tfwrapper/helpers.rb', line 83

def self.check_env_vars(required, allowed_missing)
  missing = []
  required.each do |name|
    next if allowed_missing.include?(name)
    if !ENV.include?(name)
      puts "ERROR: Environment variable '#{name}' must be set."
      missing << name
    elsif ENV[name].to_s.strip.empty?
      puts "ERROR: Environment variable '#{name}' must not be empty."
      missing << name
    end
  end
  # rubocop:disable Style/GuardClause
  unless missing.empty?
    raise StandardError, 'Missing or empty environment variables: ' \
      "#{missing}"
  end
  # rubocop:enable Style/GuardClause
end

.run_cmd(cmd) ⇒ Object

Run a system command, print the command before running it. If it exits with a non-zero status, print the exit status and output and then ‘fail`.

Parameters:

  • cmd (String)

    the command to run

Raises:

  • (StandardError)


15
16
17
18
19
20
21
22
23
# File 'lib/tfwrapper/helpers.rb', line 15

def self.run_cmd(cmd)
  puts "Running command: #{cmd}"
  out = `#{cmd}`
  status = $CHILD_STATUS.exitstatus
  return if status.zero?
  puts "Command exited #{status}:"
  puts out
  raise StandardError, "ERROR: Command failed: #{cmd}"
end

.run_cmd_stream_output(cmd, pwd, opts = {}) ⇒ Array

popen2e wrapper to simultaneously stream command output and capture it.

STDOUT and STDERR will be combined to the same stream, and returned as one string. This is because there doesn’t seem to be a safe, cross-platform way to both capture and stream STDOUT and STDERR separately that isn’t prone to deadlocking if large chunks of data are written to the pipes.

Parameters:

  • cmd (String)

    command to run

  • pwd (String)

    directory/path to run command in

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :progress (Hash)

    How to handle streaming output. Possible values are “:stream“ (default) to stream each line in STDOUT/STDERR to STDOUT, “:dots“ to print a dot for each line, “:lines“ to print a dot followed by a newline for each line, or “nil“ to not stream any output at all.

Returns:

  • (Array)
    • out_err [String], exit code [Fixnum]



40
41
42
43
44
45
46
47
48
49
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
# File 'lib/tfwrapper/helpers.rb', line 40

def self.run_cmd_stream_output(cmd, pwd, opts = {})
  stream_type = opts.fetch(:progress, :stream)
  unless [:dots, :lines, :stream, nil].include?(stream_type)
    raise(
      ArgumentError,
      'progress option must be one of: [:dots, :lines, :stream, nil]'
    )
  end
  old_sync = $stdout.sync
  $stdout.sync = true
  all_out_err = ''.dup
  exit_status = nil
  Open3.popen2e(cmd, chdir: pwd) do |stdin, stdout_and_err, wait_thread|
    stdin.close_write
    begin
      while (line = stdout_and_err.gets)
        if stream_type == :stream
          puts line
        elsif stream_type == :dots
          STDOUT.print '.'
        elsif stream_type == :lines
          puts '.'
        end
        all_out_err << line
      end
    rescue IOError => e
      STDERR.puts "IOError: #{e}"
    end
    exit_status = wait_thread.value.exitstatus
  end
  # rubocop:disable Style/RedundantReturn
  $stdout.sync = old_sync
  puts '' if stream_type == :dots
  return all_out_err, exit_status
  # rubocop:enable Style/RedundantReturn
end