Skip to content

Commit

Permalink
Add Cop.documentation_url
Browse files Browse the repository at this point in the history
  • Loading branch information
marcandre authored and bbatsov committed Aug 25, 2020
1 parent 6b26104 commit d0417d6
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -14,6 +14,8 @@
* [#8531](https://github.com/rubocop-hq/rubocop/issues/8531): Add new `Lint/EmptyFile` cop. ([@fatkodima][])
* Add new `Lint/TrailingCommaInAttributeDeclaration` cop. ([@drenmi][])
* [#8578](https://github.com/rubocop-hq/rubocop/pull/8578): Add `:restore_registry` context and `stub_cop_class` helper class. ([@marcandre][])
* [#8579](https://github.com/rubocop-hq/rubocop/pull/8579): Add `Cop.documentation_url`. ([@marcandre][])


### Bug fixes

Expand Down
1 change: 1 addition & 0 deletions lib/rubocop.rb
Expand Up @@ -34,6 +34,7 @@
require_relative 'rubocop/cop/base'
require_relative 'rubocop/cop/cop'
require_relative 'rubocop/cop/commissioner'
require_relative 'rubocop/cop/documentation'
require_relative 'rubocop/cop/corrector'
require_relative 'rubocop/cop/force'
require_relative 'rubocop/cop/severity'
Expand Down
16 changes: 16 additions & 0 deletions lib/rubocop/cop/base.rb
Expand Up @@ -56,6 +56,14 @@ def self.autocorrect_incompatible_with
[]
end

# Cops (other than builtin) are encouraged to implement this
# @return [String, nil]
#
# @api public
def self.documentation_url
Documentation.url_for(self) if builtin?
end

def initialize(config = nil, options = nil)
@config = config || Config.new
@options = options || { debug: false }
Expand Down Expand Up @@ -297,6 +305,14 @@ def complete_investigation

### Actually private methods

def self.builtin?
return false unless (m = instance_methods(false).first) # any custom method will do

path, _line = instance_method(m).source_location
path.start_with?(__dir__)
end
private_class_method :builtin?

def reset_investigation
@currently_disabled_lines = @current_offenses = @processed_source = @current_corrector = nil
end
Expand Down
22 changes: 22 additions & 0 deletions lib/rubocop/cop/documentation.rb
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module RuboCop
module Cop
# Helpers for builtin documentation
module Documentation
module_function

# @api private
def department_to_basename(department)
"cops_#{department.downcase}"
end

# @api private
def url_for(cop_class)
base = department_to_basename(cop_class.department)
fragment = cop_class.cop_name.downcase.gsub(/[^a-z]/, '')
"https://docs.rubocop.org/rubocop/#{base}.html##{fragment}"
end
end
end
end
5 changes: 3 additions & 2 deletions lib/rubocop/cops_documentation_generator.rb
Expand Up @@ -2,6 +2,7 @@

# Class for generating documentation of all cops departments
class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
include ::RuboCop::Cop::Documentation
# This class will only generate documentation for cops that belong to one of
# the departments given in the `departments` array. E.g. if we only wanted
# documentation for Lint cops:
Expand Down Expand Up @@ -210,7 +211,7 @@ def print_cops_of_department(department)
selected_cops.each do |cop|
content << print_cop_with_doc(cop)
end
file_name = "#{Dir.pwd}/docs/modules/ROOT/pages/cops_#{department.downcase}.adoc"
file_name = "#{Dir.pwd}/docs/modules/ROOT/pages/#{department_to_basename(department)}.adoc"
File.open(file_name, 'w') do |file|
puts "* generated #{file_name}"
file.write("#{content.strip}\n")
Expand Down Expand Up @@ -243,7 +244,7 @@ def cop_code(cop)

def table_of_content_for_department(department)
type_title = department[0].upcase + department[1..-1]
filename = "cops_#{department.downcase}.adoc"
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
Expand Down
16 changes: 16 additions & 0 deletions spec/rubocop/cop/cop_spec.rb
Expand Up @@ -56,6 +56,22 @@
end
end

describe '.documentation_url' do
subject(:url) { cop_class.documentation_url }

describe 'for a builtin cop class' do
let(:cop_class) { RuboCop::Cop::Layout::BlockEndNewline }

it { is_expected.to eq 'https://docs.rubocop.org/rubocop/cops_layout.html#layoutblockendnewline' } # rubocop:disable Layout/LineLength
end

describe 'for a custom cop class', :restore_registry do
let(:cop_class) { stub_cop_class('Some::Cop') { def foo; end } }

it { is_expected.to eq nil }
end
end

it 'keeps track of offenses' do
cop.add_offense(nil, location: location, message: 'message')

Expand Down

0 comments on commit d0417d6

Please sign in to comment.