From 04d1c5ca0cde241f666225460207c874eae591d9 Mon Sep 17 00:00:00 2001 From: Daniel Vandersluis Date: Wed, 15 Sep 2021 15:41:26 -0400 Subject: [PATCH] Allow safety information to be added to cop descriptions. 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. --- .yardopts | 1 + lib/rubocop/cop/generator.rb | 5 +++++ lib/rubocop/cops_documentation_generator.rb | 22 ++++++++++++++++----- spec/rubocop/cop/generator_spec.rb | 5 +++++ 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/.yardopts b/.yardopts index d0ca88828ed..4419be7d6b1 100644 --- a/.yardopts +++ b/.yardopts @@ -1,2 +1,3 @@ --markup markdown --hide-void-return +--tag safety:"Cop Safety Information" diff --git a/lib/rubocop/cop/generator.rb b/lib/rubocop/cop/generator.rb index c03f5da170a..af8b6b187d6 100644 --- a/lib/rubocop/cop/generator.rb +++ b/lib/rubocop/cop/generator.rb @@ -24,6 +24,11 @@ module %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. # diff --git a/lib/rubocop/cops_documentation_generator.rb b/lib/rubocop/cops_documentation_generator.rb index 1c0c8daaef8..a17f094ecf2 100644 --- a/lib/rubocop/cops_documentation_generator.rb +++ b/lib/rubocop/cops_documentation_generator.rb @@ -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) @@ -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) @@ -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?}" @@ -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) diff --git a/spec/rubocop/cop/generator_spec.rb b/spec/rubocop/cop/generator_spec.rb index 9e9bd3223b5..7da341e7060 100644 --- a/spec/rubocop/cop/generator_spec.rb +++ b/spec/rubocop/cop/generator_spec.rb @@ -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. #