Module: Moonshot::Shell

Overview

Mixin providing the Thor::Shell methods and other shell execution helpers.

Constant Summary collapse

CommandError =
Class.new(RuntimeError)
DEFAULT_RETRY_OPTIONS =

Retry every 10 seconds for a maximum of 2 minutes.

{
  on: RuntimeError,
  tries: 50,
  multiplier: 1,
  base_interval: 10,
  max_elapsed_time: 120,
  rand_factor: 0
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.sh_out(cmd, fail = true, stdin = '') ⇒ Object

Run a command, returning stdout. Stderr is suppressed unless the command returns non-zero.



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
# File 'lib/moonshot/shell.rb', line 22

def sh_out(cmd, fail = true, stdin = '')
  r_in, w_in = IO.pipe
  r_out, w_out = IO.pipe
  r_err, w_err = IO.pipe
  w_in.write(stdin)
  w_in.close
  pid = Process.spawn(cmd, in: r_in, out: w_out, err: w_err)
  Process.wait(pid)

  r_in.close
  w_out.close
  w_err.close
  stdout = r_out.read
  r_out.close
  stderr = r_err.read
  r_err.close

  if fail && $CHILD_STATUS.exitstatus != 0
    raise CommandError, "`#{cmd}` exited #{$CHILD_STATUS.exitstatus}\n" \
         "stdout:\n" \
         "#{stdout}\n" \
         "stderr:\n" \
         "#{stderr}\n"
  end
  stdout
end

Instance Method Details

#sh_retry(cmd, fail = true, stdin = '', opts: {}) ⇒ String

Retries every second upto maximum of 2 minutes with the default options.

Parameters:

  • cmd (String)

    command to execute.

  • fail (Boolean) (defaults to: true)

    Raise error when the command exits with non-zero.

  • stdin (String) (defaults to: '')

    Input to the command.

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

    Options for retriable.

Returns:

  • (String)

    Stdout form the command.



76
77
78
79
80
81
82
83
84
# File 'lib/moonshot/shell.rb', line 76

def sh_retry(cmd, fail = true, stdin = '', opts: {})
  Retriable.retriable(DEFAULT_RETRY_OPTIONS.merge(opts)) do
    out = sh_out(cmd, stdin:)
    yield out if block_given?
    out
  end
rescue CommandError => e
  raise e if fail
end

#sh_step(cmd, **args) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/moonshot/shell.rb', line 58

def sh_step(cmd, **args)
  msg = args.delete(:msg) || cmd
  msg = "#{msg[0..(terminal_width - 22)]}..." if msg.length > (terminal_width - 18)
  ilog.start_threaded(msg) do |step|
    out = sh_out(cmd, **args)
    yield step, out if block_given?
    step.success
  end
end

#shellObject



50
51
52
# File 'lib/moonshot/shell.rb', line 50

def shell
  @thor_shell ||= Thor::Base.shell.new
end