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. #