docs/modules/ROOT/pages/cops_gemspec.adoc
////
Do NOT edit this file by hand directly, as it is automatically generated.
Please make any necessary changes to the cop documentation within the source files themselves.
////
= Gemspec
[#gemspecaddruntimedependency]
== Gemspec/AddRuntimeDependency
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Pending
| Yes
| Always
| 1.65
| -
|===
Prefer `add_dependency` over `add_runtime_dependency` as the latter is
considered soft-deprecated.
[#examples-gemspecaddruntimedependency]
=== Examples
[source,ruby]
----
# bad
Gem::Specification.new do |spec|
spec.add_runtime_dependency('rubocop')
end
# good
Gem::Specification.new do |spec|
spec.add_dependency('rubocop')
end
----
[#configurable-attributes-gemspecaddruntimedependency]
=== Configurable attributes
|===
| Name | Default value | Configurable values
| Include
| `+**/*.gemspec+`
| Array
|===
[#references-gemspecaddruntimedependency]
=== References
* https://rubystyle.guide#add_dependency_vs_add_runtime_dependency
* https://github.com/rubygems/rubygems/issues/7799#issuecomment-2192720316
[#gemspecdependencyversion]
== Gemspec/DependencyVersion
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Disabled
| Yes
| No
| 1.29
| -
|===
Enforce that gem dependency version specifications or a commit reference (branch,
ref, or tag) are either required or forbidden.
[#examples-gemspecdependencyversion]
=== Examples
[#enforcedstyle_-required-_default_-gemspecdependencyversion]
==== EnforcedStyle: required (default)
[source,ruby]
----
# bad
Gem::Specification.new do |spec|
spec.add_dependency 'parser'
end
# bad
Gem::Specification.new do |spec|
spec.add_development_dependency 'parser'
end
# good
Gem::Specification.new do |spec|
spec.add_dependency 'parser', '>= 2.3.3.1', '< 3.0'
end
# good
Gem::Specification.new do |spec|
spec.add_development_dependency 'parser', '>= 2.3.3.1', '< 3.0'
end
----
[#enforcedstyle_-forbidden-gemspecdependencyversion]
==== EnforcedStyle: forbidden
[source,ruby]
----
# bad
Gem::Specification.new do |spec|
spec.add_dependency 'parser', '>= 2.3.3.1', '< 3.0'
end
# bad
Gem::Specification.new do |spec|
spec.add_development_dependency 'parser', '>= 2.3.3.1', '< 3.0'
end
# good
Gem::Specification.new do |spec|
spec.add_dependency 'parser'
end
# good
Gem::Specification.new do |spec|
spec.add_development_dependency 'parser'
end
----
[#configurable-attributes-gemspecdependencyversion]
=== Configurable attributes
|===
| Name | Default value | Configurable values
| EnforcedStyle
| `required`
| `required`, `forbidden`
| Include
| `+**/*.gemspec+`
| Array
| AllowedGems
| `[]`
| Array
|===
[#gemspecdeprecatedattributeassignment]
== Gemspec/DeprecatedAttributeAssignment
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Pending
| Yes
| Always
| 1.30
| 1.40
|===
Checks that deprecated attributes are not set in a gemspec file.
Removing deprecated attributes allows the user to receive smaller packed gems.
[#examples-gemspecdeprecatedattributeassignment]
=== Examples
[source,ruby]
----
# bad
Gem::Specification.new do |spec|
spec.name = 'your_cool_gem_name'
spec.test_files = Dir.glob('test/**/*')
end
# bad
Gem::Specification.new do |spec|
spec.name = 'your_cool_gem_name'
spec.test_files += Dir.glob('test/**/*')
end
# good
Gem::Specification.new do |spec|
spec.name = 'your_cool_gem_name'
end
----
[#configurable-attributes-gemspecdeprecatedattributeassignment]
=== Configurable attributes
|===
| Name | Default value | Configurable values
| Severity
| `warning`
| String
| Include
| `+**/*.gemspec+`
| Array
|===
[#gemspecdevelopmentdependencies]
== Gemspec/DevelopmentDependencies
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Pending
| Yes
| No
| 1.44
| -
|===
Enforce that development dependencies for a gem are specified in
`Gemfile`, rather than in the `gemspec` using
`add_development_dependency`. Alternatively, using `EnforcedStyle:
gemspec`, enforce that all dependencies are specified in `gemspec`,
rather than in `Gemfile`.
[#examples-gemspecdevelopmentdependencies]
=== Examples
[#enforcedstyle_-gemfile-_default_-gemspecdevelopmentdependencies]
==== EnforcedStyle: Gemfile (default)
[source,ruby]
----
# Specify runtime dependencies in your gemspec,
# but all other dependencies in your Gemfile.
# bad
# example.gemspec
s.add_development_dependency "foo"
# good
# Gemfile
gem "foo"
# good
# gems.rb
gem "foo"
# good (with AllowedGems: ["bar"])
# example.gemspec
s.add_development_dependency "bar"
----
[#enforcedstyle_-gems_rb-gemspecdevelopmentdependencies]
==== EnforcedStyle: gems.rb
[source,ruby]
----
# Specify runtime dependencies in your gemspec,
# but all other dependencies in your Gemfile.
#
# Identical to `EnforcedStyle: Gemfile`, but with a different error message.
# Rely on Bundler/GemFilename to enforce the use of `Gemfile` vs `gems.rb`.
# bad
# example.gemspec
s.add_development_dependency "foo"
# good
# Gemfile
gem "foo"
# good
# gems.rb
gem "foo"
# good (with AllowedGems: ["bar"])
# example.gemspec
s.add_development_dependency "bar"
----
[#enforcedstyle_-gemspec-gemspecdevelopmentdependencies]
==== EnforcedStyle: gemspec
[source,ruby]
----
# Specify all dependencies in your gemspec.
# bad
# Gemfile
gem "foo"
# good
# example.gemspec
s.add_development_dependency "foo"
# good (with AllowedGems: ["bar"])
# Gemfile
gem "bar"
----
[#configurable-attributes-gemspecdevelopmentdependencies]
=== Configurable attributes
|===
| Name | Default value | Configurable values
| EnforcedStyle
| `Gemfile`
| `Gemfile`, `gems.rb`, `gemspec`
| AllowedGems
| `[]`
| Array
| Include
| `+**/*.gemspec+`, `+**/Gemfile+`, `+**/gems.rb+`
| Array
|===
[#gemspecduplicatedassignment]
== Gemspec/DuplicatedAssignment
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Enabled
| Yes
| No
| 0.52
| 1.40
|===
An attribute assignment method calls should be listed only once
in a gemspec.
Assigning to an attribute with the same name using `spec.foo =` will be
an unintended usage. On the other hand, duplication of methods such
as `spec.requirements`, `spec.add_runtime_dependency`, and others are
permitted because it is the intended use of appending values.
[#examples-gemspecduplicatedassignment]
=== Examples
[source,ruby]
----
# bad
Gem::Specification.new do |spec|
spec.name = 'rubocop'
spec.name = 'rubocop2'
end
# good
Gem::Specification.new do |spec|
spec.name = 'rubocop'
end
# good
Gem::Specification.new do |spec|
spec.requirements << 'libmagick, v6.0'
spec.requirements << 'A good graphics card'
end
# good
Gem::Specification.new do |spec|
spec.add_dependency('parallel', '~> 1.10')
spec.add_dependency('parser', '>= 2.3.3.1', '< 3.0')
end
----
[#configurable-attributes-gemspecduplicatedassignment]
=== Configurable attributes
|===
| Name | Default value | Configurable values
| Severity
| `warning`
| String
| Include
| `+**/*.gemspec+`
| Array
|===
[#gemspecordereddependencies]
== Gemspec/OrderedDependencies
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Enabled
| Yes
| Always
| 0.51
| -
|===
Dependencies in the gemspec should be alphabetically sorted.
[#examples-gemspecordereddependencies]
=== Examples
[source,ruby]
----
# bad
spec.add_dependency 'rubocop'
spec.add_dependency 'rspec'
# good
spec.add_dependency 'rspec'
spec.add_dependency 'rubocop'
# good
spec.add_dependency 'rubocop'
spec.add_dependency 'rspec'
# bad
spec.add_development_dependency 'rubocop'
spec.add_development_dependency 'rspec'
# good
spec.add_development_dependency 'rspec'
spec.add_development_dependency 'rubocop'
# good
spec.add_development_dependency 'rubocop'
spec.add_development_dependency 'rspec'
# bad
spec.add_runtime_dependency 'rubocop'
spec.add_runtime_dependency 'rspec'
# good
spec.add_runtime_dependency 'rspec'
spec.add_runtime_dependency 'rubocop'
# good
spec.add_runtime_dependency 'rubocop'
spec.add_runtime_dependency 'rspec'
----
[#treatcommentsasgroupseparators_-true-_default_-gemspecordereddependencies]
==== TreatCommentsAsGroupSeparators: true (default)
[source,ruby]
----
# good
# For code quality
spec.add_dependency 'rubocop'
# For tests
spec.add_dependency 'rspec'
----
[#treatcommentsasgroupseparators_-false-gemspecordereddependencies]
==== TreatCommentsAsGroupSeparators: false
[source,ruby]
----
# bad
# For code quality
spec.add_dependency 'rubocop'
# For tests
spec.add_dependency 'rspec'
----
[#configurable-attributes-gemspecordereddependencies]
=== Configurable attributes
|===
| Name | Default value | Configurable values
| TreatCommentsAsGroupSeparators
| `true`
| Boolean
| ConsiderPunctuation
| `false`
| Boolean
| Include
| `+**/*.gemspec+`
| Array
|===
[#gemspecrequiremfa]
== Gemspec/RequireMFA
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Pending
| Yes
| Always
| 1.23
| 1.40
|===
Requires a gemspec to have `rubygems_mfa_required` metadata set.
This setting tells RubyGems that MFA (Multi-Factor Authentication) is
required for accounts to be able perform privileged operations, such as
(see RubyGems' documentation for the full list of privileged
operations):
* `gem push`
* `gem yank`
* `gem owner --add/remove`
* adding or removing owners using gem ownership page
This helps make your gem more secure, as users can be more
confident that gem updates were pushed by maintainers.
[#examples-gemspecrequiremfa]
=== Examples
[source,ruby]
----
# bad
Gem::Specification.new do |spec|
# no `rubygems_mfa_required` metadata specified
end
# good
Gem::Specification.new do |spec|
spec.metadata = {
'rubygems_mfa_required' => 'true'
}
end
# good
Gem::Specification.new do |spec|
spec.metadata['rubygems_mfa_required'] = 'true'
end
# bad
Gem::Specification.new do |spec|
spec.metadata = {
'rubygems_mfa_required' => 'false'
}
end
# good
Gem::Specification.new do |spec|
spec.metadata = {
'rubygems_mfa_required' => 'true'
}
end
# bad
Gem::Specification.new do |spec|
spec.metadata['rubygems_mfa_required'] = 'false'
end
# good
Gem::Specification.new do |spec|
spec.metadata['rubygems_mfa_required'] = 'true'
end
----
[#configurable-attributes-gemspecrequiremfa]
=== Configurable attributes
|===
| Name | Default value | Configurable values
| Severity
| `warning`
| String
| Include
| `+**/*.gemspec+`
| Array
|===
[#references-gemspecrequiremfa]
=== References
* https://guides.rubygems.org/mfa-requirement-opt-in/
[#gemspecrequiredrubyversion]
== Gemspec/RequiredRubyVersion
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Enabled
| Yes
| No
| 0.52
| 1.40
|===
Checks that `required_ruby_version` in a gemspec file is set to a valid
value (non-blank) and matches `TargetRubyVersion` as set in RuboCop's
configuration for the gem.
This ensures that RuboCop is using the same Ruby version as the gem.
[#examples-gemspecrequiredrubyversion]
=== Examples
[source,ruby]
----
# When `TargetRubyVersion` of .rubocop.yml is `2.5`.
# bad
Gem::Specification.new do |spec|
# no `required_ruby_version` specified
end
# bad
Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 2.4.0'
end
# bad
Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 2.6.0'
end
# bad
Gem::Specification.new do |spec|
spec.required_ruby_version = ''
end
# good
Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 2.5.0'
end
# good
Gem::Specification.new do |spec|
spec.required_ruby_version = '>= 2.5'
end
# accepted but not recommended
Gem::Specification.new do |spec|
spec.required_ruby_version = ['>= 2.5.0', '< 2.7.0']
end
# accepted but not recommended, since
# Ruby does not really follow semantic versioning
Gem::Specification.new do |spec|
spec.required_ruby_version = '~> 2.5'
end
----
[#configurable-attributes-gemspecrequiredrubyversion]
=== Configurable attributes
|===
| Name | Default value | Configurable values
| Severity
| `warning`
| String
| Include
| `+**/*.gemspec+`
| Array
|===
[#gemspecrubyversionglobalsusage]
== Gemspec/RubyVersionGlobalsUsage
|===
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
| Enabled
| Yes
| No
| 0.72
| 1.40
|===
Checks that `RUBY_VERSION` constant is not used in gemspec.
Using `RUBY_VERSION` is dangerous because value of the
constant is determined by `rake release`.
It's possible to have dependency based on ruby version used
to execute `rake release` and not user's ruby version.
[#examples-gemspecrubyversionglobalsusage]
=== Examples
[source,ruby]
----
# bad
Gem::Specification.new do |spec|
if RUBY_VERSION >= '3.0'
spec.add_dependency 'gem_a'
else
spec.add_dependency 'gem_b'
end
end
# good
Gem::Specification.new do |spec|
spec.add_dependency 'gem_a'
end
----
[#configurable-attributes-gemspecrubyversionglobalsusage]
=== Configurable attributes
|===
| Name | Default value | Configurable values
| Severity
| `warning`
| String
| Include
| `+**/*.gemspec+`
| Array
|===
[#references-gemspecrubyversionglobalsusage]
=== References
* https://rubystyle.guide#no-ruby-version-in-the-gemspec