Module: RakeScript::Shell

Included in:
RakeMethods
Defined in:
lib/rake_script/shell.rb

Instance Method Summary collapse

Instance Method Details

#cmd(command, *arguments) ⇒ Object

Wrapper around #execute which raise RuntimeError when command was exited unsuccessfully. Prefer to use this method unless you allow some command to fail.

Parameters:

  • command (String)

    shell command.

  • arguments (Array<String, Hash>)

    command arguments with optional last hash.



11
12
13
14
15
16
# File 'lib/rake_script/shell.rb', line 11

def cmd(command, *arguments)
  result = execute(command, *arguments)
  if result[:code] != 0
    raise RuntimeError, "command #{result[:command].inspect} failed with code: #{result[:code]}"
  end
end

#execute(command, *arguments) ⇒ Hash

Executes shell command and stream it’s output.

Parameters:

  • command (String)

    shell command.

  • arguments (Array<String, Hash>)

    command arguments with optional last hash, last arguments hash keys: :stdout [Proc<String>] each command output line will be passed to this proc (print to STDOUT by default), :stderr [Proc<String>] each command error output line will be passed to this proc (print to STDERR by default), :env [Hash] optional environment hash, :debug [TruClass,FalseClass] prints command before execution (true by default), :debug_color [Symbol] color of debug print (@see RakeScript::Formatting::PROMPT_COLORS), :debug_style [Symbol] style of debug print (@see RakeScript::Formatting::PROMPT_STYLES).

Returns:

  • (Hash)

    hash with keys: :code [Integer] exit code status of command, :command [String] command line without environment.



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
59
60
61
# File 'lib/rake_script/shell.rb', line 31

def execute(command, *arguments)
  # extracting options
  options = arguments.last.is_a?(Hash) ? arguments.pop : {}

  # extract option keys
  stdout = options.fetch(:stdout) { proc { |raw_line| STDOUT.puts(raw_line) } }
  stderr = options.fetch(:stderr) { proc { |raw_line| STDERR.puts(raw_line) } }
  env = options.fetch(:env, {})
  debug = options.fetch(:debug, true)
  debug_color = options.fetch(:debug_color, :light_cyan)
  debug_style = options.fetch(:debug_style, :underlined)

  # calculating command line
  env_str = env.map { |k, v| "#{k}=#{v}" }.join(' ')
  command_line = ([env_str, command] + arguments).reject(&:empty?).join(' ')

  # debugging
  if debug
    if respond_to?(:puts_colored, true)
      puts_colored(command_line, color: debug_color, style: debug_style)
    else
      puts command_line
    end
  end

  # execution
  status = raw_execute(command_line, stdout: stdout, stderr: stderr)

  # response
  { code: status.exitstatus, command: command_line }
end

#raw_execute(command_line, stdout:, stderr:) ⇒ Process::Status

Executes shell command and stream it’s output.

Parameters:

  • command_line (String)

    command line to execute.

  • stdout (Proc)

    each command output line will be passed to this proc.

  • stderr (Proc)

    each command error output line will be passed to this proc.

Returns:

  • (Process::Status)

    status object for command.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/rake_script/shell.rb', line 68

def raw_execute(command_line, stdout:, stderr:)
  Open3.popen3(command_line) do |_stdin_io, stdout_io, stderr_io, wait_thread|
    Thread.new do
      until (raw_line = stdout_io.gets).nil? do
        stdout.call(raw_line)
      end
    end
    Thread.new do
      until (raw_line = stderr_io.gets).nil? do
        stderr.call(raw_line)
      end
    end
    wait_thread.value
  end
end