Showing 1,311 of 1,311 total issues
Duplicate branch body detected. Open
when "value exists"
clause, = operands2rubyvalue(operator, op_args, context_type)
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks that there are no repeated bodies
within if/unless
, case-when
, case-in
and rescue
constructs.
With IgnoreLiteralBranches: true
, branches are not registered
as offenses if they return a basic literal value (string, symbol,
integer, float, rational, complex, true
, false
, or nil
), or
return an array, hash, regexp or range that only contains one of
the above basic literal values.
With IgnoreConstantBranches: true
, branches are not registered
as offenses if they return a constant value.
Example:
# bad
if foo
do_foo
do_something_else
elsif bar
do_foo
do_something_else
end
# good
if foo || bar
do_foo
do_something_else
end
# bad
case x
when foo
do_foo
when bar
do_foo
else
do_something_else
end
# good
case x
when foo, bar
do_foo
else
do_something_else
end
# bad
begin
do_something
rescue FooError
handle_error
rescue BarError
handle_error
end
# good
begin
do_something
rescue FooError, BarError
handle_error
end
Example: IgnoreLiteralBranches: true
# good
case size
when "small" then 100
when "medium" then 250
when "large" then 1000
else 250
end
Example: IgnoreConstantBranches: true
# good
case size
when "small" then SMALL_SIZE
when "medium" then MEDIUM_SIZE
when "large" then LARGE_SIZE
else MEDIUM_SIZE
end
Use block explicitly instead of block-passing a method object. Open
component[operator].all?(&method(:valid?))
- Create a ticketCreate a ticket
- Exclude checks
Avoid rescuing the Exception
class. Perhaps you meant to rescue StandardError
? Open
rescue Exception => err
_log.error("'#{err.message}'")
obj = nil
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for rescue
blocks targeting the Exception class.
Example:
# bad
begin
do_something
rescue Exception
handle_exception
end
Example:
# good
begin
do_something
rescue ArgumentError
handle_exception
end
Use ==
if you meant to do a comparison or wrap the expression in parentheses to indicate you meant to assign in a condition. Open
elsif options[:system_uid] && worker = worker_class.find_by(:system_uid => options[:system_uid])
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for assignments in the conditions of if/while/until.
AllowSafeAssignment
option for safe assignment.
By safe assignment we mean putting parentheses around
an assignment to indicate "I know I'm using an assignment
as a condition. It's not a mistake."
Safety:
This cop's autocorrection is unsafe because it assumes that the author meant to use an assignment result as a condition.
Example:
# bad
if some_var = true
do_something
end
# good
if some_var == true
do_something
end
Example: AllowSafeAssignment: true (default)
# good
if (some_var = true)
do_something
end
Example: AllowSafeAssignment: false
# bad
if (some_var = true)
do_something
end
Avoid (in)equality comparisons of floats as they are unreliable. Open
warn "Warning: Remove redundant config.active_support.cache_format_version = 7.0 from #{__FILE__}:#{__LINE__ + 1} if using config.load_defaults 7.0" if config.active_support.cache_format_version == 7.0
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for the presence of precise comparison of floating point numbers.
Floating point values are inherently inaccurate, and comparing them for exact equality
is almost never the desired semantics. Comparison via the ==/!=
operators checks
floating-point value representation to be exactly the same, which is very unlikely
if you perform any arithmetic operations involving precision loss.
Example:
# bad
x == 0.1
x != 0.1
# good - using BigDecimal
x.to_d == 0.1.to_d
# good
(x - 0.1).abs < Float::EPSILON
# good
tolerance = 0.0001
(x - 0.1).abs < tolerance
# Or some other epsilon based type of comparison:
# https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/
Use sum(columns.length * 3)
instead of inject(columns.length * 3) { |s, e| s + e }
. Open
@line_len = @max_col_width.inject(columns.length * 3) { |s, e| s + e }
- Create a ticketCreate a ticket
- Exclude checks
Avoid using or-assignment with constants. Open
INFO ||= "info".freeze
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for unintended or-assignment to a constant.
Constants should always be assigned in the same location. And its value
should always be the same. If constants are assigned in multiple
locations, the result may vary depending on the order of require
.
Safety:
This cop is unsafe because code that is already conditionally assigning a constant may have its behavior changed by autocorrection.
Example:
# bad
CONST ||= 1
# good
CONST = 1
Prefer using YAML.safe_load
over YAML.load
. Open
dialogs = YAML.load(import_file_upload.uploaded_content)
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for the use of YAML class methods which have potential security issues leading to remote code execution when loading from an untrusted source.
NOTE: Ruby 3.1+ (Psych 4) uses Psych.load
as Psych.safe_load
by default.
Safety:
The behavior of the code might change depending on what was
in the YAML payload, since YAML.safe_load
is more restrictive.
Example:
# bad
YAML.load("--- !ruby/object:Foo {}") # Psych 3 is unsafe by default
# good
YAML.safe_load("--- !ruby/object:Foo {}", [Foo]) # Ruby 2.5 (Psych 3)
YAML.safe_load("--- !ruby/object:Foo {}", permitted_classes: [Foo]) # Ruby 3.0- (Psych 3)
YAML.load("--- !ruby/object:Foo {}", permitted_classes: [Foo]) # Ruby 3.1+ (Psych 4)
YAML.dump(foo)
Specify development dependencies in gemspec. Open
gem "ruby-dbus" # For external auth
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
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
.
Example: EnforcedStyle: Gemfile (default)
# 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"
Example: EnforcedStyle: gems.rb
# 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"
Example: EnforcedStyle: gemspec
# 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"
Avoid rescuing the Exception
class. Perhaps you meant to rescue StandardError
? Open
rescue Exception => e
_log.error(e.to_s)
[]
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for rescue
blocks targeting the Exception class.
Example:
# bad
begin
do_something
rescue Exception
handle_exception
end
Example:
# good
begin
do_something
rescue ArgumentError
handle_exception
end
Avoid using or-assignment with constants. Open
ALLOWED_KEYS ||= [
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for unintended or-assignment to a constant.
Constants should always be assigned in the same location. And its value
should always be the same. If constants are assigned in multiple
locations, the result may vary depending on the order of require
.
Safety:
This cop is unsafe because code that is already conditionally assigning a constant may have its behavior changed by autocorrection.
Example:
# bad
CONST ||= 1
# good
CONST = 1
Remove unnecessary existence check File.exist?
. Open
File.unlink(attributes_file) if File.exist?(attributes_file)
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for non-atomic file operation. And then replace it with a nearly equivalent and atomic method.
These can cause problems that are difficult to reproduce, especially in cases of frequent file operations in parallel, such as test runs with parallel_rspec.
For examples: creating a directory if there is none, has the following problems
An exception occurs when the directory didn't exist at the time of exist?
,
but someone else created it before mkdir
was executed.
Subsequent processes are executed without the directory that should be there
when the directory existed at the time of exist?
,
but someone else deleted it shortly afterwards.
Safety:
This cop is unsafe, because autocorrection change to atomic processing. The atomic processing of the replacement destination is not guaranteed to be strictly equivalent to that before the replacement.
Example:
# bad - race condition with another process may result in an error in `mkdir`
unless Dir.exist?(path)
FileUtils.mkdir(path)
end
# good - atomic and idempotent creation
FileUtils.mkdir_p(path)
# bad - race condition with another process may result in an error in `remove`
if File.exist?(path)
FileUtils.remove(path)
end
# good - atomic and idempotent removal
FileUtils.rm_f(path)
Use filter_map
instead. Open
column_names = column_names.collect do |c|
next(c) if includes.include?(c)
c if includes.detect { |incl| c.match(incl) }
end.compact
- Create a ticketCreate a ticket
- Exclude checks
Avoid rescuing the Exception
class. Perhaps you meant to rescue StandardError
? Open
rescue Exception => err
raise err.message
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for rescue
blocks targeting the Exception class.
Example:
# bad
begin
do_something
rescue Exception
handle_exception
end
Example:
# good
begin
do_something
rescue ArgumentError
handle_exception
end
Specify development dependencies in gemspec. Open
gem "rufus-scheduler"
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
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
.
Example: EnforcedStyle: Gemfile (default)
# 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"
Example: EnforcedStyle: gems.rb
# 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"
Example: EnforcedStyle: gemspec
# 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"
Specify development dependencies in gemspec. Open
gem "foreman"
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
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
.
Example: EnforcedStyle: Gemfile (default)
# 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"
Example: EnforcedStyle: gems.rb
# 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"
Example: EnforcedStyle: gemspec
# 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"
Avoid immutable Array literals in loops. It is better to extract it into a local variable or a constant. Open
raise "#{name} must be true or false" unless %w[true false].include?(ENV[name])
- Create a ticketCreate a ticket
- Exclude checks
Remove redundant sort
. Open
Dir.glob("#{@engine_root}/{app,db,lib,config,locale}/**/*.{rb,erb,haml,slim,rhtml,js,jsx}").sort
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Sort globbed results by default in Ruby 3.0.
This cop checks for redundant sort
method to Dir.glob
and Dir[]
.
Safety:
This cop is unsafe, in case of having a file and a directory with
identical names, since directory will be loaded before the file, which
will break exe/files.rb
that rely on exe.rb
file.
Example:
# bad
Dir.glob('./lib/**/*.rb').sort.each do |file|
end
Dir['./lib/**/*.rb'].sort.each do |file|
end
# good
Dir.glob('./lib/**/*.rb').each do |file|
end
Dir['./lib/**/*.rb'].each do |file|
end
Duplicate branch body detected. Open
else
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks that there are no repeated bodies
within if/unless
, case-when
, case-in
and rescue
constructs.
With IgnoreLiteralBranches: true
, branches are not registered
as offenses if they return a basic literal value (string, symbol,
integer, float, rational, complex, true
, false
, or nil
), or
return an array, hash, regexp or range that only contains one of
the above basic literal values.
With IgnoreConstantBranches: true
, branches are not registered
as offenses if they return a constant value.
Example:
# bad
if foo
do_foo
do_something_else
elsif bar
do_foo
do_something_else
end
# good
if foo || bar
do_foo
do_something_else
end
# bad
case x
when foo
do_foo
when bar
do_foo
else
do_something_else
end
# good
case x
when foo, bar
do_foo
else
do_something_else
end
# bad
begin
do_something
rescue FooError
handle_error
rescue BarError
handle_error
end
# good
begin
do_something
rescue FooError, BarError
handle_error
end
Example: IgnoreLiteralBranches: true
# good
case size
when "small" then 100
when "medium" then 250
when "large" then 1000
else 250
end
Example: IgnoreConstantBranches: true
# good
case size
when "small" then SMALL_SIZE
when "medium" then MEDIUM_SIZE
when "large" then LARGE_SIZE
else MEDIUM_SIZE
end
Use filter_map
instead. Open
column_names.collect do |c|
# check for direct match first
next if excludes.include?(c) && !EXCLUDE_EXCEPTIONS.include?(c)
# check for regexp match if no direct match
- Create a ticketCreate a ticket
- Exclude checks