Module: RSpecTracer::CLI::Doctor Private
- Defined in:
- lib/rspec_tracer/cli/doctor.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 doctor` — diagnose config + environment. Reports Ruby + rspec-tracer versions, project root resolution, cache / coverage / report directory state, and SimpleCov / Rails presence. Exits 0 on healthy diagnosis, 1 if any check fails.
Constant Summary collapse
- REMOTE_CACHE_PROBES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
When remote_cache is configured, verify the backend is reachable from doctor’s vantage point so the user catches misconfig (typo’d S3 path / unreachable Redis URL / unwritable local-fs dir) BEFORE the next CI run fails. Best-effort: never FAIL the gate, just surface a WARN/INFO line.
{ s3: ->(opts) { remote_cache_s3_check(opts) }, local_fs: ->(opts) { remote_cache_local_fs_check(opts) }, redis: ->(opts) { remote_cache_redis_check(opts) } }.freeze
Class Method Summary collapse
-
.ar_schema_enabled? ⇒ Boolean
private
Internal helper for the tracer pipeline.
-
.ar_schema_narrow_attribution_check ⇒ Object
private
Surface the narrow-attribution precondition at diagnostic time.
-
.cache_path_check ⇒ Object
private
Internal helper for the tracer pipeline.
-
.cache_schema_version_check ⇒ Object
private
Surface a 1.x->2.0 cache mismatch BEFORE the user runs rspec and watches everything re-run mysteriously.
-
.coverage_path_check ⇒ Object
private
Internal helper for the tracer pipeline.
-
.git_check ⇒ Object
private
Internal helper for the tracer pipeline.
-
.path_check(label, path) ⇒ Object
private
Internal helper for the tracer pipeline.
-
.print_help(stdout) ⇒ Object
private
Internal helper for the tracer pipeline.
-
.project_root_check ⇒ Object
private
Internal helper for the tracer pipeline.
-
.rails_check ⇒ Object
private
Internal helper for the tracer pipeline.
-
.rails_loaded? ⇒ Boolean
private
Internal helper for the tracer pipeline.
-
.remote_cache_check ⇒ Object
private
Internal helper for the tracer pipeline.
-
.remote_cache_entry ⇒ Object
private
Internal helper for the tracer pipeline.
-
.remote_cache_local_fs_check(opts) ⇒ Object
private
Internal helper for the tracer pipeline.
-
.remote_cache_redis_check(opts) ⇒ Object
private
Internal helper for the tracer pipeline.
-
.remote_cache_s3_check(opts) ⇒ Object
private
Internal helper for the tracer pipeline.
-
.report_path_check ⇒ Object
private
Internal helper for the tracer pipeline.
-
.ruby_version_check ⇒ Object
private
Internal helper for the tracer pipeline.
-
.run(args, stdout: $stdout, stderr: $stderr) ⇒ Integer
private
Exit status (0 = healthy, 1 = any check FAILed; warnings keep status 0).
-
.simplecov_check ⇒ Object
private
Internal helper for the tracer pipeline.
-
.tracer_version_check ⇒ Object
private
Internal helper for the tracer pipeline.
-
.transactional_fixtures_default? ⇒ Boolean
private
Internal helper for the tracer pipeline.
Class Method Details
.ar_schema_enabled? ⇒ Boolean
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.
249 250 251 252 253 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 249 def self.ar_schema_enabled? return false unless RSpecTracer.respond_to?(:track_ar_schema_notifications?) RSpecTracer.track_ar_schema_notifications? end |
.ar_schema_narrow_attribution_check ⇒ 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.
Surface the narrow-attribution precondition at diagnostic time. When ‘track_ar_schema_notifications` is enabled AND Rails is loaded AND the rspec-rails default `use_transactional_fixtures
true` is in effect, per-example BEGIN/COMMIT fires
‘sql.active_record` inside the rspec-tracer bucket and attribution silently widens. Same shape as the boot-time warn in RSpecTracer.start, surfaced here so users running `rspec-tracer doctor` see the issue without having to boot a full rspec run first.
234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 234 def self.ar_schema_narrow_attribution_check return 'INFO AR schema: track_ar_schema_notifications not enabled' unless ar_schema_enabled? return 'INFO AR schema: Rails not loaded' unless rails_loaded? if transactional_fixtures_default? 'WARN AR schema: track_ar_schema_notifications + use_transactional_fixtures=true ' \ 'silently widens to whole-suite-on-schema-change. See README ' \ 'section "Narrow AR schema attribution".' else 'OK AR schema: narrow attribution preconditions look good' end end |
.cache_path_check ⇒ 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.
76 77 78 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 76 def self.cache_path_check path_check('cache_path:', RSpecTracer.cache_path) end |
.cache_schema_version_check ⇒ 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.
Surface a 1.x->2.0 cache mismatch BEFORE the user runs rspec and watches everything re-run mysteriously. Reads the cached ‘last_run.json` (if any) and compares its `schema_version` against the gem’s ‘Schema::CURRENT`. Three outcomes: no cache yet (INFO), match (OK), or mismatch (WARN with the cold-run note). Never FAIL - schema mismatches are the documented cold-run path, not a hard error.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 139 def self.cache_schema_version_check require 'rspec_tracer/storage/schema' require 'json' cache_path = RSpecTracer.cache_path last_run_path = File.join(cache_path.to_s, 'last_run.json') unless File.file?(last_run_path) return 'INFO schema: no cache yet (next rspec run is cold; expected on first install)' end manifest = JSON.parse(File.read(last_run_path, encoding: 'UTF-8')) stored = manifest['schema_version'] current = RSpecTracer::Storage::Schema::CURRENT if stored == current "OK schema: v#{current} (matches gem)" else "WARN schema: stored v#{stored.inspect} != gem v#{current} " \ '(next rspec run is a cold run; expected on 1.x->2.0 upgrade)' end rescue StandardError => e "WARN schema: could not read cache manifest: #{e.class}: #{e.}" end |
.coverage_path_check ⇒ 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.
82 83 84 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 82 def self.coverage_path_check path_check('coverage_path:', RSpecTracer.coverage_path) end |
.git_check ⇒ 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.
104 105 106 107 108 109 110 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 104 def self.git_check if system('git', 'rev-parse', 'HEAD', out: File::NULL, err: File::NULL) 'OK git: HEAD reachable (remote_cache will work)' else 'WARN git: not in a git repo (remote_cache will degrade gracefully)' end end |
.path_check(label, path) ⇒ 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.
94 95 96 97 98 99 100 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 94 def self.path_check(label, path) return "FAIL #{label} <missing>" if path.nil? || path.empty? return "FAIL #{label} #{path} (does not exist)" unless File.directory?(path) return "FAIL #{label} #{path} (not writable)" unless File.writable?(path) "OK #{label} #{path}" end |
.print_help(stdout) ⇒ 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.
46 47 48 49 50 51 52 53 54 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 46 def self.print_help(stdout) stdout.puts <<~HELP Usage: rspec-tracer doctor Diagnose rspec-tracer config and environment. Prints a checklist of versions, paths, and integrations; exits 0 if all checks pass. HELP 0 end |
.project_root_check ⇒ 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.
70 71 72 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 70 def self.project_root_check "OK root: #{RSpecTracer.root}" end |
.rails_check ⇒ 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.
124 125 126 127 128 129 130 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 124 def self.rails_check if defined?(::Rails::VERSION) && !::Rails::VERSION.nil? "OK Rails: #{::Rails::VERSION::STRING}" else 'INFO Rails: not loaded (this is fine for non-Rails projects)' end end |
.rails_loaded? ⇒ Boolean
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.
257 258 259 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 257 def self.rails_loaded? defined?(::Rails::VERSION) && !::Rails::VERSION.nil? end |
.remote_cache_check ⇒ 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.
175 176 177 178 179 180 181 182 183 184 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 175 def self.remote_cache_check entry = remote_cache_entry return 'INFO remote_cache: not configured (skip)' unless entry backend, opts = entry probe = REMOTE_CACHE_PROBES[backend] return "INFO remote_cache: custom backend #{backend.inspect} (skipping reachability probe)" if probe.nil? instance_exec(opts, &probe) end |
.remote_cache_entry ⇒ 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.
188 189 190 191 192 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 188 def self.remote_cache_entry return nil unless RSpecTracer.respond_to?(:remote_cache_backend_entry) RSpecTracer.remote_cache_backend_entry end |
.remote_cache_local_fs_check(opts) ⇒ 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.
206 207 208 209 210 211 212 213 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 206 def self.remote_cache_local_fs_check(opts) path = opts[:path] || opts['path'] return 'WARN remote_cache: :local_fs configured without :path' if path.nil? || path.empty? return "WARN remote_cache: :local_fs path #{path} does not exist" unless File.directory?(path) return "WARN remote_cache: :local_fs path #{path} not writable" unless File.writable?(path) "OK remote_cache: :local_fs path=#{path}" end |
.remote_cache_redis_check(opts) ⇒ 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.
217 218 219 220 221 222 223 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 217 def self.remote_cache_redis_check(opts) url = opts[:url] || opts['url'] || ENV.fetch('RSPEC_TRACER_REMOTE_CACHE_URI', nil) return 'WARN remote_cache: :redis configured without :url' if url.nil? || url.empty? "OK remote_cache: :redis url=#{url} " \ '(reachability not probed locally; verified end-to-end on next CI run)' end |
.remote_cache_s3_check(opts) ⇒ 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.
196 197 198 199 200 201 202 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 196 def self.remote_cache_s3_check(opts) bucket = opts[:bucket] || opts['bucket'] return 'WARN remote_cache: :s3 configured without :bucket' if bucket.nil? || bucket.empty? "OK remote_cache: :s3 bucket=#{bucket} " \ '(reachability not probed locally; verified end-to-end on next CI run)' end |
.report_path_check ⇒ 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.
88 89 90 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 88 def self.report_path_check path_check('report_path:', RSpecTracer.report_path) end |
.ruby_version_check ⇒ 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.
58 59 60 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 58 def self.ruby_version_check "OK ruby: #{RUBY_DESCRIPTION}" 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 = healthy, 1 = any check FAILed; warnings keep status 0).
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 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 17 def self.run(args, stdout: $stdout, stderr: $stderr) return print_help(stdout) if args.include?('-h') || args.include?('--help') require 'rspec_tracer/load_config' checks = [ ruby_version_check, tracer_version_check, project_root_check, cache_path_check, coverage_path_check, report_path_check, git_check, simplecov_check, rails_check, cache_schema_version_check, remote_cache_check, ar_schema_narrow_attribution_check ] checks.each { |line| stdout.puts line } ok = checks.none? { |line| line.start_with?('FAIL') } ok ? 0 : 1 rescue StandardError => e stderr.puts "doctor: #{e.class}: #{e.}" 1 end |
.simplecov_check ⇒ 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.
114 115 116 117 118 119 120 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 114 def self.simplecov_check if defined?(::SimpleCov) 'OK SimpleCov: loaded (interop active)' else 'INFO SimpleCov: not loaded (this is fine; SimpleCov is optional)' end end |
.tracer_version_check ⇒ 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.
64 65 66 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 64 def self.tracer_version_check "OK rspec-tracer: #{RSpecTracer::VERSION}" end |
.transactional_fixtures_default? ⇒ Boolean
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.
263 264 265 266 267 268 269 270 271 272 |
# File 'lib/rspec_tracer/cli/doctor.rb', line 263 def self.transactional_fixtures_default? return false unless defined?(::RSpec) && ::RSpec.respond_to?(:configuration) cfg = ::RSpec.configuration return false unless cfg.respond_to?(:use_transactional_fixtures) cfg.use_transactional_fixtures != false rescue StandardError false end |