Module: Pronto::RubyCritic::ConfigLoader
- Defined in:
- lib/pronto/rubycritic/config_loader.rb
Constant Summary collapse
- RECOGNISED_SECTIONS =
Top-level keys that SmellFilter expects to be sub-mappings. A non-Hash value here (e.g. ‘reek: false`, `complexity: 10`) is a user typo; we drop it with a warning rather than letting it crash SmellFilter#dig.
%w[reek flay flog complexity churn].freeze
Class Method Summary collapse
- .first_non_blank(*values) ⇒ Object
- .load_pronto_config ⇒ Object
- .load_runner_config(filename, cwd: Dir.pwd) ⇒ Object
-
.pronto_severity(pronto_config) ⇒ Object
Reads severity_level from .pronto.yml’s ‘rubycritic:` section without assuming the section is a Hash — a non-Hash section (e.g. `rubycritic: x`) would otherwise raise TypeError from Hash#dig and be swallowed upstream.
- .resolve_severity(env_value:, pronto_config:, valid_levels:, default:) ⇒ Object
- .validate_sections(config, filename) ⇒ Object
Class Method Details
.first_non_blank(*values) ⇒ Object
79 80 81 |
# File 'lib/pronto/rubycritic/config_loader.rb', line 79 def first_non_blank(*values) values.find { |v| !v.nil? && !v.to_s.strip.empty? } end |
.load_pronto_config ⇒ Object
53 54 55 56 57 58 |
# File 'lib/pronto/rubycritic/config_loader.rb', line 53 def load_pronto_config Pronto::ConfigFile.new.to_h rescue StandardError => e warn("pronto-rubycritic: could not load .pronto.yml: #{e.class}: #{e.}") {} end |
.load_runner_config(filename, cwd: Dir.pwd) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/pronto/rubycritic/config_loader.rb', line 16 def load_runner_config(filename, cwd: Dir.pwd) path = File.join(cwd, filename) return {} unless File.exist?(path) # aliases are deliberately NOT permitted: YAML anchors/aliases are not # used by this gem's config schema, and enabling them exposes a # billion-laughs expansion DoS on a config file that, in CI, can be # supplied by an untrusted pull request. parsed = YAML.safe_load_file(path, permitted_classes: [Symbol]) return {} if parsed.nil? return validate_sections(parsed, filename) if parsed.is_a?(Hash) # YAML like ":\n:\n- [" parses to a Symbol / Array / scalar — not a # Hash. SmellFilter expects a Hash (calls #dig). Reject anything else. warn("pronto-rubycritic: #{filename} must be a YAML mapping (Hash); " \ "got #{parsed.class}. Ignoring.") {} rescue Psych::Exception => e # Covers SyntaxError, DisallowedClass, and AliasesNotEnabled (the last # one fires when a config uses a YAML alias, which we intentionally # disable above). warn("pronto-rubycritic: invalid YAML in #{filename}: #{e.class}: #{e.}") {} end |
.pronto_severity(pronto_config) ⇒ Object
Reads severity_level from .pronto.yml’s ‘rubycritic:` section without assuming the section is a Hash — a non-Hash section (e.g. `rubycritic: x`) would otherwise raise TypeError from Hash#dig and be swallowed upstream.
74 75 76 77 |
# File 'lib/pronto/rubycritic/config_loader.rb', line 74 def pronto_severity(pronto_config) section = pronto_config['rubycritic'] if pronto_config.is_a?(Hash) section.is_a?(Hash) ? section['severity_level'] : nil end |
.resolve_severity(env_value:, pronto_config:, valid_levels:, default:) ⇒ Object
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/pronto/rubycritic/config_loader.rb', line 60 def resolve_severity(env_value:, pronto_config:, valid_levels:, default:) raw = first_non_blank(env_value, pronto_severity(pronto_config)) return default if raw.nil? sym = raw.to_s.strip.downcase.to_sym return sym if valid_levels.include?(sym) warn("pronto-rubycritic: invalid severity #{raw.inspect}, falling back to #{default}.") default end |
.validate_sections(config, filename) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/pronto/rubycritic/config_loader.rb', line 41 def validate_sections(config, filename) config.each_with_object({}) do |(key, value), acc| if RECOGNISED_SECTIONS.include?(key) && !value.is_a?(Hash) warn("pronto-rubycritic: #{filename}: section '#{key}' must be a mapping " \ "(got #{value.class}); ignoring it.") next end acc[key] = value end end |