Skip to content

Commit

Permalink
Add new Gemspec/AddRuntimeDependency cop
Browse files Browse the repository at this point in the history
Follow up rubygems/rubygems#7799 (comment).

Prefer `add_dependency` over `add_runtime_dependency` because
`add_runtime_dependency` is considered soft-deprecated.

```ruby
# bad
Gem::Specification.new do |spec|
  spec.add_runtime_dependency('rubocop')
end

# good
Gem::Specification.new do |spec|
  spec.add_dependency('rubocop')
end
```

rubocop/ruby-style-guide#943 has been opened for the Style Guide.
  • Loading branch information
koic committed Jul 5, 2024
1 parent d92c51f commit 2638a2b
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#13030](https://github.com/rubocop/rubocop/pull/13030): Add new `Gemspec/AddRuntimeDependency` cop. ([@koic][])
8 changes: 8 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,14 @@ Bundler/OrderedGems:

#################### Gemspec ###############################

Gemspec/AddRuntimeDependency:
Description: 'Prefer `add_dependency` over `add_runtime_dependency`.'
Reference: https://github.com/rubygems/rubygems/issues/7799#issuecomment-2192720316
Enabled: pending
VersionAdded: '<<next>>'
Include:
- '**/*.gemspec'

Gemspec/DependencyVersion:
Description: 'Requires or forbids specifying gem dependency versions.'
Enabled: false
Expand Down
1 change: 1 addition & 0 deletions lib/rubocop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@
require_relative 'rubocop/cop/bundler/insecure_protocol_source'
require_relative 'rubocop/cop/bundler/ordered_gems'

require_relative 'rubocop/cop/gemspec/add_runtime_dependency'
require_relative 'rubocop/cop/gemspec/dependency_version'
require_relative 'rubocop/cop/gemspec/deprecated_attribute_assignment'
require_relative 'rubocop/cop/gemspec/development_dependencies'
Expand Down
38 changes: 38 additions & 0 deletions lib/rubocop/cop/gemspec/add_runtime_dependency.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Gemspec
# Prefer `add_dependency` over `add_runtime_dependency` because
# `add_dependency` is considered soft-deprecated.
#
# @example
#
# # bad
# Gem::Specification.new do |spec|
# spec.add_runtime_dependency('rubocop')
# end
#
# # good
# Gem::Specification.new do |spec|
# spec.add_dependency('rubocop')
# end
#
class AddRuntimeDependency < Base
extend AutoCorrector

MSG = 'Use `add_dependency` instead of `add_runtime_dependency`.'

RESTRICT_ON_SEND = %i[add_runtime_dependency].freeze

def on_send(node)
return if !node.receiver || node.arguments.empty?

add_offense(node.loc.selector) do |corrector|
corrector.replace(node.loc.selector, 'add_dependency')
end
end
end
end
end
end
20 changes: 10 additions & 10 deletions rubocop.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ Gem::Specification.new do |s|
'rubygems_mfa_required' => 'true'
}

s.add_runtime_dependency('json', '~> 2.3')
s.add_runtime_dependency('language_server-protocol', '>= 3.17.0')
s.add_runtime_dependency('parallel', '~> 1.10')
s.add_runtime_dependency('parser', '>= 3.3.0.2')
s.add_runtime_dependency('rainbow', '>= 2.2.2', '< 4.0')
s.add_runtime_dependency('regexp_parser', '>= 2.4', '< 3.0')
s.add_runtime_dependency('rexml', '>= 3.2.5', '< 4.0')
s.add_runtime_dependency('rubocop-ast', '>= 1.31.1', '< 2.0')
s.add_runtime_dependency('ruby-progressbar', '~> 1.7')
s.add_runtime_dependency('unicode-display_width', '>= 2.4.0', '< 3.0')
s.add_dependency('json', '~> 2.3')
s.add_dependency('language_server-protocol', '>= 3.17.0')
s.add_dependency('parallel', '~> 1.10')
s.add_dependency('parser', '>= 3.3.0.2')
s.add_dependency('rainbow', '>= 2.2.2', '< 4.0')
s.add_dependency('regexp_parser', '>= 2.4', '< 3.0')
s.add_dependency('rexml', '>= 3.2.5', '< 4.0')
s.add_dependency('rubocop-ast', '>= 1.31.1', '< 2.0')
s.add_dependency('ruby-progressbar', '~> 1.7')
s.add_dependency('unicode-display_width', '>= 2.4.0', '< 3.0')
end
46 changes: 46 additions & 0 deletions spec/rubocop/cop/gemspec/add_runtime_dependency_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Gemspec::AddRuntimeDependency, :config do
it 'registers an offense when using `add_runtime_dependency`' do
expect_offense(<<~RUBY)
Gem::Specification.new do |spec|
spec.add_runtime_dependency('rubocop')
^^^^^^^^^^^^^^^^^^^^^^ Use `add_dependency` instead of `add_runtime_dependency`.
end
RUBY

expect_correction(<<~RUBY)
Gem::Specification.new do |spec|
spec.add_dependency('rubocop')
end
RUBY
end

it 'does not register an offense when using `add_dependency`' do
expect_no_offenses(<<~RUBY)
Gem::Specification.new do |spec|
spec.add_dependency('rubocop')
end
RUBY
end

it 'does not register an offense when using `add_development_dependency`' do
expect_no_offenses(<<~RUBY)
Gem::Specification.new do |spec|
spec.add_development_dependency('rubocop')
end
RUBY
end

it 'does not register an offense when using `add_runtime_dependency` without receiver' do
expect_no_offenses(<<~RUBY)
add_runtime_dependency('rubocop')
RUBY
end

it 'does not register an offense when using `add_runtime_dependency` without arguments' do
expect_no_offenses(<<~RUBY)
spec.add_runtime_dependency
RUBY
end
end

0 comments on commit 2638a2b

Please sign in to comment.