class RuboCop::Config
This class represents the configuration of the RuboCop application and all its cops. A Config is associated with a YAML configuration file from which it was read. Several different Configs can be used during a run of the rubocop program, if files in several directories are inspected.
Constants
- CopConfig
- DEFAULT_RAILS_VERSION
Attributes
Public Class Methods
# File lib/rubocop/config.rb, line 24 def self.create(hash, path, check: true) config = new(hash, path) config.check if check config end
rubocop:disable Metrics/AbcSize
# File lib/rubocop/config.rb, line 32 def initialize(hash = RuboCop::ConfigLoader.default_configuration, loaded_path = nil) @loaded_path = loaded_path @for_cop = Hash.new do |h, cop| cop_name = cop.respond_to?(:cop_name) ? cop.cop_name : cop qualified_cop_name = Cop::Registry.qualified_cop_name(cop_name, loaded_path) cop_options = self[qualified_cop_name].dup || {} cop_options['Enabled'] = enable_cop?(qualified_cop_name, cop_options) h[cop] = h[cop_name] = cop_options end @hash = hash @validator = ConfigValidator.new(self) @badge_config_cache = {}.compare_by_identity @clusivity_config_exists_cache = {} end
Public Instance Methods
# File lib/rubocop/config.rb, line 172 def active_support_extensions_enabled? for_all_cops['ActiveSupportExtensionsEnabled'] end
# File lib/rubocop/config.rb, line 98 def add_excludes_from_higher_level(highest_config) return unless highest_config.for_all_cops['Exclude'] excludes = for_all_cops['Exclude'] ||= [] highest_config.for_all_cops['Exclude'].each do |path| unless path.is_a?(Regexp) || absolute?(path) path = File.join(File.dirname(highest_config.loaded_path), path) end excludes << path unless excludes.include?(path) end end
# File lib/rubocop/config.rb, line 195 def allowed_camel_case_file?(file) # Gemspecs are allowed to have dashes because that fits with bundler best # practices in the case when the gem is nested under a namespace (e.g., # `bundler-console` conveys `Bundler::Console`). return true if File.extname(file) == '.gemspec' file_to_include?(file) do |pattern, relative_path, absolute_path| /[A-Z]/.match?(pattern.to_s) && (match_path?(pattern, relative_path) || match_path?(pattern, absolute_path)) end end
Paths specified in configuration files starting with .rubocop are relative to the directory where that file is. Paths in other config files are relative to the current directory. This is so that paths in config/default.yml, for example, are not relative to RuboCop’s config directory since that wouldn’t work.
# File lib/rubocop/config.rb, line 239 def base_dir_for_path_parameters @base_dir_for_path_parameters ||= if loaded_path && File.basename(loaded_path).start_with?('.rubocop') && loaded_path != File.join(Dir.home, ConfigLoader::DOTFILE) File.expand_path(File.dirname(loaded_path)) else Dir.pwd end end
# File lib/rubocop/config.rb, line 264 def bundler_lock_file_path return nil unless loaded_path base_path = base_dir_for_path_parameters ['Gemfile.lock', 'gems.locked'].each do |file_name| path = find_file_upwards(file_name, base_path) return path if path end nil end
# File lib/rubocop/config.rb, line 53 def check deprecation_check { |deprecation_message| warn("#{loaded_path} - #{deprecation_message}") } @validator.validate make_excludes_absolute self end
@return [Boolean] whether config for this badge has ‘Include’ or ‘Exclude’ keys @api private
# File lib/rubocop/config.rb, line 144 def clusivity_config_for_badge?(badge) exists = @clusivity_config_exists_cache[badge.to_s] return exists unless exists.nil? cop_config = for_badge(badge) @clusivity_config_exists_cache[badge.to_s] = cop_config['Include'] || cop_config['Exclude'] end
# File lib/rubocop/config.rb, line 110 def deprecation_check %w[Exclude Include].each do |key| plural = "#{key}s" next unless for_all_cops[plural] for_all_cops[key] = for_all_cops[plural] # Stay backwards compatible. for_all_cops.delete(plural) yield "AllCops/#{plural} was renamed to AllCops/#{key}" end end
# File lib/rubocop/config.rb, line 164 def disabled_new_cops? for_all_cops['NewCops'] == 'disable' end
# File lib/rubocop/config.rb, line 168 def enabled_new_cops? for_all_cops['NewCops'] == 'enable' end
# File lib/rubocop/config.rb, line 217 def file_to_exclude?(file) file = File.expand_path(file) patterns_to_exclude.any? { |pattern| match_path?(pattern, file) } end
# File lib/rubocop/config.rb, line 176 def file_to_include?(file) relative_file_path = path_relative_to_config(file) # Optimization to quickly decide if the given file is hidden (on the top # level) and cannot be matched by any pattern. is_hidden = relative_file_path.start_with?('.') && !relative_file_path.start_with?('..') return false if is_hidden && !possibly_include_hidden? absolute_file_path = File.expand_path(file) patterns_to_include.any? do |pattern| if block_given? yield pattern, relative_file_path, absolute_file_path else match_path?(pattern, relative_file_path) || match_path?(pattern, absolute_file_path) end end end
# File lib/rubocop/config.rb, line 160 def for_all_cops @for_all_cops ||= self['AllCops'] || {} end
@return [Config] for the given cop merged with that of its department (if any) Note: the ‘Enabled’ attribute is same as that returned by ‘for_cop`
# File lib/rubocop/config.rb, line 130 def for_badge(badge) @badge_config_cache[badge] ||= begin department_config = self[badge.department_name] cop_config = for_cop(badge.to_s) if department_config department_config.merge(cop_config) else cop_config end end end
@return [Config] for the given cop / cop name. Note: the ‘Enabled’ attribute is calculated according to the department’s and ‘AllCops’ configuration; other attributes are not inherited.
# File lib/rubocop/config.rb, line 124 def for_cop(cop) @for_cop[cop] end
@return [Config] for the given department name. Note: the ‘Enabled’ attribute will be present only if specified at the department’s level
# File lib/rubocop/config.rb, line 155 def for_department(department_name) @for_department ||= Hash.new { |h, dept| h[dept] = self[dept] || {} } @for_department[department_name.to_s] end
True if this is a config file that is shipped with RuboCop
# File lib/rubocop/config.rb, line 78 def internal? base_config_path = File.expand_path(File.join(ConfigLoader::RUBOCOP_HOME, 'config')) File.expand_path(loaded_path).start_with?(base_config_path) end
rubocop:enable Metrics/AbcSize
# File lib/rubocop/config.rb, line 49 def loaded_features @loaded_features ||= ConfigLoader.loaded_features end
# File lib/rubocop/config.rb, line 83 def make_excludes_absolute each_key do |key| @validator.validate_section_presence(key) next unless self[key]['Exclude'] self[key]['Exclude'].map! do |exclude_elem| if exclude_elem.is_a?(String) && !absolute?(exclude_elem) File.expand_path(File.join(base_dir_for_path_parameters, exclude_elem)) else exclude_elem end end end end
# File lib/rubocop/config.rb, line 230 def path_relative_to_config(path) relative_path(path, base_dir_for_path_parameters) end
# File lib/rubocop/config.rb, line 226 def patterns_to_exclude for_all_cops['Exclude'] || [] end
# File lib/rubocop/config.rb, line 222 def patterns_to_include for_all_cops['Include'] || [] end
# File lib/rubocop/config.rb, line 275 def pending_cops keys.each_with_object([]) do |qualified_cop_name, pending_cops| department = department_of(qualified_cop_name) next if department && department['Enabled'] == false cop_metadata = self[qualified_cop_name] next unless cop_metadata['Enabled'] == 'pending' pending_cops << CopConfig.new(qualified_cop_name, cop_metadata) end end
# File lib/rubocop/config.rb, line 73 def signature @signature ||= Digest::SHA1.hexdigest(to_s) end
# File lib/rubocop/config.rb, line 260 def smart_loaded_path PathUtil.smart_path(@loaded_path) end
# File lib/rubocop/config.rb, line 249 def target_rails_version @target_rails_version ||= if for_all_cops['TargetRailsVersion'] for_all_cops['TargetRailsVersion'].to_f elsif target_rails_version_from_bundler_lock_file target_rails_version_from_bundler_lock_file else DEFAULT_RAILS_VERSION end end
# File lib/rubocop/config.rb, line 69 def to_s @to_s ||= @hash.to_s end
# File lib/rubocop/config.rb, line 60 def validate_after_resolution @validator.validate_after_resolution self end
Private Instance Methods
# File lib/rubocop/config.rb, line 322 def department_of(qualified_cop_name) *cop_department, _ = qualified_cop_name.split('/') return nil if cop_department.empty? self[cop_department.join('/')] end
# File lib/rubocop/config.rb, line 310 def enable_cop?(qualified_cop_name, cop_options) # If the cop is explicitly enabled or `Lint/Syntax`, the other checks can be skipped. return true if cop_options['Enabled'] == true || qualified_cop_name == 'Lint/Syntax' department = department_of(qualified_cop_name) cop_enabled = cop_options.fetch('Enabled') { !for_all_cops['DisabledByDefault'] } return true if cop_enabled == 'override_department' return false if department && department['Enabled'] == false cop_enabled end
# File lib/rubocop/config.rb, line 297 def read_rails_version_from_bundler_lock_file lock_file_path = bundler_lock_file_path return nil unless lock_file_path File.foreach(lock_file_path) do |line| # If Rails (or one of its frameworks) is in Gemfile.lock or gems.lock, there should be # a line like: # railties (X.X.X) result = line.match(/^\s+railties\s+\((\d+\.\d+)/) return result.captures.first.to_f if result end end
# File lib/rubocop/config.rb, line 293 def target_rails_version_from_bundler_lock_file @target_rails_version_from_bundler_lock_file ||= read_rails_version_from_bundler_lock_file end