All cops should have documentation
Summary
All cops should have documentation so that developers can understand the rationale behind them, how to fix them, and when they can be ignored. Historically, we have linked to new cop proposal issues for this, but this does not age well and does not present information in a consistent way.
Proposal
I think we can annotate cops similar to what we do for sidekiq workers, then auto-generate documentation based on these annotations. For example, CodeReuse/ActiveRecord can be annotated like so:
# frozen_string_literal: true
module Rubocop
module Cop
module CodeReuse
class ActiveRecord < OurBaseClassWhichImplementsAnnotations
purpose 'This cop denies the use of ActiveRecord methods outside of models.'
rationale 'Models should [encapsulate of data-layer logic](https://docs.gitlab.com/ee/development/reusing_abstractions.html#models).'
bad_examples 'Project.where(archived: true)'
good_examples 'Project.archived'
when_to_disable <<~MARKDOWN
This cop can be disabled if the caller is not an ActiveRecord model,
or if the code is used in a highly specific context that is unlikely
to be re-used. For example, the `.joins()` and `.where()` statements
for a query with a lateral join is unlikely to be re-used elsewhere in the codebase.
```ruby
::Ci::Runner.joins("JOIN LATERAL (#{lateral_query.to_sql}) builds_with_limit ON true")
.id_in(runner_ids)
.select(:id, Arel.star.count.as('count'))
.group(:id)
.index_by(&:id)
```
MARKDOWN
[... cop source]
end
end
end
end
We can then use ERB to auto-generate documentation for each cop, and link to these docs in the cop's message:
## `<%= cop_name =>`
<%= purpose =>
### Rationale
<%= rationale =>
### Examples
Good
```ruby
<%= good_examples =>
```
Bad
```ruby
<%= bad_examples =>
```
### When to disable
<%= when_to_disable =>
Continuation of: !227 (comment 2082367394)