Skip to content

Commit dc5d6a0

Browse files
committed
Simplify manual generation
Prefix the file list passed to YARD to avoid superclass ambiguity and failure to detect it before OUR base cop is analyzed. [47] pry(#<RuboCop::RSpec::DescriptionExtractor>)> @code_objects.select {|x| x.inspect =~ /class RuboCop::Cop/ }.map { |x| x.send(:yardoc).superclass.path } => ["RuboCop::Cop", ... "RuboCop::Cop", "RuboCop::Cop::Cop", "RuboCop::Cop::RSpec::Cop", ... "RuboCop::Cop::RSpec::Cop"]
1 parent 69f5012 commit dc5d6a0

File tree

4 files changed

+38
-47
lines changed

4 files changed

+38
-47
lines changed

bin/build_config

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ require 'rubocop-rspec'
99
require 'rubocop/rspec/description_extractor'
1010
require 'rubocop/rspec/config_formatter'
1111

12-
glob = File.join(__dir__, '..', 'lib', 'rubocop', 'cop', 'rspec',
12+
glob = File.join('lib', 'rubocop', 'cop', 'rspec',
1313
'{,capybara,factory_bot,rails}', '*.rb')
14-
YARD.parse(Dir[glob], [])
14+
# Due to YARD's sensitivity to file require order (as of 0.9.25),
15+
# we have to prepend the list with our base cop, RuboCop::Cop::RSpec::Cop.
16+
# Otherwise, cop's parent class for cops loaded before our base cop class
17+
# are detected as RuboCop::Cop::Cop, and that complicates the detection
18+
# of their relation with RuboCop RSpec.
19+
rspec_cop_path = File.join('lib', 'rubocop', 'cop', 'rspec', 'cop.rb')
20+
YARD.parse(Dir[glob].prepend(rspec_cop_path), [])
1521

1622
descriptions = RuboCop::RSpec::DescriptionExtractor.new(YARD::Registry.all).to_h
1723
current_config = YAML.load_file('config/default.yml')

lib/rubocop/cop/rspec/cop.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@
33
module RuboCop
44
module Cop
55
module RSpec
6-
# @abstract parent class to rspec cops
6+
# @abstract parent class to RSpec cops
77
#
88
# The criteria for whether rubocop-rspec analyzes a certain ruby file
99
# is configured via `AllCops/RSpec`. For example, if you want to
1010
# customize your project to scan all files within a `test/` directory
1111
# then you could add this to your configuration:
1212
#
1313
# @example configuring analyzed paths
14-
#
15-
# AllCops:
16-
# RSpec:
17-
# Patterns:
18-
# - '_test.rb$'
19-
# - '(?:^|/)test/'
14+
# # .rubocop.yml
15+
# # AllCops:
16+
# # RSpec:
17+
# # Patterns:
18+
# # - '_test.rb$'
19+
# # - '(?:^|/)test/'
2020
class Cop < ::RuboCop::Cop::Cop
2121
include RuboCop::RSpec::Language
2222
include RuboCop::RSpec::Language::NodePattern

lib/rubocop/rspec/description_extractor.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def to_h
2121

2222
# Decorator of a YARD code object for working with documented rspec cops
2323
class CodeObject
24-
COP_CLASS_NAMES = %w[RuboCop::Cop RuboCop::Cop::RSpec::Cop].freeze
24+
COP_CLASS_NAME = 'RuboCop::Cop::RSpec::Cop'
2525
RSPEC_NAMESPACE = 'RuboCop::Cop::RSpec'
2626

2727
def initialize(yardoc)
@@ -68,9 +68,7 @@ def documented_constant
6868
end
6969

7070
def cop_subclass?
71-
# FIXME: simplify
72-
73-
COP_CLASS_NAMES.include?(yardoc.superclass.path)
71+
yardoc.superclass.path == COP_CLASS_NAME
7472
end
7573

7674
def abstract?

tasks/cops_documentation.rake

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ task generate_cops_documentation: :yard_for_generate_documentation do
8585
h3('Configurable attributes') + to_table(header, content)
8686
end
8787

88-
# rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength
89-
def configurable_values(pars, name)
88+
def configurable_values(pars, name) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength
9089
case name
9190
when /^Enforced/
9291
supported_style_name = RuboCop::Cop::Util.to_supported_styles(name)
@@ -110,7 +109,6 @@ task generate_cops_documentation: :yard_for_generate_documentation do
110109
end
111110
end
112111
end
113-
# rubocop:enable Metrics/CyclomaticComplexity,Metrics/MethodLength
114112

115113
def to_table(header, content)
116114
table = [
@@ -121,8 +119,7 @@ task generate_cops_documentation: :yard_for_generate_documentation do
121119
table.join("\n") + "\n"
122120
end
123121

124-
# rubocop:disable Metrics/MethodLength
125-
def format_table_value(val)
122+
def format_table_value(val) # rubocop:disable Metrics/MethodLength
126123
value =
127124
case val
128125
when Array
@@ -136,20 +133,19 @@ task generate_cops_documentation: :yard_for_generate_documentation do
136133
end
137134
value.gsub("#{Dir.pwd}/", '').rstrip
138135
end
139-
# rubocop:enable Metrics/MethodLength
140136

141137
def cop_urls(config, cop)
142138
rubocop_version = Gem::Version.new(RuboCop::Version::STRING)
143139

144-
# Since Rubocop v0.75.0 and above, MessageAnnotator#new changed from:
140+
# Since RuboCop v0.75.0 and above, MessageAnnotator#new changed from:
145141
# def initialize(config, cop_config, options)
146142
# to:
147143
# def initialize(config, cop_name, cop_config, options)
148144
#
149-
# Since this library has a loose Rubocop dependency, we select the
145+
# Since this library has a loose RuboCop dependency, we select the
150146
# right arguments based on the installed version.
151147
#
152-
# TODO: When Rubocop < 0.75 is no longer supported, remove the second half
148+
# TODO: When RuboCop < 0.75 is no longer supported, remove the second half
153149
# of this condition.
154150

155151
if rubocop_version >= Gem::Version.new('0.75.0')
@@ -172,30 +168,29 @@ task generate_cops_documentation: :yard_for_generate_documentation do
172168
content
173169
end
174170

175-
# rubocop:disable Metrics/AbcSize
176-
# rubocop:disable Metrics/MethodLength
177-
def print_cops_of_department(cops, department, config)
178-
selected_cops = cops_of_department(cops, department).select do |cop|
179-
cop.to_s.start_with?('RuboCop::Cop::RSpec')
171+
def selected_cops(cops, department)
172+
cops_of_department(cops, department.to_sym).select do |cop|
173+
cop.name.start_with?('RuboCop::Cop::RSpec') &&
174+
cop.name != 'RuboCop::Cop::RSpec::Cop'
180175
end
176+
end
177+
178+
def print_cops_of_department(cops, department, config) # rubocop:disable Metrics/MethodLength
179+
selected_cops = selected_cops(cops, department)
181180
return if selected_cops.empty?
182181

183-
content = +"# #{department}\n"
184-
selected_cops.each do |cop|
185-
content << print_cop_with_doc(cop, config)
186-
end
182+
content = [
183+
"# #{department}\n",
184+
*selected_cops.map { |cop| print_cop_with_doc(cop, config) }
185+
].join
187186
file_name = "#{Dir.pwd}/manual/cops_#{department.downcase}.md"
188187
File.open(file_name, 'w') do |file|
189188
puts "* generated #{file_name}"
190-
file.write(content.strip + "\n")
189+
file.write(content)
191190
end
192191
end
193-
# rubocop:enable Metrics/AbcSize
194-
# rubocop:enable Metrics/MethodLength
195192

196-
# rubocop:disable Metrics/AbcSize
197-
# rubocop:disable Metrics/MethodLength
198-
def print_cop_with_doc(cop, config)
193+
def print_cop_with_doc(cop, config) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
199194
t = config.for_cop(cop)
200195
non_display_keys = %w[Description Enabled StyleGuide Reference]
201196
pars = t.reject { |k| non_display_keys.include? k }
@@ -209,15 +204,9 @@ task generate_cops_documentation: :yard_for_generate_documentation do
209204
end
210205
cops_body(config, cop, description, examples_object, pars)
211206
end
212-
# rubocop:enable Metrics/AbcSize
213-
# rubocop:enable Metrics/MethodLength
214207

215-
# rubocop:disable Metrics/AbcSize
216-
# rubocop:disable Metrics/MethodLength
217208
def table_of_content_for_department(cops, department)
218-
selected_cops = cops_of_department(cops, department.to_sym).select do |cop|
219-
cop.to_s.start_with?('RuboCop::Cop::RSpec')
220-
end
209+
selected_cops = selected_cops(cops, department)
221210
return if selected_cops.empty?
222211

223212
type_title = department[0].upcase + department[1..-1]
@@ -230,8 +219,6 @@ task generate_cops_documentation: :yard_for_generate_documentation do
230219

231220
content
232221
end
233-
# rubocop:enable Metrics/AbcSize
234-
# rubocop:enable Metrics/MethodLength
235222

236223
def print_table_of_contents(cops)
237224
path = "#{Dir.pwd}/manual/cops.md"
@@ -254,7 +241,7 @@ task generate_cops_documentation: :yard_for_generate_documentation do
254241
.map(&:to_s)
255242
.sort
256243
.map { |department| table_of_content_for_department(cops, department) }
257-
.reject(&:nil?)
244+
.compact
258245
.join("\n")
259246
end
260247

0 commit comments

Comments
 (0)