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.



108
109
110
111
112
# File 'lib/rubocop/config.rb', line 108

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

.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



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

def merge_with_default(config, config_file)
  default_config = load_file(DEFAULT_FILE)
  new(merge(default_config, config), config_file)
end

Instance Method Details

#cop_enabled?(cop) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#file_to_exclude?(file) ⇒ Boolean

Returns:

  • (Boolean)


162
163
164
165
166
167
# File 'lib/rubocop/config.rb', line 162

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)


155
156
157
158
159
160
# File 'lib/rubocop/config.rb', line 155

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



114
115
116
# File 'lib/rubocop/config.rb', line 114

def for_cop(cop)
  self[cop]
end

#patterns_to_excludeObject



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

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

#patterns_to_includeObject



169
170
171
# File 'lib/rubocop/config.rb', line 169

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

#validate!Object

TODO: This should be a private method



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

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

  default_config = Config.load_file(DEFAULT_FILE)

  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



122
123
124
125
126
# File 'lib/rubocop/config.rb', line 122

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