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
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.yml` is a developer-local override (typically gitignored); `.rigor.dist.yml` is 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_PATH` for 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 has `tmp/`, libraries usually don’t); user-supplied ‘exclude:` entries in `.rigor.yml` cover 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, "fold_platform_specific_paths" => false, "cache" => { "path" => ".rigor/cache" }, "plugins_io" => { "network" => "disabled", "allowed_paths" => [], "allowed_url_hosts" => [] }, "severity_profile" => "balanced", "severity_overrides" => {}, "dependencies" => { "source_inference" => [], "budget_per_gem" => Configuration::Dependencies::DEFAULT_BUDGET_PER_GEM } }.freeze
Instance Attribute Summary collapse
-
#cache_path ⇒ Object
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.
-
#paths ⇒ Object
readonly
Returns the value of attribute paths.
-
#plugins ⇒ Object
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.
-
#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 ⇒ Object
readonly
Returns the value of attribute target_ruby.
Class Method Summary collapse
-
.discover ⇒ Object
Returns the path to the config file Rigor would load under auto-discovery, or ‘nil` when neither candidate exists.
-
.load(path = nil) ⇒ Object
Loads a configuration file.
- .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/PerceivedComplexity, Metrics/MethodLength.
-
#to_h ⇒ Object
rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength.
Constructor Details
#initialize(data = DEFAULTS) ⇒ Configuration
rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/rigor/configuration.rb', line 218 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) 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 @fold_platform_specific_paths = data.fetch( "fold_platform_specific_paths", DEFAULTS.fetch("fold_platform_specific_paths") ) == true @cache_path = cache.fetch("path").to_s @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")) ) @dependencies = Dependencies.from_h( data.fetch("dependencies", DEFAULTS.fetch("dependencies")) ) end |
Instance Attribute Details
#cache_path ⇒ Object (readonly)
Returns the value of attribute cache_path.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def cache_path @cache_path end |
#dependencies ⇒ Object (readonly)
Returns the value of attribute dependencies.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def dependencies @dependencies end |
#disabled_rules ⇒ Object (readonly)
Returns the value of attribute disabled_rules.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def disabled_rules @disabled_rules end |
#exclude_patterns ⇒ Object (readonly)
Returns the value of attribute exclude_patterns.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def exclude_patterns @exclude_patterns end |
#fold_platform_specific_paths ⇒ Object (readonly)
Returns the value of attribute fold_platform_specific_paths.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def fold_platform_specific_paths @fold_platform_specific_paths end |
#libraries ⇒ Object (readonly)
Returns the value of attribute libraries.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def libraries @libraries end |
#paths ⇒ Object (readonly)
Returns the value of attribute paths.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def paths @paths end |
#plugins ⇒ Object (readonly)
Returns the value of attribute plugins.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def plugins @plugins end |
#plugins_io_allowed_paths ⇒ Object (readonly)
Returns the value of attribute plugins_io_allowed_paths.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 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.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 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.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def plugins_io_network @plugins_io_network end |
#severity_overrides ⇒ Object (readonly)
Returns the value of attribute severity_overrides.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def severity_overrides @severity_overrides end |
#severity_profile ⇒ Object (readonly)
Returns the value of attribute severity_profile.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def severity_profile @severity_profile end |
#signature_paths ⇒ Object (readonly)
Returns the value of attribute signature_paths.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def signature_paths @signature_paths end |
#target_ruby ⇒ Object (readonly)
Returns the value of attribute target_ruby.
76 77 78 |
# File 'lib/rigor/configuration.rb', line 76 def target_ruby @target_ruby end |
Class Method Details
.discover ⇒ Object
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.
110 111 112 |
# File 'lib/rigor/configuration.rb', line 110 def self.discover DISCOVERY_ORDER.find { |candidate| File.exist?(candidate) } end |
.load(path = nil) ⇒ Object
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](phpstan.org/config-reference#paths).
98 99 100 101 102 103 104 |
# File 'lib/rigor/configuration.rb', line 98 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 |
.resolve_path_key!(out, key, base_dir) ⇒ Object
163 164 165 166 167 |
# File 'lib/rigor/configuration.rb', line 163 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
169 170 171 172 173 174 175 176 |
# File 'lib/rigor/configuration.rb', line 169 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 ⇒ Object
rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/rigor/configuration.rb', line 252 def to_h { "target_ruby" => target_ruby, "paths" => paths, "exclude" => exclude_patterns - BUILTIN_EXCLUDES, "plugins" => plugins, "disable" => disabled_rules, "libraries" => libraries, "signature_paths" => signature_paths, "fold_platform_specific_paths" => fold_platform_specific_paths, "cache" => { "path" => cache_path }, "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] }, "dependencies" => dependencies.to_h } end |