Module: RSpecTracer::CLI::ReportOpen Private

Defined in:
lib/rspec_tracer/cli/report_open.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

rspec-tracer report:open — open the HTML report in the default browser. Resolves report_path/index.html and dispatches via open (macOS) / xdg-open (Linux). Falls back to printing the path when no opener is available.

Class Method Summary collapse

Class Method Details

.detect_openerObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the opener binary name on PATH, or nil. Checked in priority order: macOS open, then Linux xdg-open. Windows is unsupported per COMPATIBILITY_MATRIX.md's explicit drop; users on Windows see the print-the-path fallback.



75
76
77
# File 'lib/rspec_tracer/cli/report_open.rb', line 75

def self.detect_opener
  %w[open xdg-open].find { |bin| which(bin) }
end

.launch(opener, index_path, stdout, stderr) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal helper for the tracer pipeline.



48
49
50
51
52
53
54
55
56
# File 'lib/rspec_tracer/cli/report_open.rb', line 48

def self.launch(opener, index_path, stdout, stderr)
  if system(opener, index_path, out: File::NULL, err: File::NULL)
    stdout.puts "report:open: opened #{index_path} via #{opener}"
    0
  else
    stderr.puts "report:open: failed to launch #{opener} #{index_path}"
    1
  end
end

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal helper for the tracer pipeline.



60
61
62
63
64
65
66
67
68
69
# File 'lib/rspec_tracer/cli/report_open.rb', line 60

def self.print_help(stdout)
  stdout.puts <<~HELP
    Usage: rspec-tracer report:open

    Open the HTML report (`report_path/index.html`) in the default
    browser. Uses `open` on macOS and `xdg-open` on Linux. Prints
    the path and exits 0 when no opener is available.
  HELP
  0
end

.run(args, stdout: $stdout, stderr: $stderr) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns exit status (0 = opened or path printed, 1 = report missing).

Parameters:

  • args (Array<String>)

    sub-command args (-h / --help).

  • stdout (IO) (defaults to: $stdout)
  • stderr (IO) (defaults to: $stderr)

Returns:

  • (Integer)

    exit status (0 = opened or path printed, 1 = report missing).



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
# File 'lib/rspec_tracer/cli/report_open.rb', line 17

def self.run(args, stdout: $stdout, stderr: $stderr)
  return print_help(stdout) if args.include?('-h') || args.include?('--help')

  report_path = RSpecTracer.report_path
  index_path = File.join(report_path, 'index.html')

  unless File.file?(index_path)
    stderr.puts "report:open: no report at #{index_path}"
    stderr.puts '  run rspec first to generate the HTML report'
    return 1
  end

  opener = detect_opener
  if opener.nil?
    stdout.puts "report:open: report at #{index_path}"
    stdout.puts '  no opener detected (open / xdg-open); open the path manually'
    return 0
  end

  launch(opener, index_path, stdout, stderr)
rescue Errno::EPIPE
  # Downstream pipe (`... | head`) closed early -- routine in
  # shell pipelines, not a failure. Exit 0 silently.
  0
rescue StandardError => e
  stderr.puts "report:open: #{e.class}: #{e.message}"
  1
end

.which(binary) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Internal helper for the tracer pipeline.



81
82
83
84
85
86
87
# File 'lib/rspec_tracer/cli/report_open.rb', line 81

def self.which(binary)
  found = ENV.fetch('PATH', '').split(File::PATH_SEPARATOR).any? do |dir|
    path = File.join(dir, binary)
    File.file?(path) && File.executable?(path)
  end
  found ? binary : nil
end