Top Level Namespace

Defined Under Namespace

Classes: Add, Analyze, Array, Build, Clean, Clobber, Command, Commands, Commit, Doc, Gemspec, Git, Hash, Internet, MSBuild, Publish, Pull, Push, Setup, Test, Text, Timer, Update, Upgrade

Constant Summary collapse

INFO =
Array.new
BUFFER_SIZE =
1024
SOURCE =
FileList.new('LICENSE','README','README.md',"Gemfile")
COMMANDS =
Commands.new
MSBUILD =
MSBuild.new

Instance Method Summary collapse

Instance Method Details

#run_with_timeout(command, timeout, tick) ⇒ Object

The following code was copied from gist.github.com/lpar/1032297 Gist title: lpar/timeout.rb

Runs a specified shell command in a separate thread. If it exceeds the given timeout in seconds, kills it. Returns any output produced by the command (stdout or stderr) as a String. Uses Kernel.select to wait up to the tick length (in seconds) between checks on the command’s status

If you’ve got a cleaner way of doing this, I’d be interested to see it. If you think you can do it with Ruby’s Timeout module, think again.



13
14
15
16
17
18
19
20
21
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
48
# File 'lib/timeout.rb', line 13

def run_with_timeout(command, timeout, tick)
  output = ''
  begin
    # Start task in another thread, which spawns a process
    stdin, stderrout, thread = Open3.popen2e(command)
    # Get the pid of the spawned process
    pid = thread[:pid]
    start = Time.now

    while (Time.now - start) < timeout and thread.alive?
      # Wait up to `tick` seconds for output/error data
      Kernel.select([stderrout], nil, nil, tick)
      # Try to read the data
      begin
        output << stderrout.read_nonblock(BUFFER_SIZE)
      rescue IO::WaitReadable
        # A read would block, so loop around for another select
      rescue EOFError
        # Command has completed, not really an error...
        break
      end
    end
    # Give Ruby time to clean up the other thread
    sleep 1

    if thread.alive?
      # We need to kill the process, because killing the thread leaves
      # the process alive but detached, annoyingly enough.
      Process.kill("TERM", pid)
    end
  ensure
    stdin.close if stdin
    stderrout.close if stderrout
  end
  return output
end