Class: ReactOnRails::Doctor
- Inherits:
-
Object
- Object
- ReactOnRails::Doctor
- Includes:
- ConfigPathResolver, ShakapackerConfigHelpers
- Defined in:
- lib/react_on_rails/doctor.rb
Overview
rubocop:disable Metrics/ClassLength, Metrics/AbcSize
Constant Summary collapse
- MESSAGE_COLORS =
{ error: :red, warning: :yellow, success: :green, info: :blue }.freeze
- RSPEC_HELPER_FILES =
["spec/rails_helper.rb", "spec/spec_helper.rb"].freeze
- MINITEST_HELPER_FILE =
"test/test_helper.rb"- DEFAULT_BUILD_TEST_COMMAND =
'config.build_test_command = "RAILS_ENV=test bin/shakapacker"'- SERVER_BUNDLE_SOURCE_EXTENSIONS =
%w[.js .jsx .ts .tsx .mjs .cjs].freeze
- CUSTOM_LAUNCHER_INDICATOR_FILES =
%w[dev].freeze
- RAILS_SERVER_COMMAND_REGEX =
%r{\b(?:(?:bin/)?rails\s+(?:server|s)|puma|unicorn|rackup|passenger\s+start)\b}- DEPRECATED_RENDERER_CACHE_TASK =
Deprecated-renderer-cache scan (used by check_deprecated_renderer_cache_task): look for references to the old pre_stage_bundle_for_node_renderer task in common deploy-script locations so users on older Procfile/Dockerfile entries get a migration nudge before the task is removed.
"pre_stage_bundle_for_node_renderer"- RENDERER_CACHE_DEPLOY_SCRIPT_PATHS =
Fixed allowlist of single-file deploy-script paths. Each entry is a literal path that may host a deploy hook referencing the deprecated task. Directory globs (e.g., per-stage Capistrano files or per-workflow GitHub Actions YAML) live in RENDERER_CACHE_DEPLOY_SCRIPT_GLOBS so they stay bounded.
[ "Procfile", "Procfile.dev", "Procfile.dev-static-assets", "Procfile.production", "Dockerfile", "Dockerfile.production", "Dockerfile.staging", "Dockerfile.review", "docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml", "bin/deploy", "bin/release", "bin/docker-entrypoint", "config/deploy.rb", "config/deploy/production.rb", "config/deploy/staging.rb", ".kamal/deploy.yml", "scripts/deploy.sh", ".circleci/config.yml", ".gitlab-ci.yml", "bitbucket-pipelines.yml", "Jenkinsfile" ].freeze
- RENDERER_CACHE_DEPLOY_SCRIPT_GLOBS =
Bounded glob allowlist for deploy manifests that live in a known directory but use per-environment or per-workflow filenames. Each pattern matches only one directory level (no ‘**`) so the scan never recurses into the project tree, and the expansion is capped by RENDERER_CACHE_DEPLOY_SCRIPT_GLOB_MAX_MATCHES.
[ ".github/workflows/*.yml", ".github/workflows/*.yaml", "config/deploy/*.rb" ].freeze
- RENDERER_CACHE_DEPLOY_SCRIPT_MAX_BYTES =
Per-file safety gate to bound IO during the scan, not a meaningful size limit.
1_048_576- RENDERER_CACHE_DEPLOY_SCRIPT_GLOB_MAX_MATCHES =
Defense-in-depth cap on how many files a single glob may contribute. Realistic repos have a handful of workflow / deploy-stage files; far more than this is a sign of an unexpectedly broad pattern, not legitimate config.
100- OUTPUT_FORMATS =
Supported output formats. :text is the human-readable default; :json emits a machine-readable report (see JSON_SCHEMA_VERSION below).
%i[text json].freeze
- JSON_SCHEMA_VERSION =
Version of the machine-readable doctor report schema (FORMAT=json). Bump ONLY on breaking changes to the shape below. Schema (v1):
{ "schema_version": 1, "ror_version": "<ReactOnRails::VERSION>", "status": "pass" | "warn" | "fail", // worst check status "checks": [ { "id": "<stable snake_case id from CHECK_SECTIONS>", "title": "<human section title>", "status": "pass" | "warn" | "fail", "message": "<most severe message content, or null>", "details": [ { "level": "success|warning|error|info", "content": "..." } ] } ], "summary": { "pass": <count>, "warn": <count>, "fail": <count> } }No timestamp is included so output is deterministic for a given app state. Exit code semantics match text mode: 1 if any check fails, else 0.
1- CHECK_SECTIONS =
Doctor check sections. The :id values are part of the stable JSON schema contract (consumed by agents/tooling) — never rename or reuse them; add new sections with new ids instead.
[ { id: "environment_prerequisites", title: "Environment Prerequisites", method: :check_environment }, { id: "react_on_rails_versions", title: "React on Rails Versions", method: :check_react_on_rails_versions }, { id: "react_on_rails_packages", title: "React on Rails Packages", method: :check_packages }, { id: "javascript_package_dependencies", title: "JavaScript Package Dependencies", method: :check_dependencies }, { id: "key_configuration_files", title: "Key Configuration Files", method: :check_key_files }, { id: "configuration_analysis", title: "Configuration Analysis", method: :check_configuration_details }, { id: "bin_dev_launcher_setup", title: "bin/dev Launcher Setup", method: :check_bin_dev_launcher }, { id: "rails_integration", title: "Rails Integration", method: :check_rails }, { id: "bundler_configuration", title: "Bundler Configuration", method: :check_bundler_configuration }, { id: "testing_setup", title: "Testing Setup", method: :check_testing_setup }, { id: "development_environment", title: "Development Environment", method: :check_development }, { id: "react_on_rails_pro_setup", title: "React on Rails Pro Setup", method: :check_pro_setup }, { id: "react_server_components", title: "React Server Components", method: :check_rsc_setup } ].freeze
Constants included from ShakapackerConfigHelpers
ShakapackerConfigHelpers::DEFAULT_SHAKAPACKER_CONFIG_PATH, ShakapackerConfigHelpers::SUPPORTED_ASSETS_BUNDLERS
Constants included from ConfigPathResolver
ConfigPathResolver::ALL_DEFAULT_CONFIG_CANDIDATES, ConfigPathResolver::RSPACK_DEFAULT_CONFIG_CANDIDATES, ConfigPathResolver::WEBPACK_DEFAULT_CONFIG_CANDIDATES
Instance Method Summary collapse
-
#initialize(verbose: false, fix: false, format: :text) ⇒ Doctor
constructor
A new instance of Doctor.
- #run_diagnosis ⇒ Object
Constructor Details
#initialize(verbose: false, fix: false, format: :text) ⇒ Doctor
Returns a new instance of Doctor.
168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/react_on_rails/doctor.rb', line 168 def initialize(verbose: false, fix: false, format: :text) @verbose = verbose @fix = fix @format = format.respond_to?(:to_sym) ? format.to_sym : format unless OUTPUT_FORMATS.include?(@format) raise ArgumentError, "Invalid doctor format #{format.inspect}; expected one of #{OUTPUT_FORMATS.join(', ')}" end @checker = SystemChecker.new @test_output_path_strategy = :unknown @rails_environment_loaded = false end |
Instance Method Details
#run_diagnosis ⇒ Object
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/react_on_rails/doctor.rb', line 181 def run_diagnosis return run_json_diagnosis if format == :json print_header run_all_checks print_summary print_recommendations if should_show_recommendations? exit_with_status end |