Class: RuboCop::Cop::Registry

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/rubocop/cop/registry.rb

Overview

Registry that tracks all cops by their badge and department.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cops = [], options = {}) ⇒ Registry

Returns a new instance of Registry.


29
30
31
32
33
34
35
36
# File 'lib/rubocop/cop/registry.rb', line 29

def initialize(cops = [], options = {})
  @registry = {}
  @departments = {}
  @cops_by_cop_name = Hash.new { |hash, key| hash[key] = [] }

  @enrollment_queue = cops
  @options = options
end

Class Attribute Details

.globalObject (readonly)

Returns the value of attribute global


210
211
212
# File 'lib/rubocop/cop/registry.rb', line 210

def global
  @global
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options


27
28
29
# File 'lib/rubocop/cop/registry.rb', line 27

def options
  @options
end

Class Method Details

.allObject


213
214
215
# File 'lib/rubocop/cop/registry.rb', line 213

def self.all
  global.without_department(:Test).cops
end

.qualified_cop_name(name, origin) ⇒ Object


217
218
219
# File 'lib/rubocop/cop/registry.rb', line 217

def self.qualified_cop_name(name, origin)
  global.qualified_cop_name(name, origin)
end

.with_temporary_global(temp_global = global.dup) ⇒ Object

Changes momentarily the global registry Intended for testing purposes


223
224
225
226
227
228
229
# File 'lib/rubocop/cop/registry.rb', line 223

def self.with_temporary_global(temp_global = global.dup)
  previous = @global
  @global = temp_global
  yield
ensure
  @global = previous
end

Instance Method Details

#==(other) ⇒ Object


182
183
184
# File 'lib/rubocop/cop/registry.rb', line 182

def ==(other)
  cops == other.cops
end

#contains_cop_matching?(names) ⇒ Boolean

Returns:

  • (Boolean)

67
68
69
# File 'lib/rubocop/cop/registry.rb', line 67

def contains_cop_matching?(names)
  cops.any? { |cop| cop.match?(names) }
end

#copsObject


142
143
144
145
# File 'lib/rubocop/cop/registry.rb', line 142

def cops
  clear_enrollment_queue
  @registry.values
end

#department_missing?(badge, name) ⇒ Boolean

Returns:

  • (Boolean)

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

def department_missing?(badge, name)
  !badge.qualified? && unqualified_cop_names.include?(name)
end

#departmentsArray<Symbol>

Returns list of departments for current cops.

Returns:

  • (Array<Symbol>)

    list of departments for current cops.


47
48
49
50
# File 'lib/rubocop/cop/registry.rb', line 47

def departments
  clear_enrollment_queue
  @departments.keys
end

#dismiss(cop) ⇒ Object


42
43
44
# File 'lib/rubocop/cop/registry.rb', line 42

def dismiss(cop)
  raise "Cop #{cop} could not be dismissed" unless @enrollment_queue.delete(cop)
end

#each(&block) ⇒ Object


197
198
199
# File 'lib/rubocop/cop/registry.rb', line 197

def each(&block)
  cops.each(&block)
end

#enabled(config, only = [], only_safe: false) ⇒ Object


152
153
154
155
156
# File 'lib/rubocop/cop/registry.rb', line 152

def enabled(config, only = [], only_safe: false)
  select do |cop|
    only.include?(cop.cop_name) || enabled?(cop, config, only_safe)
  end
end

#enabled?(cop, config, only_safe) ⇒ Boolean

Returns:

  • (Boolean)

158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/rubocop/cop/registry.rb', line 158

def enabled?(cop, config, only_safe)
  cfg = config.for_cop(cop)

  cop_enabled = cfg.fetch('Enabled') == true ||
                enabled_pending_cop?(cfg, config)

  if only_safe
    cop_enabled && cfg.fetch('Safe', true)
  else
    cop_enabled
  end
end

#enabled_pending_cop?(cop_cfg, config) ⇒ Boolean

Returns:

  • (Boolean)

171
172
173
174
175
176
# File 'lib/rubocop/cop/registry.rb', line 171

def enabled_pending_cop?(cop_cfg, config)
  return false if @options[:disable_pending_cops]

  cop_cfg.fetch('Enabled') == 'pending' &&
    (@options[:enable_pending_cops] || config.enabled_new_cops?)
end

#enlist(cop) ⇒ Object


38
39
40
# File 'lib/rubocop/cop/registry.rb', line 38

def enlist(cop)
  @enrollment_queue << cop
end

#find_by_cop_name(cop_name) ⇒ Class?

Parameters:

Returns:

  • (Class, nil)

203
204
205
# File 'lib/rubocop/cop/registry.rb', line 203

def find_by_cop_name(cop_name)
  to_h[cop_name].first
end

#lengthObject


147
148
149
150
# File 'lib/rubocop/cop/registry.rb', line 147

def length
  clear_enrollment_queue
  @registry.size
end

#namesObject


178
179
180
# File 'lib/rubocop/cop/registry.rb', line 178

def names
  cops.map(&:cop_name)
end

121
122
123
124
125
126
127
# File 'lib/rubocop/cop/registry.rb', line 121

def print_warning(name, path)
  message = "#{path}: Warning: no department given for #{name}."
  if path.end_with?('.rb')
    message += ' Run `rubocop -a --only Migration/DepartmentName` to fix.'
  end
  warn message
end

#qualified_cop_name(name, path, warn: true) ⇒ String

Note:

Emits a warning if the provided name has an incorrect namespace

Convert a user provided cop name into a properly namespaced name

Examples:

gives back a correctly qualified cop name


cops = RuboCop::Cop::Cop.all
cops.
  qualified_cop_name('Layout/EndOfLine') # => 'Layout/EndOfLine'

fixes incorrect namespaces


cops = RuboCop::Cop::Cop.all
cops.qualified_cop_name('Lint/EndOfLine') # => 'Layout/EndOfLine'

namespaces bare cop identifiers


cops = RuboCop::Cop::Cop.all
cops.qualified_cop_name('EndOfLine') # => 'Layout/EndOfLine'

passes back unrecognized cop names


cops = RuboCop::Cop::Cop.all
cops.qualified_cop_name('NotACop') # => 'NotACop'

Parameters:

  • name (String)

    Cop name extracted from config

  • path (String, nil)

    Path of file that `name` was extracted from

Returns:

  • (String)

    Qualified cop name

Raises:

  • (AmbiguousCopName)

    if a bare identifier with two possible namespaces is provided


103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/rubocop/cop/registry.rb', line 103

def qualified_cop_name(name, path, warn: true)
  badge = Badge.parse(name)
  print_warning(name, path) if warn && department_missing?(badge, name)
  return name if registered?(badge)

  potential_badges = qualify_badge(badge)

  case potential_badges.size
  when 0 then name # No namespace found. Deal with it later in caller.
  when 1 then resolve_badge(badge, potential_badges.first, path)
  else raise AmbiguousCopName.new(badge, path, potential_badges)
  end
end

#select(&block) ⇒ Object


193
194
195
# File 'lib/rubocop/cop/registry.rb', line 193

def select(&block)
  cops.select(&block)
end

#sort!Object


186
187
188
189
190
191
# File 'lib/rubocop/cop/registry.rb', line 186

def sort!
  clear_enrollment_queue
  @registry = Hash[@registry.sort_by { |badge, _| badge.cop_name }]

  self
end

#to_hHash{String => Array<Class>}

Returns:

  • (Hash{String => Array<Class>})

137
138
139
140
# File 'lib/rubocop/cop/registry.rb', line 137

def to_h
  clear_enrollment_queue
  @cops_by_cop_name
end

#unqualified_cop_namesObject


129
130
131
132
133
134
# File 'lib/rubocop/cop/registry.rb', line 129

def unqualified_cop_names
  clear_enrollment_queue
  @unqualified_cop_names ||=
    Set.new(@cops_by_cop_name.keys.map { |qn| File.basename(qn) }) <<
    'RedundantCopDisableDirective'
end

#with_department(department) ⇒ Registry

Returns Cops for that specific department.

Returns:

  • (Registry)

    Cops for that specific department.


53
54
55
56
# File 'lib/rubocop/cop/registry.rb', line 53

def with_department(department)
  clear_enrollment_queue
  with(@departments.fetch(department, []))
end

#without_department(department) ⇒ Registry

Returns Cops not for a specific department.

Returns:

  • (Registry)

    Cops not for a specific department.


59
60
61
62
63
64
65
# File 'lib/rubocop/cop/registry.rb', line 59

def without_department(department)
  clear_enrollment_queue
  without_department = @departments.dup
  without_department.delete(department)

  with(without_department.values.flatten)
end