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, env = nil) ⇒ Command

Returns a new instance of Command.



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

def initialize(cmd_str, env = nil)
  @cmd_str = cmd_str
  @env     = stringify_hash(env || {})
  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

#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



108
109
110
111
112
113
# File 'lib/scmd/command.rb', line 108

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

#killObject



89
90
91
92
93
94
# File 'lib/scmd/command.rb', line 89

def kill
  return if !running?

  send_kill
  wait # indefinitely until cmd is killed
end

#run(input = nil) ⇒ Object



26
27
28
29
# File 'lib/scmd/command.rb', line 26

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

#run!(input = nil) ⇒ Object



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

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)


96
97
98
# File 'lib/scmd/command.rb', line 96

def running?
  !@child_process.nil?
end

#start(input = nil) ⇒ Object



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

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



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

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)


100
101
102
# File 'lib/scmd/command.rb', line 100

def success?
  @exitstatus == 0
end

#to_sObject



104
105
106
# File 'lib/scmd/command.rb', line 104

def to_s
  @cmd_str.to_s
end

#wait(timeout = nil) ⇒ Object



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

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