Skip to content

Commit

Permalink
Pluginfy RuboCop RSpec
Browse files Browse the repository at this point in the history
This PR adds support for RuboCop's Plugin feature:
rubocop/rubocop#13792

It replaces the ad-hoc `Inject` with RuboCop plugins introduced in RuboCop 1.72.

NOTE: Version 1.72.1 or later is specified, as it includes rubocop/rubocop#13837,
which removes the `Inject` from spec_helper.rb. While 1.72.0 is sufficient for runtime,
but specifying the patch version 1.72.1 keeps things simple.
  • Loading branch information
koic committed Feb 15, 2025
1 parent d29fd64 commit b96ee8d
Show file tree
Hide file tree
Showing 12 changed files with 60 additions and 82 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ jobs:
- uses: actions/checkout@v4
- name: Use oldest RuboCop allowed by gemspec
run: |
sed -nr "s/ *spec.add_dependency 'rubocop', '~> ([0-9\.]+)'/gem 'rubocop', '= \1'/p" \
rubocop-rspec.gemspec > Gemfile.local
sed -nr "s/ *spec.add_dependency 'rubocop', '~> ([0-9\.]+)'(, '>= ([0-9\.]+)')?/\
gem 'rubocop', '= \3' || '= \1'/p" rubocop-rspec.gemspec > Gemfile.local
cat Gemfile.local
- uses: ruby/setup-ruby@v1
with:
Expand Down
4 changes: 2 additions & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
inherit_from: .rubocop_todo.yml

require:
plugins:
- rubocop-performance
- rubocop-rake
- rubocop-rspec
- rubocop/cop/internal_affairs
- rubocop-internal_affairs

AllCops:
DisplayCopNames: true
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Don't let `RSpec/PredicateMatcher` replace `respond_to?` with two arguments with the RSpec `respond_to` matcher. ([@bquorning])
- Fix `RSpec/PredicateMatcher` support for `eql` and `equal` matchers. ([@bquorning])
- Pluginfy RuboCop RSpec. ([@koic])

## 3.4.0 (2025-01-20)

Expand Down
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,31 +48,34 @@ ways to do this:
Put this into your `.rubocop.yml`.

```yaml
require: rubocop-rspec
plugins: rubocop-rspec
```
Alternatively, use the following array notation when specifying multiple extensions.
```yaml
require:
plugins:
- rubocop-other-extension
- rubocop-rspec
```
Now you can run `rubocop` and it will automatically load the RuboCop RSpec
cops together with the standard cops.

> [!NOTE]
> The plugin system is supported in RuboCop 1.72+. In earlier versions, use `require` instead of `plugins`.

### Command line

```bash
rubocop --require rubocop-rspec
rubocop --plugin rubocop-rspec
```

### Rake task

```ruby
RuboCop::RakeTask.new do |task|
task.requires << 'rubocop-rspec'
task.plugins << 'rubocop-rspec'
end
```

Expand Down
10 changes: 6 additions & 4 deletions docs/modules/ROOT/pages/usage.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ There are three ways to do this:
Put this into your `.rubocop.yml`:

----
require: rubocop-rspec
plugins: rubocop-rspec
----

or, if you are using several extensions:

----
require:
plugins:
- rubocop-rspec
- rubocop-performance
----

Now you can run `rubocop` and it will automatically load the RuboCop RSpec
cops together with the standard cops.

NOTE: The plugin system is supported in RuboCop 1.72+. In earlier versions, use `require` instead of `plugins`.

=== RSpec DSL configuration

In case you https://github.com/rspec/rspec-core/blob/b0d0843a285693c64cdbe0c85726db155b46047e/lib/rspec/core/configuration.rb#L1122[define aliases for RSpec DSL], i.e. examples, example groups, hooks, or include example statements, you need to configure it so those elements are properly detected by RuboCop RSpec.
Expand Down Expand Up @@ -78,15 +80,15 @@ RuboCop RSpec's https://github.com/rubocop/rubocop-rspec/blob/a43424527c09fae2e6

[source,bash]
----
$ rubocop --require rubocop-rspec
$ rubocop --plugin rubocop-rspec
----

== Rake task

[source,ruby]
----
RuboCop::RakeTask.new do |task|
task.requires << 'rubocop-rspec'
task.plugins << 'rubocop-rspec'
end
----

Expand Down
4 changes: 1 addition & 3 deletions lib/rubocop-rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
require 'rubocop'

require_relative 'rubocop/rspec'
require_relative 'rubocop/rspec/inject'
require_relative 'rubocop/rspec/language'
require_relative 'rubocop/rspec/node'
require_relative 'rubocop/rspec/plugin'
require_relative 'rubocop/rspec/version'
require_relative 'rubocop/rspec/wording'

Expand All @@ -34,8 +34,6 @@
require_relative 'rubocop/rspec/example_group'
require_relative 'rubocop/rspec/hook'

RuboCop::RSpec::Inject.defaults!

require_relative 'rubocop/cop/rspec_cops'

# We have to register our autocorrect incompatibilities in RuboCop's cops
Expand Down
7 changes: 0 additions & 7 deletions lib/rubocop/rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,5 @@
module RuboCop
# RuboCop RSpec project namespace
module RSpec
PROJECT_ROOT = Pathname.new(__dir__).parent.parent.expand_path.freeze
CONFIG_DEFAULT = PROJECT_ROOT.join('config', 'default.yml').freeze

private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)

::RuboCop::ConfigObsoletion.files << PROJECT_ROOT.join('config',
'obsoletion.yml')
end
end
18 changes: 0 additions & 18 deletions lib/rubocop/rspec/inject.rb

This file was deleted.

35 changes: 35 additions & 0 deletions lib/rubocop/rspec/plugin.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

require 'lint_roller'

module RuboCop
module RSpec
# A plugin that integrates RuboCop RSpec with RuboCop's plugin system.
class Plugin < LintRoller::Plugin
def about
LintRoller::About.new(
name: 'rubocop-rspec',
version: Version::STRING,
homepage: 'https://github.com/rubocop/rubocop-rspec',
description: 'Code style checking for RSpec files.'
)
end

def supported?(context)
context.engine == :rubocop
end

def rules(_context)
project_root = Pathname.new(__dir__).join('../../..')

ConfigObsoletion.files << project_root.join('config', 'obsoletion.yml')

LintRoller::Rules.new(
type: :path,
config_format: :rubocop,
value: project_root.join('config/default.yml')
)
end
end
end
end
6 changes: 4 additions & 2 deletions rubocop-rspec.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ Gem::Specification.new do |spec|
spec.metadata = {
'changelog_uri' => 'https://github.com/rubocop/rubocop-rspec/blob/master/CHANGELOG.md',
'documentation_uri' => 'https://docs.rubocop.org/rubocop-rspec/',
'rubygems_mfa_required' => 'true'
'rubygems_mfa_required' => 'true',
'default_lint_roller_plugin' => 'RuboCop::RSpec::Plugin'
}

spec.add_dependency 'rubocop', '~> 1.61'
spec.add_dependency 'lint_roller', '~> 1.1'
spec.add_dependency 'rubocop', '~> 1.72', '>= 1.72.1'
end
40 changes: 0 additions & 40 deletions spec/rubocop/rspec/inject_spec.rb

This file was deleted.

2 changes: 2 additions & 0 deletions tasks/cops_documentation.rake
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ end

desc 'Generate docs of all cops departments'
task generate_cops_documentation: :yard_for_generate_documentation do
RuboCop::ConfigLoader.inject_defaults!("#{__dir__}/../config/default.yml")

generator = CopsDocumentationGenerator.new(
departments: %w[RSpec]
)
Expand Down

0 comments on commit b96ee8d

Please sign in to comment.