Top Level Namespace

Defined Under Namespace

Modules: Zip Classes: Add, Analyze, Array, Build, Command, Commands, Commit, Dev, Dir, Doc, Environment, File, Gemspec, Git, GitUrl, Hash, History, Internet, MSBuild, Nuget, Package, Project, Projects, Publish, Pull, Push, Setup, String, Svn, Tasks, Test, Text, Timer, Update, Version, Wix, XCodeBuild

Constant Summary collapse

DELIMITER =
"==================================================================================="
DEV =
Dev.new
COMMANDS =
Commands.new
MSBUILD =
MSBuild.new
TIMER =
Timer.new
NUNIT =
FileList.new("**/bin/**/*.Test.dll", "**/bin/**/*.Tests.dll", "**/lib/**/*.Test.dll",
"**/lib/**/*.Tests.dll")
SOURCE =
FileList.new("LICENSE", "README", "README.md", "Gemfile")
SLN_FILES =
FileList.new("*.sln", "*/*.sln", "*/*/*.sln")
WXS_FILES =
FileList.new("**/*.wxs")
SMARTASSEMBLY_FILES =
FileList.new("**/*.saproj")
BUFFER_SIZE =
1024
VERSION =
Version.get_version
NUGET_FILES =
FileList.new("**/*.nuspec")

Instance Method Summary collapse

Instance Method Details

#run_with_timeout(directory, command, timeout, tick) ⇒ Object

The following code is based on code originally 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.



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
49
50
51
52
53
54
55
# File 'lib/base/timeout.rb', line 16

def run_with_timeout(directory, command, timeout, tick)
  output = ""
  exit_code = 1

  Open3.popen2e(command, chdir: directory) do |_stdin, stderrout, thread|
    pid = thread.pid

    start = Time.now
    while ((Time.now - start) < timeout) && 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...
        exit_code = wait_thread.value
        break
      end

      sleep(0.5)
    end

    exit_code = wait_thread.value

    # 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)
      exit_code = 5
    end
  end

  [output, exit_code]
end

#run_with_timeout2(directory, command, timeout) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/base/timeout.rb', line 100

def run_with_timeout2(directory, command, timeout)
  # stdout, stderr pipes
  rout, wout = IO.pipe
  rerr, werr = IO.pipe
  output = ""
  error = ""
  exit_code = 1
  pid = Process.spawn(command, chdir: directory, out: wout, err: werr)
  begin
    Timeout.timeout(timeout) do
      exit_code = Process.wait2(pid)
      output = rout.readlines.join("\n")
      error = rerr.readlines.join("\n")
    end
  rescue StandardError
    Proces.kill("TERM", pid)
    output = "#{output}timeout occurred."
  ensure
    rout.close
    rerr.close
  end
  [output, exit_code]
end