Class: Subcontractor::CLI

Inherits:
Object
  • Object
show all
Defined in:
lib/subcontractor/cli.rb

Instance Method Summary collapse

Instance Method Details

#find_child_pids(pids) ⇒ Object



70
71
72
73
74
75
# File 'lib/subcontractor/cli.rb', line 70

def find_child_pids(pids)
  lines = `ps axo pid,ppid`.lines
  child_pids = lines.map(&:split).select do |(child_pid, parent_pid)|
    pids.include?(parent_pid.to_i)
  end.map(&:first).map(&:to_i)
end

#find_pids_to_kill(*pids_to_investigate) ⇒ Object



61
62
63
64
65
66
67
68
# File 'lib/subcontractor/cli.rb', line 61

def find_pids_to_kill(*pids_to_investigate)
  pids_to_kill = pids_to_investigate
  begin
    pids_to_investigate = find_child_pids(pids_to_investigate)
    pids_to_kill = pids_to_investigate + pids_to_kill
  end until pids_to_investigate.empty?
  pids_to_kill
end

#parse_options(argv) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/subcontractor/cli.rb', line 77

def parse_options(argv)
  options = {}
  parser = OptionParser.new do |opt|
    opt.banner = "USAGE: subcontract [options] -- executable"
    opt.on("-r", "--rvm RVM", "run in a specific RVM") do |rvm|
      options[:rvm] = rvm
    end
    opt.on("-b", "--rbenv RBENV", "run in a specific RBENV") do |rbenv|
      options[:rbenv] = rbenv
    end
    opt.on("-h", "--chruby CHRUBY", "run in a specific CHRUBY") do |chruby|
      options[:chruby] = chruby
    end
    opt.on("-c", "--choose-env ENV", "run in either specified RBENV, RVM, or CHRUBY, whichever is present") do |env|
      options[:choose_env] = env
    end
    opt.on("-d", "--chdir PATH", "chdir to PATH before starting process") do |path|
      options[:chdir] = path
    end
    opt.on("-s", "--signal SIGNAL", "signal to send to process to kill it, default TERM") do |signal|
      options[:signal] = signal
    end
  end

  parser.parse! argv
  options
end

#runObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/subcontractor/cli.rb', line 39

def run
  options = parse_options(ARGV)
  command = Subcontractor::Command.build(ARGV, options)
  Dir.chdir(options[:chdir]) if options[:chdir]
  signal = options[:signal] || "TERM"
  SafePty.spawn(command) do |stdin, stdout, pid|
    trap("TERM") do
      send_kill(signal, find_pids_to_kill(pid))
    end
    trap("INT") do
      send_kill(signal, find_pids_to_kill(pid))
    end
    until stdin.eof?
      puts stdin.gets
    end
  end
end

#send_kill(signal, pids) ⇒ Object



57
58
59
# File 'lib/subcontractor/cli.rb', line 57

def send_kill(signal, pids)
  pids.each { |pid| Process.kill(signal, pid) }
end