Class: Rigor::Configuration
- Inherits:
-
Object
- Object
- Rigor::Configuration
- Defined in:
- lib/rigor/configuration.rb,
lib/rigor/configuration/dependencies.rb,
lib/rigor/configuration/severity_profile.rb,
sig/rigor.rbs
Overview
rubocop:disable Metrics/ClassLength
Defined Under Namespace
Modules: SeverityProfile Classes: Dependencies
Constant Summary collapse
- DISCOVERY_ORDER =
File-discovery order for
Configuration.load(nil).The first file present is loaded; the others are NOT implicitly merged. To extend a base config explicitly the winning file MUST list the base via
includes:..rigor.ymlis a developer-local override (typically gitignored);.rigor.dist.ymlis the project default (committed to the repo). When both are present the developer's local override wins outright — there is no implicit auto-merge. %w[.rigor.yml .rigor.dist.yml].freeze
- DEFAULT_PATH =
Back-compat alias. Keep here so external callers that read
Configuration::DEFAULT_PATHfor help text / fixture paths still work; the discovery list is the canonical source. DISCOVERY_ORDER.first
- BUILTIN_EXCLUDES =
Built-in exclusion patterns appended to
exclude:so vendored dependencies, Bundler artefacts, and JavaScript node_modules are never analysed by accident when a directory glob expands. Users cannot disable these defaults; the trade-off is that analysing any of these paths is essentially never what the user wants (they're build outputs / external dependencies, not source).We deliberately keep this list narrow.
tmp/and similar directories vary across project layouts (Rails hastmp/, libraries usually don't); user-suppliedexclude:entries in.rigor.ymlcover the project-specific cases. %w[ **/vendor/bundle/** **/.bundle/** **/node_modules/** ].freeze
- DEFAULTS =
{ "target_ruby" => "4.0", "paths" => ["lib"], "exclude" => [], "plugins" => [], "disable" => [], "libraries" => [], "signature_paths" => nil, # ADR-17 — project-side monkey-patch pre-evaluation. Empty by default; users opt in by listing explicit # files that the analyzer walks before per-file inference so patched-method declarations are visible # across the project (e.g. `lib/core_ext/string_extensions.rb`). Slice 1 plumbing only — listed files # are validated at config-load time (`pre-eval.file-not-found` on a missing path), but the dispatcher # tier consuming the registry lands in slice 2. "pre_eval" => [], # ADR-22 — baseline file path. nil (default) means no baseline is loaded; the `false` literal is # treated as the explicit-disable form for `.rigor.yml`-side override of an upstream `.rigor.dist.yml` # `baseline:` declaration. The presence of `.rigor-baseline.yml` on disk alone does NOT activate # filtering — the path must be named here (WD2 (b) of ADR-22). "baseline" => nil, "fold_platform_specific_paths" => false, "cache" => { "path" => ".rigor/cache", # LRU eviction cap in bytes (ADR-54 WD3). The least-recently-used entries are removed at the end of a # run when the total exceeds this limit. The 256 MB default exists to reap orphans — entries whose # content key nothing references any more (an rbs gem bump, a signature change) and that no run # would otherwise ever delete; a full active per-project set is ~2 MB, so the cap never touches live # entries. Set explicitly to `null` to disable eviction (pre-WD3 behaviour: the cache grows until # `--clear-cache`). "max_bytes" => 268_435_456 }, "plugins_io" => { "network" => "disabled", "allowed_paths" => [], "allowed_url_hosts" => [] }, "severity_profile" => "balanced", "severity_overrides" => {}, # ADR-50 § WD2 — bleeding-edge overlay opt-in. Selects which of the *next major's* queued changes # ({Rigor::BleedingEdge}) this project adopts early. Orthogonal to `severity_profile:`. Accepts `false` # (default — adopt none), `true` (adopt the whole overlay), a list of feature ids (adopt only those), # or `{ all: true, except: [ids] }` (adopt all but the named). The overlay is empty today, so every # form is currently a no-op; it becomes live when the first discipline is queued for a major. "bleeding_edge" => false, "dependencies" => { "source_inference" => [], "budget_per_gem" => Configuration::Dependencies::DEFAULT_BUDGET_PER_GEM }, "parallel" => { # ADR-15 Phase 4c — when greater than zero, `rigor check` dispatches per-file analysis across N # Ractor workers built around {Rigor::Analysis::WorkerSession}. `0` (default) keeps the sequential # coordinator path bit-for-bit unchanged. The CLI's `--workers=N` flag and the `RIGOR_RACTOR_WORKERS` # env var both override this setting; precedence is CLI > env > config > 0. "workers" => 0 }, "bundler" => { # Open item O4 — target-project Bundler awareness. When `bundle_path:` is set (or auto-detected), # Rigor walks `<bundle_path>/ruby/*/gems/*/sig/` and adds each gem-shipped sig directory to # `signature_paths:`. With O7's failure-memo in place, conflicts (a vendored sig already declares the # same constant) degrade gracefully to "no RBS env" with a single-line warning naming the offending # file, rather than hanging. # # `bundle_path:` (String, optional): explicit path to the bundler install root (e.g., # "vendor/bundle" or an absolute path). Resolved relative to the project root (`paths:`'s base) when # relative. # # `auto_detect:` (Boolean, default true): when no explicit `bundle_path:` is set, try # `.bundle/config`'s `BUNDLE_PATH:` first; fall back to `vendor/bundle/` under the project root if it # exists. When neither is found, no extra sigs are added — the analyzer sees only rigor's vendored # RBS and the user's `signature_paths:`. # # O4 Layer 3 keys: # # `lockfile:` (String, optional): explicit path to a `Gemfile.lock`. Resolved relative to the # project root when relative. When set (or auto-detected via the `auto_detect:` flag below) Rigor # parses the lockfile and uses it to FILTER the bundle-discovered `sig/` directories: only gems whose # `(name, version, platform)` matches a lockfile entry are admitted to `signature_paths:`. Stale or # out-of-band gems sitting in the bundle install tree are silently dropped. # # `auto_detect:` (Boolean, also gates the lockfile search): when true and `lockfile:` is nil, look # for `<project_root>/Gemfile.lock`. "bundle_path" => nil, "auto_detect" => true, "lockfile" => nil }, "rbs_collection" => { # Open item O4 Layer 3 slice 2 — `rbs collection install` awareness. When the target project has been # set up with `rbs collection install`, the resulting `rbs_collection.lock.yaml` carries the resolved # (gem, version, source) triples and `.gem_rbs_collection/` holds the downloaded `.rbs` files. Rigor # parses the lockfile and auto-feeds each gem's `<collection_root>/<name>/<version>/` directory into # `RbsLoader`'s `signature_paths:`. Sources of type `stdlib` are skipped because rigor's bundled # `DEFAULT_LIBRARIES` already covers that surface. # # `lockfile:` (String, optional): explicit path to `rbs_collection.lock.yaml`. Resolved relative to # the project root when relative. # # `auto_detect:` (Boolean, default true): when no explicit `lockfile:` is set, look for # `<project_root>/rbs_collection.lock.yaml`. "lockfile" => nil, "auto_detect" => true } }.freeze
Instance Attribute Summary collapse
-
#baseline_path ⇒ String?
readonly
Returns the value of attribute baseline_path.
-
#bleeding_edge ⇒ Object
readonly
Returns the value of attribute bleeding_edge.
-
#bleeding_edge_severity_overrides ⇒ Object
readonly
Returns the value of attribute bleeding_edge_severity_overrides.
-
#bundler_auto_detect ⇒ Object
readonly
Returns the value of attribute bundler_auto_detect.
-
#bundler_bundle_path ⇒ Object
readonly
Returns the value of attribute bundler_bundle_path.
-
#bundler_lockfile ⇒ Object
readonly
Returns the value of attribute bundler_lockfile.
-
#cache_max_bytes ⇒ Object
readonly
Returns the value of attribute cache_max_bytes.
-
#cache_path ⇒ String
readonly
Returns the value of attribute cache_path.
-
#dependencies ⇒ Object
readonly
Returns the value of attribute dependencies.
-
#disabled_rules ⇒ Object
readonly
Returns the value of attribute disabled_rules.
-
#exclude_patterns ⇒ Object
readonly
Returns the value of attribute exclude_patterns.
-
#fold_platform_specific_paths ⇒ Object
readonly
Returns the value of attribute fold_platform_specific_paths.
-
#libraries ⇒ Object
readonly
Returns the value of attribute libraries.
-
#parallel_workers ⇒ Object
readonly
Returns the value of attribute parallel_workers.
-
#paths ⇒ Array[String]
readonly
Returns the value of attribute paths.
-
#plugins ⇒ Array[String]
readonly
Returns the value of attribute plugins.
-
#plugins_io_allowed_paths ⇒ Object
readonly
Returns the value of attribute plugins_io_allowed_paths.
-
#plugins_io_allowed_url_hosts ⇒ Object
readonly
Returns the value of attribute plugins_io_allowed_url_hosts.
-
#plugins_io_network ⇒ Object
readonly
Returns the value of attribute plugins_io_network.
-
#pre_eval ⇒ Object
readonly
Returns the value of attribute pre_eval.
-
#rbs_collection_auto_detect ⇒ Object
readonly
Returns the value of attribute rbs_collection_auto_detect.
-
#rbs_collection_lockfile ⇒ Object
readonly
Returns the value of attribute rbs_collection_lockfile.
-
#severity_overrides ⇒ Object
readonly
Returns the value of attribute severity_overrides.
-
#severity_profile ⇒ Object
readonly
Returns the value of attribute severity_profile.
-
#signature_paths ⇒ Object
readonly
Returns the value of attribute signature_paths.
-
#target_ruby ⇒ String
readonly
Returns the value of attribute target_ruby.
Class Method Summary collapse
-
.discover ⇒ String?
Returns the path to the config file Rigor would load under auto-discovery, or
nilwhen neither candidate exists. -
.load(path = nil) ⇒ Configuration
Loads a configuration file.
-
.load_with_includes(path, visited: Set.new) ⇒ Hash[String, untyped]
Reads
path(which MUST exist) plus every file listed in itsincludes:chain, merging them under the order: included files first (in declaration order), then the current file's own keys override. - .resolve_path_key!(out, key, base_dir) ⇒ Object
- .resolve_plugins_io_paths!(out, base_dir) ⇒ Object
Instance Method Summary collapse
-
#initialize(data = DEFAULTS) ⇒ Configuration
constructor
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity.
-
#to_h ⇒ Hash[String, untyped]
rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity.
-
#with_bleeding_edge(value) ⇒ Object
ADR-50 § WD2 — returns a sibling Configuration whose bleeding-edge selection (and the derived
bleeding_edge_severity_overridesthe two SeverityProfile.resolve sites consult) is replaced byvalue, leaving every other field shared with the receiver.
Constructor Details
#initialize(data = DEFAULTS) ⇒ Configuration
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'lib/rigor/configuration.rb', line 282 def initialize(data = DEFAULTS) cache = DEFAULTS.fetch("cache").merge(data.fetch("cache", {})) plugins_io = DEFAULTS.fetch("plugins_io").merge(data.fetch("plugins_io", {})) @target_ruby = coerce_target_ruby(data.fetch("target_ruby", DEFAULTS.fetch("target_ruby"))) @paths = Array(data.fetch("paths", DEFAULTS.fetch("paths"))).map(&:to_s).freeze user_excludes = Array(data.fetch("exclude", DEFAULTS.fetch("exclude"))).map(&:to_s) @exclude_patterns = (BUILTIN_EXCLUDES + user_excludes).uniq.freeze @plugins = Array(data.fetch("plugins", DEFAULTS.fetch("plugins"))).map do |entry| coerce_plugin_entry(entry) end.freeze @disabled_rules = Array(data.fetch("disable", DEFAULTS.fetch("disable"))).map(&:to_s).freeze @libraries = Array(data.fetch("libraries", DEFAULTS.fetch("libraries"))).map(&:to_s).freeze sig_paths = data.fetch("signature_paths", DEFAULTS.fetch("signature_paths")) @signature_paths = sig_paths.nil? ? nil : Array(sig_paths).map(&:to_s).freeze @pre_eval = ( Array(data.fetch("pre_eval", DEFAULTS.fetch("pre_eval"))).map(&:to_s) ) @baseline_path = coerce_baseline_path(data.fetch("baseline", DEFAULTS.fetch("baseline"))) @fold_platform_specific_paths = data.fetch( "fold_platform_specific_paths", DEFAULTS.fetch("fold_platform_specific_paths") ) == true @cache_path = cache.fetch("path").to_s raw_max = cache.fetch("max_bytes") @cache_max_bytes = raw_max.nil? ? nil : Integer(raw_max) @plugins_io_network = coerce_network_policy(plugins_io.fetch("network")) @plugins_io_allowed_paths = Array(plugins_io.fetch("allowed_paths")).map(&:to_s).freeze @plugins_io_allowed_url_hosts = Array(plugins_io.fetch("allowed_url_hosts")).map(&:to_s).freeze @severity_profile = coerce_severity_profile( data.fetch("severity_profile", DEFAULTS.fetch("severity_profile")) ) @severity_overrides = coerce_severity_overrides( data.fetch("severity_overrides", DEFAULTS.fetch("severity_overrides")) ) @bleeding_edge = coerce_bleeding_edge( data.fetch("bleeding_edge", DEFAULTS.fetch("bleeding_edge")) ) @bleeding_edge_severity_overrides = BleedingEdge.severity_overrides_for(@bleeding_edge) @dependencies = Dependencies.from_h( data.fetch("dependencies", DEFAULTS.fetch("dependencies")) ) parallel = DEFAULTS.fetch("parallel").merge(data.fetch("parallel", {})) @parallel_workers = coerce_parallel_workers(parallel.fetch("workers")) bundler = DEFAULTS.fetch("bundler").merge(data.fetch("bundler", {})) bp = bundler.fetch("bundle_path") @bundler_bundle_path = bp.nil? ? nil : bp.to_s.dup.freeze @bundler_auto_detect = bundler.fetch("auto_detect") == true lf = bundler.fetch("lockfile") @bundler_lockfile = lf.nil? ? nil : lf.to_s.dup.freeze rbs_collection = DEFAULTS.fetch("rbs_collection").merge(data.fetch("rbs_collection", {})) rclf = rbs_collection.fetch("lockfile") @rbs_collection_lockfile = rclf.nil? ? nil : rclf.to_s.dup.freeze @rbs_collection_auto_detect = rbs_collection.fetch("auto_detect") == true # Ractor migration Phase 2a: deep-freeze the Configuration so it is `Ractor.shareable?`. Every ivar # above is now either a frozen value (Symbol / nil / Boolean) or an explicitly frozen collection / # value object; freezing `self` makes the whole carrier safe to send across Ractor boundaries (and # catches accidental post-init mutation in any caller). See `docs/design/20260514-ractor-migration.md`. freeze end |
Instance Attribute Details
#baseline_path ⇒ String? (readonly)
Returns the value of attribute baseline_path.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def baseline_path @baseline_path end |
#bleeding_edge ⇒ Object (readonly)
Returns the value of attribute bleeding_edge.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def bleeding_edge @bleeding_edge end |
#bleeding_edge_severity_overrides ⇒ Object (readonly)
Returns the value of attribute bleeding_edge_severity_overrides.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def bleeding_edge_severity_overrides @bleeding_edge_severity_overrides end |
#bundler_auto_detect ⇒ Object (readonly)
Returns the value of attribute bundler_auto_detect.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def bundler_auto_detect @bundler_auto_detect end |
#bundler_bundle_path ⇒ Object (readonly)
Returns the value of attribute bundler_bundle_path.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def bundler_bundle_path @bundler_bundle_path end |
#bundler_lockfile ⇒ Object (readonly)
Returns the value of attribute bundler_lockfile.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def bundler_lockfile @bundler_lockfile end |
#cache_max_bytes ⇒ Object (readonly)
Returns the value of attribute cache_max_bytes.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def cache_max_bytes @cache_max_bytes end |
#cache_path ⇒ String (readonly)
Returns the value of attribute cache_path.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def cache_path @cache_path end |
#dependencies ⇒ Object (readonly)
Returns the value of attribute dependencies.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def dependencies @dependencies end |
#disabled_rules ⇒ Object (readonly)
Returns the value of attribute disabled_rules.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def disabled_rules @disabled_rules end |
#exclude_patterns ⇒ Object (readonly)
Returns the value of attribute exclude_patterns.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def exclude_patterns @exclude_patterns end |
#fold_platform_specific_paths ⇒ Object (readonly)
Returns the value of attribute fold_platform_specific_paths.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def fold_platform_specific_paths @fold_platform_specific_paths end |
#libraries ⇒ Object (readonly)
Returns the value of attribute libraries.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def libraries @libraries end |
#parallel_workers ⇒ Object (readonly)
Returns the value of attribute parallel_workers.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def parallel_workers @parallel_workers end |
#paths ⇒ Array[String] (readonly)
Returns the value of attribute paths.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def paths @paths end |
#plugins ⇒ Array[String] (readonly)
Returns the value of attribute plugins.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def plugins @plugins end |
#plugins_io_allowed_paths ⇒ Object (readonly)
Returns the value of attribute plugins_io_allowed_paths.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def plugins_io_allowed_paths @plugins_io_allowed_paths end |
#plugins_io_allowed_url_hosts ⇒ Object (readonly)
Returns the value of attribute plugins_io_allowed_url_hosts.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def plugins_io_allowed_url_hosts @plugins_io_allowed_url_hosts end |
#plugins_io_network ⇒ Object (readonly)
Returns the value of attribute plugins_io_network.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def plugins_io_network @plugins_io_network end |
#pre_eval ⇒ Object (readonly)
Returns the value of attribute pre_eval.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def pre_eval @pre_eval end |
#rbs_collection_auto_detect ⇒ Object (readonly)
Returns the value of attribute rbs_collection_auto_detect.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def rbs_collection_auto_detect @rbs_collection_auto_detect end |
#rbs_collection_lockfile ⇒ Object (readonly)
Returns the value of attribute rbs_collection_lockfile.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def rbs_collection_lockfile @rbs_collection_lockfile end |
#severity_overrides ⇒ Object (readonly)
Returns the value of attribute severity_overrides.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def severity_overrides @severity_overrides end |
#severity_profile ⇒ Object (readonly)
Returns the value of attribute severity_profile.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def severity_profile @severity_profile end |
#signature_paths ⇒ Object (readonly)
Returns the value of attribute signature_paths.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def signature_paths @signature_paths end |
#target_ruby ⇒ String (readonly)
Returns the value of attribute target_ruby.
146 147 148 |
# File 'lib/rigor/configuration.rb', line 146 def target_ruby @target_ruby end |
Class Method Details
.discover ⇒ String?
Returns the path to the config file Rigor would load under auto-discovery, or nil when neither
candidate exists. Public so the CLI / spec drift checks can introspect the resolved file.
179 180 181 |
# File 'lib/rigor/configuration.rb', line 179 def self.discover DISCOVERY_ORDER.find { |candidate| File.exist?(candidate) } end |
.load(path = nil) ⇒ Configuration
Loads a configuration file.
path == nil triggers auto-discovery against DISCOVERY_ORDER. The first present file in that list is
loaded; if none exist the built-in DEFAULTS are used.
When a path is supplied (whether by auto-discovery or by the caller) the YAML body is processed for
includes: recursively, and every relative path inside path-bearing keys (paths:,
signature_paths:, plugins_io.allowed_paths:, includes:) is resolved against THAT file's
directory. The resolution is per-file: an included file's relative paths resolve against the included
file's directory, not the top-level file. Path resolution mirrors
PHPStan.
169 170 171 172 173 174 175 |
# File 'lib/rigor/configuration.rb', line 169 def self.load(path = nil) resolved = path || discover return new(DEFAULTS) if resolved.nil? || !File.exist?(resolved) data = load_with_includes(resolved) new(DEFAULTS.merge(data)) end |
.load_with_includes(path, visited: Set.new) ⇒ Hash[String, untyped]
Reads path (which MUST exist) plus every file listed in its includes: chain, merging them under the
order: included files first (in declaration order), then the current file's own keys override.
Relative paths inside each file are resolved against that file's directory. Public so the CLI can run
the include-aware load before applying --treat-all-as-inline-rbs's plugin injection (see
Rigor::CLI::CheckCommand#load_check_configuration).
188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/rigor/configuration.rb', line 188 def self.load_with_includes(path, visited: Set.new) absolute = File.(path) raise ArgumentError, "circular include: #{absolute}" if visited.include?(absolute) raw = YAML.safe_load_file(absolute, aliases: false) || {} raise ArgumentError, "config file must be a YAML mapping: #{absolute}" unless raw.is_a?(Hash) base_dir = File.dirname(absolute) includes = Array(raw.delete("includes") || []) data = resolve_paths_in(raw, base_dir) next_visited = visited + [absolute] merge_includes(data, includes, base_dir, next_visited) end |
.resolve_path_key!(out, key, base_dir) ⇒ Object
230 231 232 233 234 |
# File 'lib/rigor/configuration.rb', line 230 def self.resolve_path_key!(out, key, base_dir) return unless out.key?(key) && !out[key].nil? out[key] = Array(out[key]).map { |p| File.(p.to_s, base_dir) } end |
.resolve_plugins_io_paths!(out, base_dir) ⇒ Object
236 237 238 239 240 241 242 243 |
# File 'lib/rigor/configuration.rb', line 236 def self.resolve_plugins_io_paths!(out, base_dir) plugins_io = out["plugins_io"] return unless plugins_io.is_a?(Hash) && plugins_io["allowed_paths"] duped = plugins_io.dup duped["allowed_paths"] = Array(plugins_io["allowed_paths"]).map { |p| File.(p.to_s, base_dir) } out["plugins_io"] = duped end |
Instance Method Details
#to_h ⇒ Hash[String, untyped]
rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/rigor/configuration.rb', line 343 def to_h # rubocop:disable Metrics/MethodLength, Metrics/AbcSize { "target_ruby" => target_ruby, "paths" => paths, "exclude" => exclude_patterns - BUILTIN_EXCLUDES, "plugins" => plugins, "disable" => disabled_rules, "libraries" => libraries, "signature_paths" => signature_paths, "pre_eval" => pre_eval, "fold_platform_specific_paths" => fold_platform_specific_paths, "cache" => { "path" => cache_path, "max_bytes" => cache_max_bytes }, "plugins_io" => { "network" => plugins_io_network.to_s, "allowed_paths" => plugins_io_allowed_paths, "allowed_url_hosts" => plugins_io_allowed_url_hosts }, "severity_profile" => severity_profile.to_s, "severity_overrides" => severity_overrides.to_h { |k, v| [k, v.to_s] }, "bleeding_edge" => bleeding_edge_to_h, "dependencies" => dependencies.to_h, "parallel" => { "workers" => parallel_workers }, "bundler" => { "bundle_path" => bundler_bundle_path, "auto_detect" => bundler_auto_detect, "lockfile" => bundler_lockfile }, "rbs_collection" => { "lockfile" => rbs_collection_lockfile, "auto_detect" => rbs_collection_auto_detect } } end |
#with_bleeding_edge(value) ⇒ Object
ADR-50 § WD2 — returns a sibling Configuration whose bleeding-edge selection (and the derived
bleeding_edge_severity_overrides the two Rigor::Configuration::SeverityProfile.resolve sites consult) is replaced by
value, leaving every other field shared with the receiver. value takes the same forms as the
bleeding_edge: config key — false / true / a feature-id Array / { "all" => true, "except" => [...] } — and is normalised through the same #coerce_bleeding_edge path, so an unknown id stays
inert.
The CLI's --bleeding-edge[=ids] / --no-bleeding-edge flag uses this to override the configured
selection for a single run (the same CLI-over-config precedence --workers and --no-cache follow).
It is a frozen dup with the two bleeding-edge ivars re-set: dup returns an unfrozen shallow copy
(every other ivar is the receiver's deeply-frozen value, safe to share read-only), the two replacements
are themselves deeply frozen, and the re-freeze keeps the result Ractor.shareable? for the worker
path.
395 396 397 398 399 400 401 402 |
# File 'lib/rigor/configuration.rb', line 395 def with_bleeding_edge(value) selector = coerce_bleeding_edge(value) copy = dup copy.instance_variable_set(:@bleeding_edge, selector) copy.instance_variable_set(:@bleeding_edge_severity_overrides, BleedingEdge.severity_overrides_for(selector)) copy.freeze end |