Module: Terraspace::Util::Popen

Includes:
Logging
Included in:
Cloud::Cost::Infracost
Defined in:
lib/terraspace/util/popen.rb

Constant Summary collapse

BLOCK_SIZE =
Integer(ENV['TS_BUFFER_BLOCK_SIZE'] || 102400)

Instance Method Summary collapse

Methods included from Logging

#logger

Instance Method Details

#all_eof?(files) ⇒ Boolean

Returns:

  • (Boolean)


62
63
64
# File 'lib/terraspace/util/popen.rb', line 62

def all_eof?(files)
  files.find { |f| !f.eof }.nil?
end

#handle_stderr(line, options = {}) ⇒ Object



58
59
60
# File 'lib/terraspace/util/popen.rb', line 58

def handle_stderr(line, options={})
  logger.error(line) unless line.include?(options[:filter])
end

#handle_stdout(line, options = {}) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/terraspace/util/popen.rb', line 44

def handle_stdout(line, options={})
  newline = options[:newline].nil? ? true : options[:newline]
  filter = options[:filter]

  # Terraspace logger has special stdout method so original terraform output
  # can be piped to jq. IE:
  #   terraspace show demo --json | jq
  if logger.respond_to?(:stdout) && !options[:log_to_stderr]
    logger.stdout(line, newline: newline) unless line.include?(filter)
  else
    logger.info(line) unless line.include?(filter)
  end
end

#handle_streams(stdin, stdout, stderr, options) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/terraspace/util/popen.rb', line 21

def handle_streams(stdin, stdout, stderr, options)
  files = [stdout, stderr]
  until all_eof?(files) do
    ready = IO.select(files)
    next unless ready

    readable = ready[0]
    readable.each do |f|
      buffer = f.read_nonblock(BLOCK_SIZE, exception: false)
      next unless buffer

      lines = buffer.split("\n")
      lines.each do |line|
        if f.fileno == stdout.fileno
          handle_stdout(line, options)
        else
          handle_stderr(line, options)
        end
      end
    end
  end
end

#popen(command, options = {}) ⇒ Object

Similar to Terraspace::Shell#popen3 More generalized. Useful for plugins



9
10
11
12
13
14
15
16
17
18
# File 'lib/terraspace/util/popen.rb', line 9

def popen(command, options={})
  Open3.popen3(command) do |stdin, stdout, stderr, wait_thread|
    handle_streams(stdin, stdout, stderr, options)
    status = wait_thread.value.exitstatus
    unless status == 0
      logger.error "Error running command #{command}".color(:red)
      exit 1
    end
  end
end