Skip to content

Commit

Permalink
Allow safety information to be added to cop descriptions.
Browse files Browse the repository at this point in the history
Register a `@safety` custom YARD tag, and uses it to create a new section to the documentation about cop safety. Also updates the `new_cop` template to add the `@safety` tag section.
  • Loading branch information
dvandersluis authored and bbatsov committed Sep 20, 2021
1 parent 3c8e9f4 commit 04d1c5c
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 5 deletions.
1 change: 1 addition & 0 deletions .yardopts
@@ -1,2 +1,3 @@
--markup markdown
--hide-void-return
--tag safety:"Cop Safety Information"
5 changes: 5 additions & 0 deletions lib/rubocop/cop/generator.rb
Expand Up @@ -24,6 +24,11 @@ module %<department>s
# `SupportedStyle` and unique configuration, there needs to be examples.
# Examples must have valid Ruby syntax. Do not use upticks.
#
# @safety
# Delete this section if the cop is not unsafe (`Safe: false` or
# `SafeAutoCorrect: false`), or use it to explain how the cop is
# unsafe.
#
# @example EnforcedStyle: bar (default)
# # Description of the `bar` style.
#
Expand Down
22 changes: 17 additions & 5 deletions lib/rubocop/cops_documentation_generator.rb
Expand Up @@ -33,11 +33,12 @@ def cops_of_department(department)
cops.with_department(department).sort!
end

def cops_body(cop, description, examples_objects, pars)
def cops_body(cop, description, examples_objects, safety_objects, pars) # rubocop:disable Metrics/AbcSize
content = h2(cop.cop_name)
content << required_ruby_version(cop)
content << properties(cop)
content << "#{description}\n"
content << safety_object(safety_objects) if safety_objects.any? { |s| !s.text.blank? }
content << examples(examples_objects) if examples_objects.count.positive?
content << configurations(pars)
content << references(cop)
Expand All @@ -52,6 +53,16 @@ def examples(examples_object)
end
end

def safety_object(safety_object_objects)
safety_object_objects.each_with_object(h3('Safety').dup) do |safety_object, content|
next if safety_object.text.blank?

content << "\n" unless content.end_with?("\n\n")
content << safety_object.text
content << "\n"
end
end

def required_ruby_version(cop)
return '' unless cop.respond_to?(:required_minimum_ruby_version)

Expand All @@ -61,8 +72,8 @@ def required_ruby_version(cop)
# rubocop:disable Metrics/MethodLength
def properties(cop)
header = [
'Enabled by default', 'Safe', 'Supports autocorrection', 'VersionAdded',
'VersionChanged'
'Enabled by default', 'Safe', 'Supports autocorrection', 'Version Added',
'Version Changed'
]
autocorrect = if cop.support_autocorrect?
"Yes#{' (Unsafe)' unless cop.new(config).safe_autocorrect?}"
Expand Down Expand Up @@ -217,12 +228,13 @@ def print_cop_with_doc(cop)
]
pars = cop_config.reject { |k| non_display_keys.include? k }
description = 'No documentation'
examples_object = []
examples_object = safety_object = []
cop_code(cop) do |code_object|
description = code_object.docstring unless code_object.docstring.blank?
examples_object = code_object.tags('example')
safety_object = code_object.tags('safety')
end
cops_body(cop, description, examples_object, pars)
cops_body(cop, description, examples_object, safety_object, pars)
end

def cop_code(cop)
Expand Down
5 changes: 5 additions & 0 deletions spec/rubocop/cop/generator_spec.rb
Expand Up @@ -25,6 +25,11 @@ module Style
# `SupportedStyle` and unique configuration, there needs to be examples.
# Examples must have valid Ruby syntax. Do not use upticks.
#
# @safety
# Delete this section if the cop is not unsafe (`Safe: false` or
# `SafeAutoCorrect: false`), or use it to explain how the cop is
# unsafe.
#
# @example EnforcedStyle: bar (default)
# # Description of the `bar` style.
#
Expand Down

0 comments on commit 04d1c5c

Please sign in to comment.