Class: Rails::Hyperdrive::Tools::LookupDoc

Inherits:
Base
  • Object
show all
Defined in:
lib/rails/hyperdrive/tools/lookup_doc.rb

Defined Under Namespace

Classes: FakeStatus

Constant Summary collapse

RI_TIMEOUT_SECONDS =
10

Class Method Summary collapse

Methods inherited from Base

respond_error, respond_json, respond_text, with_dev_guard

Class Method Details

.call(reference:, server_context: nil) ⇒ Object



21
22
23
24
25
26
27
28
29
30
# File 'lib/rails/hyperdrive/tools/lookup_doc.rb', line 21

def self.call(reference:, server_context: nil)
  with_dev_guard do
    ref = reference.to_s.strip
    stdout, stderr, status = run_ri(ref)
    return respond_error("ri not available") if status.nil?
    return respond_text(stdout) if status.success?
    first_stderr_line = stderr.to_s.lines.first.to_s.strip
    respond_error("ri exited #{status.exitstatus}: #{first_stderr_line}")
  end
end

.run_ri(reference) ⇒ Object

The manual timeout lets a hung ri be TERMed; a missing ri returns [nil, nil, nil].



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rails/hyperdrive/tools/lookup_doc.rb', line 34

def self.run_ri(reference)
  Open3.popen3("ri", "-T", "--format=markdown", reference) do |_in, out, err, wait_thr|
    begin
      ::Timeout.timeout(RI_TIMEOUT_SECONDS) do
        stdout = out.read
        stderr = err.read
        [stdout, stderr, wait_thr.value]
      end
    rescue ::Timeout::Error
      begin
        Process.kill("TERM", wait_thr.pid)
      rescue Errno::ESRCH
      end
      ["", "ri timeout after #{RI_TIMEOUT_SECONDS}s", FakeStatus.new(124)]
    end
  end
rescue Errno::ENOENT
  [nil, nil, nil]
end