Class: CopsDocumentationGenerator Private
Do not use. This class is for internal use only.
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Instance Chain:
|
|
Inherits: | Object |
Defined in: | lib/rubocop/cops_documentation_generator.rb |
Overview
Class for generating documentation of all cops departments
Class Method Summary
-
.new(departments: []) ⇒ CopsDocumentationGenerator
constructor
Internal use only
This class will only generate documentation for cops that belong to one of the departments given in the
departments
array.
Instance Attribute Summary
- #config readonly private Internal use only
- #cops readonly private Internal use only
- #departments readonly private Internal use only
- #docs_path readonly private Internal use only
Instance Method Summary
- #call Internal use only
- #check_examples_to_have_the_default_enforced_style!(examples_object, cop) private Internal use only
- #code_example(ruby_code) private Internal use only
- #configurable_values(pars, name) private Internal use only
- #configuration_name(department, name) private Internal use only
- #configurations(department, pars) private Internal use only
- #cop_code(cop) private Internal use only
- #cop_status(status) private Internal use only
-
#cops_body(cop, description, examples_objects, safety_objects, see_objects, pars)
private
Internal use only
Metrics/ParameterLists.
- #cops_of_department(department) private Internal use only
- #examples(examples_object) private Internal use only
- #footer_for_department(department) private Internal use only
- #format_table_value(val) private Internal use only
- #h2(title) private Internal use only
- #h3(title) private Internal use only
- #h4(title) private Internal use only
- #print_cop_with_doc(cop) private Internal use only
- #print_cops_of_department(department) private Internal use only
- #print_table_of_contents private Internal use only
- #properties(cop) private Internal use only
- #references(cop, see_objects) private Internal use only
- #required_ruby_version(cop) private Internal use only
- #safety_object(safety_object_objects) private Internal use only
- #table_contents private Internal use only
- #table_of_content_for_department(department) private Internal use only
- #to_table(header, content) private Internal use only
- #wrap_backtick(value) private Internal use only
::RuboCop::Cop::Documentation
- Included
Instance Attribute Details
#config (readonly, private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 34
attr_reader :departments, :cops, :config, :docs_path
#cops (readonly, private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 34
attr_reader :departments, :cops, :config, :docs_path
#departments (readonly, private)
[ GitHub ]#docs_path (readonly, private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 34
attr_reader :departments, :cops, :config, :docs_path
Instance Method Details
#call
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 23
def call YARD::Registry.load! departments.each { |department| print_cops_of_department(department) } print_table_of_contents ensure RuboCop::ConfigLoader.default_configuration = nil end
#check_examples_to_have_the_default_enforced_style!(examples_object, cop) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 54
def check_examples_to_have_the_default_enforced_style!(examples_object, cop) return if examples_object.none? examples_describing_enforced_style = examples_object.map(&:name).grep(/EnforcedStyle:/) return if examples_describing_enforced_style.none? if examples_describing_enforced_style.index { |name| name.match?('default') }.nonzero? raise "Put the example with the default EnforcedStyle on top for #{cop.cop_name}" end return if examples_describing_enforced_style.any? { |name| name.match?('default') } raise "Specify the default EnforcedStyle for #{cop.cop_name}" end
#code_example(ruby_code) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 138
def code_example(ruby_code) content = +"[source,ruby]\n----\n" content << ruby_code.text.gsub('@good', '# good').gsub('@bad', '# bad').strip content << "\n----\n" content end
#configurable_values(pars, name) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 171
def configurable_values(pars, name) case name when /^Enforced/ supported_style_name = RuboCop::Cop::Util.to_supported_styles(name) format_table_value(pars[supported_style_name]) when 'IndentationWidth' 'Integer' when 'Database' format_table_value(pars['SupportedDatabases']) else case pars[name] when String 'String' when Integer 'Integer' when Float 'Float' when true, false 'Boolean' when Array 'Array' else '' end end end
#configuration_name(department, name) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 163
def configuration_name(department, name) return name unless name == 'AllowMultilineFinalElement' filename = "#{department_to_basename(department)}.adoc" "xref:#{filename}#allowmultilinefinalelement[AllowMultilineFinalElement]" end
#configurations(department, pars) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 145
def configurations(department, pars) return '' if pars.empty? header = ['Name', 'Default value', 'Configurable values'] configs = pars .each_key .reject { |key| key.start_with?('Supported') } .reject { |key| key.start_with?('AllowMultipleStyles') } content = configs.map do |name| configurable = configurable_values(pars, name) default = format_table_value(pars[name]) [configuration_name(department, name), default, configurable] end h3('Configurable attributes') + to_table(header, content) end
#cop_code(cop) (private)
[ GitHub ]#cop_status(status) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 336
def cop_status(status) return 'Disabled' unless status status == 'pending' ? 'Pending' : 'Enabled' end
#cops_body(cop, description, examples_objects, safety_objects, see_objects, pars) (private)
Metrics/ParameterLists
# File 'lib/rubocop/cops_documentation_generator.rb', line 40
def cops_body(cop, description, examples_objects, safety_objects, see_objects, pars) # rubocop:disable Metrics/AbcSize, Metrics/ParameterLists check_examples_to_have_the_default_enforced_style!(examples_objects, cop) 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.any? content << configurations(cop.department, pars) content << references(cop, see_objects) content end
#cops_of_department(department) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 36
def cops_of_department(department) cops.with_department(department).sort! end
#examples(examples_object) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 69
def examples(examples_object) examples_object.each_with_object(h3('Examples').dup) do |example, content| content << "\n" unless content.end_with?("\n\n") content << h4(example.name) unless example.name == '' content << code_example(example) end end
#format_table_value(val) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 209
def format_table_value(val) value = case val when Array if val.empty? '`[]`' else val.map { |config| format_table_value(config) }.join(', ') end else wrap_backtick(val.nil? ? '<none>' : val) end value.gsub("#{Dir.pwd}/", '').rstrip end
#h2(title) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 118
def h2(title) content = +"\n" content << "== #{title}\n" content << "\n" content end
#h3(title) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 125
def h3(title) content = +"\n" content << "=== #{title}\n" content << "\n" content end
#h4(title) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 132
def h4(title) content = +"==== #{title}\n" content << "\n" content end
#print_cop_with_doc(cop) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 278
def print_cop_with_doc(cop) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength cop_config = config.for_cop(cop) non_display_keys = %w[ AutoCorrect Description Enabled StyleGuide Reference Safe SafeAutoCorrect VersionAdded VersionChanged ] pars = cop_config.reject { |k| non_display_keys.include? k } description = 'No documentation' examples_object = safety_object = see_object = [] cop_code(cop) do |code_object| description = code_object.docstring unless code_object.docstring.blank? examples_object = code_object. ('example') safety_object = code_object. ('safety') see_object = code_object. ('see') end cops_body(cop, description, examples_object, safety_object, see_object, pars) end
#print_cops_of_department(department) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 257
def print_cops_of_department(department) selected_cops = cops_of_department(department) content = +<<~HEADER //// Do NOT edit this file by hand directly, as it is automatically generated. Please make any necessary changes to the cop documentation within the source files themselves. //// = #{department} HEADER selected_cops.each { |cop| content << print_cop_with_doc(cop) } content << (department) file_name = "#{docs_path}/#{department_to_basename(department)}.adoc" File.open(file_name, 'w') do |file| puts "* generated #{file_name}" file.write("#{content.strip}\n") end end
#print_table_of_contents (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 316
def print_table_of_contents path = "#{docs_path}/cops.adoc" File.write(path, table_contents) and return unless File.exist?(path) original = File.read(path) content = +"// START_COP_LIST\n\n" content << table_contents content << "\n// END_COP_LIST" content = original.sub(%r{// START_COP_LIST.+// END_COP_LIST}m, content) File.write(path, content) end
#properties(cop) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 94
def properties(cop) header = [ 'Enabled by default', 'Safe', 'Supports autocorrection', 'Version Added', 'Version Changed' ] autocorrect = if cop.support_autocorrect? context = cop.new.always_autocorrect? ? 'Always' : 'Command-line only' "#{context}#{' (Unsafe)' unless cop.new(config).safe_autocorrect?}" else 'No' end cop_config = config.for_cop(cop) content = [[ cop_status(cop_config.fetch('Enabled')), cop_config.fetch('Safe', true) ? 'Yes' : 'No', autocorrect, cop_config.fetch('VersionAdded', '-'), cop_config.fetch('VersionChanged', '-') ]] "#{to_table(header, content)}\n" end
#references(cop, see_objects) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 233
def references(cop, see_objects) # rubocop:disable Metrics/AbcSize cop_config = config.for_cop(cop) urls = RuboCop::Cop::MessageAnnotator.new(config, cop.name, cop_config, {}).urls return '' if urls.empty? && see_objects.empty? content = h3('References') content << urls.map { |url| "* #{url}" }.join("\n") content << "\n" unless urls.empty? content << see_objects.map { |see| "* #{see.name}" }.join("\n") content << "\n" unless see_objects.empty? content end
#required_ruby_version(cop) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 87
def required_ruby_version(cop) return '' unless cop.respond_to?(:required_minimum_ruby_version) "NOTE: Required Ruby version: #{cop.required_minimum_ruby_version}\n\n" end
#safety_object(safety_object_objects) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 77
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
#table_contents (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 332
def table_contents departments.map { |department| table_of_content_for_department(department) }.join("\n") end
#table_of_content_for_department(department) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 304
def table_of_content_for_department(department) type_title = department[0].upcase + department[1..] filename = "#{department_to_basename(department)}.adoc" content = +"=== Department xref:#{filename}[#{type_title}]\n\n" cops_of_department(department).each do |cop| anchor = cop.cop_name.sub('/', '').downcase content << "* xref:#{filename}##{anchor}[#{cop.cop_name}]\n" end content end
#to_table(header, content) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 199
def to_table(header, content) table = ['|===', "| #{header.join(' | ')}\n\n"].join("\n") marked_contents = content.map do |plain_content| # Escape `|` with backslash to prevent the regexp `|` is not used as a table separator. plain_content.map { |c| "| #{c.gsub('|', '\|')}" }.join("\n") end table << marked_contents.join("\n\n") table << "\n|===\n" end
#wrap_backtick(value) (private)
[ GitHub ]# File 'lib/rubocop/cops_documentation_generator.rb', line 224
def wrap_backtick(value) if value.is_a?(String) # Use `+` to prevent text like `**/*.gemspec`, `spec/**/*` from being bold. value.include?('*') ? "`+#{value}+`" : "`#{value}`" else "`#{value}`" end end