Class: Scmd::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/scmd/command.rb

Defined Under Namespace

Classes: ChildProcess

Constant Summary collapse

READ_SIZE =

bytes

10240
READ_CHECK_TIMEOUT =

seconds

0.001
DEFAULT_STOP_TIMEOUT =

seconds

3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cmd_str, opts = nil) ⇒ Command

Returns a new instance of Command.



20
21
22
23
24
25
26
# File 'lib/scmd/command.rb', line 20

def initialize(cmd_str, opts = nil)
  opts ||= {}
  @cmd_str = cmd_str
  @env     = stringify_hash(opts[:env] || {})
  @options = opts[:options] || {}
  reset_attrs
end

Instance Attribute Details

#cmd_strObject (readonly)

Returns the value of attribute cmd_str.



17
18
19
# File 'lib/scmd/command.rb', line 17

def cmd_str
  @cmd_str
end

#envObject (readonly)

Returns the value of attribute env.



17
18
19
# File 'lib/scmd/command.rb', line 17

def env
  @env
end

#exitstatusObject (readonly)

Returns the value of attribute exitstatus.



18
19
20
# File 'lib/scmd/command.rb', line 18

def exitstatus
  @exitstatus
end

#optionsObject (readonly)

Returns the value of attribute options.



17
18
19
# File 'lib/scmd/command.rb', line 17

def options
  @options
end

#pidObject (readonly)

Returns the value of attribute pid.



18
19
20
# File 'lib/scmd/command.rb', line 18

def pid
  @pid
end

#stderrObject (readonly)

Returns the value of attribute stderr.



18
19
20
# File 'lib/scmd/command.rb', line 18

def stderr
  @stderr
end

#stdoutObject (readonly)

Returns the value of attribute stdout.



18
19
20
# File 'lib/scmd/command.rb', line 18

def stdout
  @stdout
end

Instance Method Details

#inspectObject



110
111
112
113
114
115
# File 'lib/scmd/command.rb', line 110

def inspect
  reference = '0x0%x' % (self.object_id << 1)
  "#<#{self.class}:#{reference}"\
  " @cmd_str=#{self.cmd_str.inspect}"\
  " @exitstatus=#{@exitstatus.inspect}>"
end

#kill(signal = nil) ⇒ Object



91
92
93
94
95
96
# File 'lib/scmd/command.rb', line 91

def kill(signal = nil)
  return if !running?

  send_kill(signal)
  wait # indefinitely until cmd is killed
end

#run(input = nil) ⇒ Object



28
29
30
31
# File 'lib/scmd/command.rb', line 28

def run(input = nil)
  run!(input) rescue RunError
  self
end

#run!(input = nil) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/scmd/command.rb', line 33

def run!(input = nil)
  start_err_msg, start_err_bt = nil, nil
  begin
    start(input)
  rescue StandardError => err
    start_err_msg, start_err_bt = err.message, err.backtrace
  ensure
    wait # indefinitely until cmd is done running
    raise RunError.new(start_err_msg || @stderr, start_err_bt || caller) if !success?
  end

  self
end

#running?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/scmd/command.rb', line 98

def running?
  !@child_process.nil?
end

#start(input = nil) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/scmd/command.rb', line 47

def start(input = nil)
  setup_run

  @pid = @child_process.pid.to_i
  @child_process.write(input)
  @read_output_thread = Thread.new do
    while @child_process.check_for_exit
      begin
        read_output
      rescue EOFError => err
      end
    end
    @stop_w.write_nonblock('.')
  end
end

#stop(timeout = nil) ⇒ Object



80
81
82
83
84
85
86
87
88
89
# File 'lib/scmd/command.rb', line 80

def stop(timeout = nil)
  return if !running?

  send_term
  begin
    wait(timeout || DEFAULT_STOP_TIMEOUT)
  rescue TimeoutError => err
    kill
  end
end

#success?Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/scmd/command.rb', line 102

def success?
  @exitstatus == 0
end

#to_sObject



106
107
108
# File 'lib/scmd/command.rb', line 106

def to_s
  @cmd_str.to_s
end

#wait(timeout = nil) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/scmd/command.rb', line 63

def wait(timeout = nil)
  return if !running?

  wait_for_exit(timeout)
  if @child_process.running?
    kill
    raise(TimeoutError, "`#{@cmd_str}` timed out (#{timeout}s).")
  end
  @read_output_thread.join

  @stdout << @child_process.flush_stdout
  @stderr << @child_process.flush_stderr
  @exitstatus = @child_process.exitstatus

  teardown_run
end