123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::CLI::Command::Explain Private

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Base
Instance Chain:
self, CopNames, Base
Inherits: RuboCop::CLI::Command::Base
Defined in: lib/rubocop/cli/command/explain.rb

Overview

Explains what a single cop does: its description, how it is configured, whether it corrects, and the examples from its own documentation.

Constant Summary

  • METADATA_KEYS =

    Keys that describe the cop to RuboCop itself rather than something a user would set, so they are reported in their own section or not at all.

    # File 'lib/rubocop/cli/command/explain.rb', line 16
    %w[
      Description StyleGuide Reference References Enabled Safe SafeAutoCorrect
      AutoCorrect VersionAdded VersionChanged Include Exclude Details Preview
    ].freeze

Class Attribute Summary

Base - Inherited

Class Method Summary

Base - Inherited

Instance Attribute Summary

Base - Inherited

Instance Method Summary

CopNames - Included

#cop_class_for, #department?, #department_message,
#known_cop_classes

The cops among names that exist, so a command can report on what it understood before #validate_cop_names! objects to the rest.

#unknown_cop_message, #validate_cop_names!

Constructor Details

.new(env) ⇒ Explain

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 21

def initialize(env)
  super

  @config = @config_store.for(PathUtil.pwd)
end

Instance Method Details

#autocorrect_description(cop_class, cop_config) (private)

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 105

def autocorrect_description(cop_class, cop_config)
  return 'not supported' unless cop_class.support_autocorrect?

  if cop_config.fetch('Safe', true) && cop_config.fetch('SafeAutoCorrect', true)
    'safe, applied by -a'
  else
    'unsafe, applied by -A only'
  end
end

#configuration_lines(cop_config) (private)

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 122

def configuration_lines(cop_config)
  (cop_config.keys - METADATA_KEYS).sort.map do |key|
    "#{key}: #{format_value(cop_config[key])}"
  end
end

#description_lines(cop_config) (private)

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 68

def description_lines(cop_config)
  Array(cop_config['Description']).flat_map { |line| line.split("\n") }
end

#documentation_sections(cop_class, description) (private)

The comment above the class opens by restating the description, which is already printed above, so that opening is dropped.

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 140

def documentation_sections(cop_class, description)
  sections = Cop::CopDocumentation.new(cop_class).sections
  sections.filter_map do |title, body|
    body -= description if title == 'Details'
    body = strip_blank(body)
    [title, body] unless body.empty?
  end
end

#format_value(value) (private)

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 128

def format_value(value)
  value.is_a?(Array) ? value.join(', ') : value.to_s
end

#patterns_line(label, patterns) (private)

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 91

def patterns_line(label, patterns)
  patterns = Array(patterns).compact
  return [] if patterns.empty?

  ["#{label}#{patterns.map { |pattern| readable_pattern(pattern) }.join(', ')}"]
end

#property_lines(cop_class, cop_config) (private)

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 72

def property_lines(cop_class, cop_config)
  [
    "Enabled:     #{cop_config.fetch('Enabled', true)}",
    "Safe:        #{cop_config.fetch('Safe', true)}",
    "Autocorrect: #{autocorrect_description(cop_class, cop_config)}",
    *version_lines(cop_config),
    *scope_lines(cop_config)
  ]
end

#readable_pattern(pattern) (private)

Exclude patterns are absolutized against the config that set them, which makes for a wall of identical prefixes. A user config can also hold a regexp rather than a glob.

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 101

def readable_pattern(pattern)
  pattern.is_a?(String) ? PathUtil.smart_path(pattern) : pattern.inspect
end

#reference_lines(cop_class, cop_config) (private)

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 132

def reference_lines(cop_class, cop_config)
  annotator = Cop::MessageAnnotator.new(@config, cop_class.cop_name, cop_config, {})

  [*annotator.urls, Cop::Documentation.url_for(cop_class, @config)].compact
end

#run

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 27

def run
  names = @options[:explain]

  known_cop_classes(names).each_with_index do |cop_class, index|
    puts if index.positive?
    print_explanation(cop_class)
  end

  # Checked after printing, so a typo in a list does not cost you the
  # explanations you asked for alongside it.
  validate_cop_names!(names)
end

#scope_lines(cop_config) (private)

Which files the cop looks at. A cop that only runs on Gemfiles explains an absent offense better than anything else here does.

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 84

def scope_lines(cop_config)
  [
    *patterns_line('Applies to:  ', cop_config['Include']),
    *patterns_line('Excludes:    ', cop_config['Exclude'])
  ]
end

#strip_blank(lines) (private)

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 149

def strip_blank(lines)
  lines.drop_while(&:empty?).reverse.drop_while(&:empty?).reverse
end

#version_lines(cop_config) (private)

[ GitHub ]

  
# File 'lib/rubocop/cli/command/explain.rb', line 115

def version_lines(cop_config)
  lines = []
  lines << "Added:       #{cop_config['VersionAdded']}" if cop_config['VersionAdded']
  lines << "Changed:     #{cop_config['VersionChanged']}" if cop_config['VersionChanged']
  lines
end