An epic release - the one which contains the most new features and
bugfixes since the inception of the project! A huge thanks to the
amazing contributors who helped make it a reality!
Notably, this release adds support for Ruby 2.3 and introduces the
important concept of a target Ruby version - meaning RuboCop will no
longer try to parse the code with a parser matching the interpreter
you're using, but a parser matching the target Ruby version you
specified in .rubocop.yml
. This way you won't introduce accidentally
syntax from a newer Ruby when you want to maintain
compatibility with certain older Rubies.
Enjoy!
New features
- #2598: New cop
Lint/RandOne
checks forrand(1)
,Kernel.rand(1.0)
and similar calls. Such call are most likely a mistake because they always return0
. (@DNNX) - #2590: New cop
Performance/DoubleStartEndWith
checks for twostart_with?
(orend_with?
) calls joined by||
with the same receiver, likestr.start_with?('x') || str.start_with?('y')
and suggests using one call instead:str.start_with?('x', 'y')
. (@DNNX) - #2583: New cop
Performance/TimesMap
checks forx.times.map{}
and suggests replacing them withArray.new(x){}
. (@DNNX) - #2529: Add EnforcedStyle config parameter to IndentArray. (@jawshooah)
- #2479: Add option
AllowHeredoc
toMetrics/LineLength
. (@fphilipe) - #2416: New cop
Style/ConditionalAssignment
checks for assignment of the same variable in all branches of conditionals and replaces them with a single assignment to the return of the conditional. (@rrosenblum) - #2410: New cop
Style/IndentAssignment
checks the indentation of the first line of the right-hand-side of a multi-line assignment. (@panthomakos) - #2431: Add
IgnoreExecutableScripts
option toStyle/FileName
. (@sometimesfood) - #2460: New cop
Style/UnneededInterpolation
checks for strings that are just an interpolated expression. (@cgriego) - #2361:
Style/MultilineAssignmentLayout
cop checks for a newline after the assignment operator in a multi-line assignment. (@panthomakos) - #2462:
Lint/UselessAccessModifier
can catch more types of useless access modifiers. (@alexdowad) - #1677: Add new
Performance/Casecmp
cop. (@alexdowad) - #1677: Add new
Performance/RangeInclude
cop. (@alexdowad) - #1677: Add new
Performance/RedundantSortBy
cop. (@alexdowad) - #1677: Add new
Performance/LstripRstrip
cop. (@alexdowad) - #1677: Add new
Performance/StartWith
cop. (@alexdowad) - #1677: Add new
Performance/EndWith
cop. (@alexdowad) - #1677: Add new
Performance/RedundantMerge
cop. (@alexdowad) Lint/Debugger
cop can now auto-correct offenses. (@alexdowad)- #1677: Add new
Performance/RedundantMatch
cop. (@alexdowad) - #1677: Add new
Performance/RedundantBlockCall
cop. (@alexdowad) - #1954:
Lint/UnneededDisable
can now autocorrect. (@alexdowad) - #2501: Add new
Lint/ImplicitStringConcatenation
cop. (@alexdowad) - Add new
Style/RedundantParentheses
cop. (@lumeet) - #1346:
Style/SpecialGlobalVars
can be configured to use eitheruse_english_names
oruse_perl_names
styles. (@alexdowad) - #2426: New
Style/NestedParenthesizedCalls
cop checks for non-parenthesized method calls nested inside a parenthesized call, likemethod1(method2 arg)
. (@alexdowad) - #2502: The
--stdin
and--auto-correct
CLI options can be combined, and if you do so, corrected code is printed to stdout. (@alexdowad) Style/ConditionalAssignment
works on conditionals with a common aref assignment (likearray[index] = val
) or attribute assignment (likeself.attribute = val
). (@alexdowad)- #2476:
Style/GuardClause
catches if..else nodes with one branch which terminates the execution of the current scope. (@alexdowad) - New
Style/IdenticalConditionalBranches
flagsif..else
andcase..when..else
constructs with an identical line at the end of each branch. (@alexdowad) - #207: Add new
Lint/FloatOutOfRange
cop which catches floating-point literals which are too large or too small for Ruby to represent. (@alexdowad) Style/GuardClause
doesn't report offenses in places where correction would make a line too long. (@alexdowad)Lint/DuplicateMethods
can find duplicate method definitions in many more circumstances, even across multiple files; however, it ignores definitions insideif
or something which could be a DSL method. (@alexdowad)- A warning is printed if an invalid
EnforcedStyle
is configured. (@alexdowad) - #1367: New
Lint/IneffectiveAccessModifier
checks for access modifiers which are erroneously applied to a singleton method, where they have no effect. (@alexdowad) - #1614:
Lint/BlockAlignment
aligns block end with splat operator when applied to a splatted method call. (@alexdowad) - #2263: Warn if
task.options = %w(--format ...)
is used when configuringRuboCop::RakeTask
; this should betask.formatters = ...
instead. (@alexdowad) - #2511:
--no-offense-counts
CLI option suppresses the inclusion of offense count lines in auto-generated config. (@alexdowad) - #2504: New
AllowForAlignment
config parameter forStyle/SingleSpaceBeforeFirstArg
allows the insertion of extra spaces before the first argument if it aligns it with something on the preceding or following line. (@alexdowad) - #2478:
Style/ExtraSpacing
has newForceEqualSignAlignment
config parameter which forces = signs on consecutive lines to be aligned, and it can auto-correct. (@alexdowad) Lint/BlockAlignment
aligns block end with unary operators like ~, -, or ! when such operators are applied to the method call taking the block. (@alexdowad)- #1460:
Style/Alias
supports bothprefer_alias
andprefer_alias_method
styles. (@alexdowad) - #1569: New
ExpectMatchingDefinition
config parameter forStyle/FileName
makes it check for a class or module definition in each file which corresponds to the file name and path. (@alexdowad) - #2480: Add a configuration to
Style/ConditionalAssignment
to check and correct conditionals that contain multiple assignments. (@rrosenblum) - #2480: Allow
Style/ConditionalAssignment
to correct assignment in ternary operations. (@rrosenblum) - #2480: Allow
Style/ConditionalAssignment
to correct comparable methods. (@rrosenblum) - #1633: New cop
Style/MultilineMethodCallIndentation
takes over the responsibility for checking alignment of methods from theStyle/MultilineOperationIndentation
cop. (@jonas054) - #2472: New cop
Style/MultilineArrayBraceLayout
checks that the closing brace in an array literal is symmetrical with respect to the opening brace and the array elements. (@panthomakos) - #1543:
Style/WordArray
has bothpercent
andbrackets
(which enforces the use of bracketed arrays for strings) styles. (@alexdowad) Style/SpaceAroundOperators
hasAllowForAlignment
config parameter which allows extra spaces on the left if they serve to align the operator with another. (@alexdowad)Style/SymbolArray
has bothpercent
andbrackets
(which enforces the user of bracketed arrays for symbols) styles. (@alexdowad)- #2343: Entire cop types (or "departments") can be disabled using in .rubocop.yml using config like
Style: Enabled: false
. (@alexdowad) - #2399: New
start_of_line
style forLint/EndAlignment
aligns a closingend
keyword with the start of the line where the opening keyword appears. (@alexdowad) - #1545: New
Regex
config parameter forStyle/FileName
allows user to provide their own regex for validating file names. (@alexdowad) - #2253: New
DefaultFormatter
config parameter can be used to set formatter from within .rubocop.yml. (@alexdowad) - #2481: New
WorstOffendersFormatter
prints a list of files with offenses (and offense counts), showing the files with the most offenses first. (@alexdowad) - New
IfInsideElse
cop catchesif..end
nodes which can be converted into anelsif
instead, reducing the nesting level. (@alexdowad) - #1725: --color CLI option forces color output, even when not printing to a TTY. (@alexdowad)
- #2549: New
ConsistentQuotesInMultiline
config param forStyle/StringLiterals
forces all literals which are concatenated using \ to use the same quote style. (@alexdowad) - #2560:
Style/AccessModifierIndentation
,Style/CaseIndentation
,Style/FirstParameterIndentation
,Style/IndentArray
,Style/IndentAssignment
,Style/IndentHash
,Style/MultilineMethodCallIndentation
, andStyle/MultilineOperationIndentation
all have a newIndentationWidth
parameter which can be used to override the indentation width fromStyle/IndentationWidth
. (@alexdowad) - Add new
Performance/HashEachMethods
cop. (@ojab) - New cop
Style/FrozenStringLiteralComment
will check for and add the comment# frozen_string_literal: true
to the top of files. This will help with upgrading to Ruby 3.0. (@rrosenblum)
Bug Fixes
- #2594:
Style/EmptyLiteral
autocorrector respectsStyle/StringLiterals:EnforcedStyle
config. (@DNNX) - #2411: Make local inherited configuration override configuration loaded from gems. (@jonas054)
- #2413: Allow
%Q
for dynamic strings with double quotes inside them. (@jonas054) - #2404:
Style/Next
does not remove comments when auto-correcting. (@lumeet) Style/Next
handles auto-correction of nested offenses. (@lumeet)Style/VariableInterpolation
now detects non-numeric regex back references. (@cgriego)ProgressFormatter
fully respects the--no-color
switch. (@savef)- Replace
Time.zone.current
withTime.current
onRails::TimeZone
cop message. (@volmer) - #2451:
Style/StabbyLambdaParentheses
does not treat method calls namedlambda
as lambdas. (@domcleal) - #2463: Allow comments before an access modifier. (@codebeige)
- #2471:
Style/MethodName
doesn't choke on methods which are defined inside methods. (@alexdowad) - #2449:
Style/StabbyLambdaParentheses
only checks lambdas in the arrow form. (@lumeet) - #2456:
Lint/NestedMethodDefinition
doesn't register offenses for method definitions inside an eval block (eitherinstance_eval
,class_eval
, ormodule_eval
). (@alexdowad) - #2464:
Style/ParallelAssignment
understands aref and attribute assignments, and doesn't warn if they can't be correctly rearranged into a series of single assignments. (@alexdowad) - #2482:
Style/AndOr
doesn't raise an exception when trying to autocorrect!variable or ...
. (@alexdowad) - #2446:
Style/Tab
doesn't register errors for leading tabs which occur inside a string literal (including heredoc). (@alexdowad) - #2452:
Style/TrailingComma
incorrectly categorizes single-line hashes in methods calls. (@panthomakos) - #2441:
Style/AlignParameters
doesn't crash if it finds nested offenses. (@alexdowad) - #2436:
Style/SpaceInsideHashLiteralBraces
doesn't mangle a hash literal which is not surrounded by curly braces, but has another hash literal which does as its first key. (@alexdowad) - #2483:
Style/Attr
differentiate between attr_accessor and attr_reader. (@weh) Style/ConditionalAssignment
doesn't crash if it finds acase
with an empty branch. (@lumeet)- #2506:
Lint/FormatParameterMismatch
understands %{} and %<> interpolations. (@alexdowad) - #2145:
Lint/ParenthesesAsGroupedExpression
ignores calls with multiple arguments, since they are not ambiguous. (@alexdowad) - #2484: Remove two vulnerabilities in cache handling. (@jonas054)
- #2517:
Lint/UselessAccessModifier
doesn't think that an access modifier applied toattr_writer
is useless. (@alexdowad) - #2518:
Style/ConditionalAssignment
doesn't think that branches using<<
and[]=
should be combined. (@alexdowad) CharacterLiteral
auto-corrector now properly corrects?'
. (@bfontaine)- #2313:
Rails/FindEach
doesn't break code which usesorder(...).each
,limit(...).each
, and so on. (@alexdowad) - #1938:
Rails/FindBy
doesn't autocorrectwhere(...).first
tofind_by
, since the returned record is often different. (@alexdowad) - #1801:
EmacsFormatter
strips newlines out of error messages, if there are any. (@alexdowad) - #2534:
Style/RescueEnsureAlignment
works onrescue
nested inside aclass
ormodule
block. (@alexdowad) Lint/BlockAlignment
does not refer to a block terminator asend
when it is actually}
. (@alexdowad)- #2540:
Lint/FormatParameterMismatch
understands format specifiers with multiple flags. (@alexdowad) - #2538:
Style/SpaceAroundOperators
doesn't eat newlines. (@alexdowad) - #2531:
Style/AndOr
autocorrects in cases where parentheses must be added, even inside a nested begin node. (@alexdowad) - #2450:
Style/Next
adjusts indentation when auto-correcting, to avoid introducing new offenses. (@alexdowad) - #2066:
Style/TrivialAccessors
doesn't flag what appear to be trivial accessor method definitions, if they are nested inside a call toinstance_eval
. (@alexdowad) Style/SymbolArray
doesn't flag arrays of symbols if a symbol contains a space character. (@alexdowad)Style/SymbolArray
can auto-correct offenses. (@alexdowad)- #2546: Report when two
rubocop:disable
comments (not the single line kind) for a given cop apppear in a file with norubocop:enable
in between. (@jonas054) - #2552:
Style/Encoding
can auto-correct files with a blank first line. (@alexdowad) - #2556:
Style/SpecialGlobalVariables
generates auto-config correctly. (@alexdowad) - #2565: Let
Style/SpaceAroundOperators
leave spacing around=>
toStyle/AlignHash
. (@jonas054) - #2569:
Style/MethodCallParentheses
doesn't register warnings forobject.()
syntax, since it is handled byStyle/LambdaCall
. (@alexdowad) - #2570:
Performance/RedundantMerge
doesn't break code with a modifierif
when autocorrecting. (@alexdowad) Performance/RedundantMerge
doesn't break code with a modifierwhile
oruntil
when autocorrecting. (@alexdowad)- #2574:
variable
style forLint/EndAlignment
is working again. (@alexdowad) Lint/EndAlignment
can autocorrect offenses on the RHS of an assignment to an instance variable, class variable, constant, and so on; previously, it only worked if the LHS was a local variable. (@alexdowad)- #2580:
Style/StringReplacement
doesn't break code when autocorrection involves a regex with embedded escapes (like /\n/). (@alexdowad) - #2582:
Style/AlignHash
doesn't move a key so far left that it goes onto the previous line (in an attempt to align). (@alexdowad) - #2588:
Style/SymbolProc
doesn't break code when autocorrecting a method call with a trailing comma in the argument list. (@alexdowad) - #2448:
Style/TrailingCommaInArguments
andStyle/TrailingCommaInLiteral
don't special-case single-item lists in a way which contradicts the documentation. (@alexdowad) - Fix for remote config files to only load from on http and https URLs. (@ptrippett)
- #2604:
Style/FileName
doesn't fail on empty files whenExpectMatchingDefinition
is true. (@alexdowad) Style/RedundantFreeze
registers offences for frozen dynamic symbols. (@segiddins)- #2609: All cops which rely on the
AutocorrectUnlessChangingAST
module can now autocorrect files which contain__FILE__
. (@alexdowad) - #2608:
Style/ConditionalAssignment
can autocorrect=~
within a ternary expression. (@alexdowad)
Changes
- #2427: Allow non-snake-case file names (e.g.
some-random-script
) for Ruby scripts that have a shebang. (@sometimesfood) - #2430:
Lint/UnneededDisable
now adds "unknown cop" to messages if cop names inrubocop:disable
comments are unrecognized, or "did you mean ..." if they are misspelled names of existing cops. (@jonas054) - #947:
Style/Documentation
considers classes and modules which only define constants to be "namespaces", and doesn't flag them for lack of a documentation comment. (@alexdowad) - #2467: Explicitly inheriting configuration from the rubocop gem in .rubocop.yml is not allowed. (@alexdowad)
- #2322: Output of --auto-gen-config shows content of default config parameters which are Arrays; this is especially useful for SupportedStyles. (@alexdowad)
- #1566: When autocorrecting on Windows, line endings are not converted to "\r\n" in untouched portions of the source files; corrected portions may use "\n" rather than "\r\n". (@alexdowad)
- New
rake repl
task can be used for experimentation when working on RuboCop. (@alexdowad) Lint/SpaceBeforeFirstArg
cop has been removed, since it just duplicatesStyle/SingleSpaceBeforeFirstArg
. (@alexdowad)Style/SingleSpaceBeforeFirstArg
cop has been renamed toStyle/SpaceBeforeFirstArg
, which more accurately reflects what it now does. (@alexdowad)Style/UnneededPercentQ
reports%q()
strings with what only appears to be an escape, but is not really (there are no escapes in%q()
strings). (@alexdowad)Performance/StringReplacement
,Performance\StartWith
, andPerformance\EndWith
more accurately identify code which can be improved. (@alexdowad)- The
MultiSpaceAllowedForOperators
config parameter forStyle/SpaceAroundOperators
has been removed, as it is made redundant byAllowForAlignment
. If someone attempts to use it, config validation will fail with a helpful message. (@alexdowad) - The
RunRailsCops
config parameter in .rubocop.yml is now obsolete. If someone attempts to use it, config validation will fail with a helpful message. (@alexdowad) - If .rubocop.yml contains configuration for a custom cop, no warning regarding "unknown cop" will be printed. The custom cop must inherit from RuboCop::Cop::Cop, and must be loaded into memory for this to work. (@alexdowad)
- #2102: If .rubocop.yml exists in the working directory when running --auto-gen-config, any
Exclude
config parameters in .rubocop.yml will be merged into the generated .rubocop_todo.yml. (@alexdowad) - #1895: Remove
Rails/DefaultScope
cop. (@alexdowad) - #2550: New
TargetRubyVersion
configuration parameter can be used to specify which version of the Ruby interpreter the inspected code is intended to run on. (@alexdowad) - #2557:
Style/GuardClause
does not warn aboutif
nodes whose condition spans multiple lines. (@alexdowad) Style/EmptyLinesAroundClassBody
,Style/EmptyLinesAroundModuleBody
, andStyle/EmptyLinesAroundBlockBody
accept an empty body with no blank line, even if configured toempty_lines
style. This is because the empty lines only serve to provide a break between the header, body, and footer, and are redundant if there is no body. (@alexdowad)- #2554:
Style/FirstMethodArgumentLineBreak
handles implicit hash arguments without braces;Style/FirstHashElementLineBreak
still handles those with braces. (@alexdowad) Style/TrailingComma
has been split intoStyle/TrailingCommaInArguments
andStyle/TrailingCommaInLiteral
. (@alexdowad)- RuboCop returns process exit code 2 if it fails due to bad configuration, bad CLI options, or an internal error. If it runs successfully but finds one or more offenses, it still exits with code 1, as was previously the case. This is helpful when invoking RuboCop programmatically, perhaps from a script. (@alexdowad)