class Gitlab::QA::Support::ShellCommand

def execute! # rubocop:disable Metrics/AbcSize

rubocop:disable Metrics/AbcSize
def execute! # rubocop:disable Metrics/AbcSize
  raise StatusError, 'Command already executed' if output.any?
  logger.info("Shell command: `#{mask_secrets(command).cyan}`")
  Open3.popen2e(command.to_s) do |stdin, out, wait|
    if @stdin_data
      stdin.puts(@stdin_data)
      stdin.close
    end
    out.each do |line|
      output.push(line)
      if stream_progress
        print "."
      elsif stream_output
        puts line
      end
      yield line, wait if block_given?
    end
    puts if stream_progress && !output.empty?
    fail! if wait.value.exited? && wait.value.exitstatus.nonzero?
    logger.debug("Shell command output:\n#{string_output}") unless stream_output || output.empty?
  end
  string_output
end

def fail!

Returns:
  • (void) -
def fail!
  logger.error("Shell command output:\n#{string_output}") unless stream_output
  raise StatusError, "Command `#{mask_secrets(command).truncate(100)}` failed! " + "✘".red
end

def initialize(command = nil, stdin_data: nil, mask_secrets: nil, stream_output: false)

Parameters:
  • stream_output (Boolean) -- stream command output to stdout directly instead of logger
  • mask_secrets () --
  • command () --
def initialize(command = nil, stdin_data: nil, mask_secrets: nil, stream_output: false)
  @command = command
  @mask_secrets = Array(mask_secrets)
  @stream_output = stream_output
  @output = []
  @logger = Runtime::Logger.logger
  @stdin_data = stdin_data
end

def mask_secrets(input)

Returns:
  • (String) - The masked string

Parameters:
  • input (String) -- the string to mask
def mask_secrets(input)
  @mask_secrets.reduce(input) { |s, secret| s.gsub(secret, '*****') }.to_s
end

def stream_progress

Returns:
  • (Boolean) -
def stream_progress
  !(Runtime::Env.ci || stream_output)
end

def string_output

Returns:
  • (String) -
def string_output
  mask_secrets(output.join.chomp)
end