Class: Rubocop::Config

Inherits:
Hash
  • Object
show all
Defined in:
lib/rubocop/config.rb

Defined Under Namespace

Classes: ValidationError

Constant Summary collapse

DOTFILE =
'.rubocop.yml'
RUBOCOP_HOME =
File.realpath(File.join(File.dirname(__FILE__), '..', '..'))
DEFAULT_FILE =
File.join(RUBOCOP_HOME, 'config', 'default.yml')

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash = {}, loaded_path = nil) ⇒ Config

Returns a new instance of Config.



111
112
113
114
115
# File 'lib/rubocop/config.rb', line 111

def initialize(hash = {}, loaded_path = nil)
  @hash = hash
  @loaded_path = loaded_path
  super(@hash)
end

Instance Attribute Details

#loaded_pathObject (readonly)

Returns the value of attribute loaded_path.



15
16
17
# File 'lib/rubocop/config.rb', line 15

def loaded_path
  @loaded_path
end

Class Method Details

.base_configs(path, inherit_from) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/rubocop/config.rb', line 57

def base_configs(path, inherit_from)
  base_files = case inherit_from
               when nil then []
               when String then [inherit_from]
               when Array then inherit_from
               end
  base_files.map do |f|
    f = File.join(File.dirname(path), f) unless f.start_with?('/')
    load_file(f)
  end
end

.configuration_file_for(target_dir) ⇒ Object

Returns the path of .rubocop.yml searching upwards in the directory structure starting at the given directory where the inspected file is. If no .rubocop.yml is found there, the user’s home directory is checked. If there’s no .rubocop.yml there either, the path to the default file is returned.



74
75
76
77
78
79
80
81
82
83
# File 'lib/rubocop/config.rb', line 74

def configuration_file_for(target_dir)
  possible_config_files = dirs_to_search(target_dir).map do |dir|
    File.join(dir, DOTFILE)
  end

  found_file = possible_config_files.find do |config_file|
    File.exist?(config_file)
  end
  found_file || DEFAULT_FILE
end

.configuration_from_file(config_file) ⇒ Object



85
86
87
88
# File 'lib/rubocop/config.rb', line 85

def configuration_from_file(config_file)
  config = load_file(config_file)
  merge_with_default(config, config_file)
end

.default_configurationObject



90
91
92
# File 'lib/rubocop/config.rb', line 90

def default_configuration
  @default_configuration ||= load_file(DEFAULT_FILE)
end

.load_file(path) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/rubocop/config.rb', line 18

def load_file(path)
  hash = YAML.load_file(path)

  base_configs(path, hash['inherit_from']).reverse.each do |base_config|
    base_config.each do |key, value|
      if value.is_a?(Hash)
        hash[key] = hash.has_key?(key) ? merge(value, hash[key]) : value
      end
    end
  end

  hash.delete('inherit_from')
  config = new(hash, File.realpath(path))
  config.warn_unless_valid
  config
end

.merge(base_hash, derived_hash) ⇒ Object

Return a recursive merge of two hashes. That is, a normal hash merge, with the addition that any value that is a hash, and occurs in both arguments, will also be merged. And so on.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/rubocop/config.rb', line 38

def merge(base_hash, derived_hash)
  result = {}
  base_hash.each do |key, value|
    result[key] = if derived_hash.has_key?(key)
                    if value.is_a?(Hash)
                      merge(value, derived_hash[key])
                    else
                      derived_hash[key]
                    end
                  else
                    base_hash[key]
                  end
  end
  derived_hash.each do |key, value|
    result[key] = value unless base_hash.has_key?(key)
  end
  result
end

.merge_with_default(config, config_file) ⇒ Object



94
95
96
# File 'lib/rubocop/config.rb', line 94

def merge_with_default(config, config_file)
  new(merge(default_configuration, config), config_file)
end

Instance Method Details

#cop_enabled?(cop) ⇒ Boolean

Returns:

  • (Boolean)


121
122
123
# File 'lib/rubocop/config.rb', line 121

def cop_enabled?(cop)
  self[cop].nil? || self[cop]['Enabled']
end

#file_to_exclude?(file) ⇒ Boolean

Returns:

  • (Boolean)


165
166
167
168
169
170
# File 'lib/rubocop/config.rb', line 165

def file_to_exclude?(file)
  relative_file_path = relative_path_to_loaded_dir(file)
  patterns_to_exclude.any? do |pattern|
    match_path?(pattern, relative_file_path)
  end
end

#file_to_include?(file) ⇒ Boolean

Returns:

  • (Boolean)


158
159
160
161
162
163
# File 'lib/rubocop/config.rb', line 158

def file_to_include?(file)
  relative_file_path = relative_path_to_loaded_dir(file)
  patterns_to_include.any? do |pattern|
    match_path?(pattern, relative_file_path)
  end
end

#for_cop(cop) ⇒ Object



117
118
119
# File 'lib/rubocop/config.rb', line 117

def for_cop(cop)
  self[cop]
end

#patterns_to_excludeObject



176
177
178
# File 'lib/rubocop/config.rb', line 176

def patterns_to_exclude
  @hash['AllCops']['Excludes']
end

#patterns_to_includeObject



172
173
174
# File 'lib/rubocop/config.rb', line 172

def patterns_to_include
  @hash['AllCops']['Includes']
end

#validateObject

TODO: This should be a private method



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/rubocop/config.rb', line 132

def validate
  # Don't validate RuboCop's own files. Avoids inifinite recursion.
  return if @loaded_path.start_with?(RUBOCOP_HOME)

  default_config = self.class.default_configuration

  valid_cop_names, invalid_cop_names = @hash.keys.partition do |key|
    default_config.has_key?(key)
  end

  invalid_cop_names.each do |name|
    fail ValidationError,
         "unrecognized cop #{name} found in #{loaded_path || self}"
  end

  valid_cop_names.each do |name|
    @hash[name].each_key do |param|
      unless default_config[name].has_key?(param)
        fail ValidationError,
             "unrecognized parameter #{name}:#{param} found " +
             "in #{loaded_path || self}"
      end
    end
  end
end

#warn_unless_validObject



125
126
127
128
129
# File 'lib/rubocop/config.rb', line 125

def warn_unless_valid
  validate
rescue Config::ValidationError => e
  puts "Warning: #{e.message}".color(:red)
end