Skip to content

Commit

Permalink
Merge branch 'rubocop:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
thearjunmdas committed Jul 20, 2021
2 parents e76e566 + 4874caa commit a68088a
Show file tree
Hide file tree
Showing 36 changed files with 223 additions and 68 deletions.
4 changes: 4 additions & 0 deletions .rubocop.yml
Expand Up @@ -99,6 +99,10 @@ Metrics/ModuleLength:
- 'spec/**/*.rb'

Naming/InclusiveLanguage:
FlaggedTerms:
offence:
Suggestions:
- offense
Exclude:
- lib/rubocop/cop/naming/inclusive_language.rb

Expand Down
@@ -0,0 +1 @@
* [#9922](https://github.com/rubocop/rubocop/issues/9922): Make better auto-corrections in `Style/DoubleCopDisableDirective`. ([@jonas054][])
1 change: 1 addition & 0 deletions changelog/fix_error_message_for_dept.md
@@ -0,0 +1 @@
* [#9752](https://github.com/rubocop/rubocop/issues/9752): Improve error message for top level department used in configuration. ([@jonas054][])
@@ -0,0 +1 @@
* [#9928](https://github.com/rubocop/rubocop/issues/9928): Fix an infinite loop error and a false auto-correction behavior for `Layout/EndAlignment` when using operator methods and `EnforcedStyleAlignWith: variable`. ([@koic][])
1 change: 1 addition & 0 deletions changelog/fix_github_actions_in_non_default_directory.md
@@ -0,0 +1 @@
* [#9933](https://github.com/rubocop/rubocop/pull/9933): Fix GitHub Actions formatter when running in non-default directory. ([@ojab][])
@@ -0,0 +1 @@
* [#9938](https://github.com/rubocop/rubocop/pull/9938): Fix an incorrect auto-correct for `Layout/LineLength` when a heredoc is used as the first element of an array. ([@koic][])
@@ -0,0 +1 @@
* [#9940](https://github.com/rubocop/rubocop/issues/9940): Fix an incorrect auto-correct for `Style/HashTransformValues` when value is a hash literal for `_.to_h{...}`. ([@koic][])
@@ -0,0 +1 @@
* [#9930](https://github.com/rubocop/rubocop/pull/9930): Support Ruby 2.7's pattern matching for `Lint/DuplicateBranch` cop. ([@koic][])
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/cops_style.adoc
Expand Up @@ -3330,7 +3330,7 @@ will not attempt to automatically add a binding, or add filename and
line values.

This cop works only when a string literal is given as a code string.
No offence is reported if a string variable is given as below:
No offense is reported if a string variable is given as below:

=== Examples

Expand Down
23 changes: 18 additions & 5 deletions lib/rubocop/config_validator.rb
Expand Up @@ -104,19 +104,32 @@ def alert_about_unrecognized_cops(invalid_cop_names)
# to do so than to pass the value around to various methods.
next if name == 'inherit_mode'

suggestions = NameSimilarity.find_similar_names(name, Cop::Registry.global.map(&:cop_name))
suggestion = "Did you mean `#{suggestions.join('`, `')}`?" if suggestions.any?

message = <<~MESSAGE.rstrip
unrecognized cop #{name} found in #{smart_loaded_path}
#{suggestion}
unrecognized cop or department #{name} found in #{smart_loaded_path}
#{suggestion(name)}
MESSAGE

unknown_cops << message
end
raise ValidationError, unknown_cops.join("\n") if unknown_cops.any?
end

def suggestion(name)
registry = Cop::Registry.global
departments = registry.departments.map(&:to_s)
suggestions = NameSimilarity.find_similar_names(name, departments + registry.map(&:cop_name))
if suggestions.any?
"Did you mean `#{suggestions.join('`, `')}`?"
else
# Department names can contain slashes, e.g. Chef/Correctness, but there's no support for
# the concept of higher level departments in RuboCop. It's a flat structure. So if the user
# tries to configure a "top level department", we hint that it's the bottom level
# departments that should be configured.
suggestions = departments.select { |department| department.start_with?("#{name}/") }
"#{name} is not a department. Use `#{suggestions.join('`, `')}`." if suggestions.any?
end
end

def validate_syntax_cop
syntax_config = @config['Lint/Syntax']
default_config = ConfigLoader.default_configuration['Lint/Syntax']
Expand Down
9 changes: 8 additions & 1 deletion lib/rubocop/cop/layout/end_alignment.rb
Expand Up @@ -167,7 +167,8 @@ def alignment_node(node)
def alignment_node_for_variable_style(node)
return node.parent if node.case_type? && node.argument?

assignment = node.ancestors.find(&:assignment_or_similar?)
assignment = assignment_or_operator_method(node)

if assignment && !line_break_before_keyword?(assignment.source_range, node)
assignment
else
Expand All @@ -177,6 +178,12 @@ def alignment_node_for_variable_style(node)
node
end
end

def assignment_or_operator_method(node)
node.ancestors.find do |ancestor|
ancestor.assignment_or_similar? || ancestor.send_type? && ancestor.operator_method?
end
end
end
end
end
Expand Down
30 changes: 15 additions & 15 deletions lib/rubocop/cop/layout/hash_alignment.rb
Expand Up @@ -213,7 +213,7 @@ def on_hash(node)
check_pairs(node)
end

attr_accessor :offences_by, :column_deltas
attr_accessor :offenses_by, :column_deltas

private

Expand All @@ -224,7 +224,7 @@ def autocorrect_incompatible_with_other_cops?(node)
end

def reset!
self.offences_by = {}
self.offenses_by = {}
self.column_deltas = Hash.new { |hash, key| hash[key] = {} }
end

Expand All @@ -248,33 +248,33 @@ def check_pairs(node)
end
end

add_offences
add_offenses
end

def add_offences
kwsplat_offences = offences_by.delete(KeywordSplatAlignment)
register_offences_with_format(kwsplat_offences, KeywordSplatAlignment)
def add_offenses
kwsplat_offenses = offenses_by.delete(KeywordSplatAlignment)
register_offenses_with_format(kwsplat_offenses, KeywordSplatAlignment)

format, offences = offences_by.min_by { |_, v| v.length }
register_offences_with_format(offences, format)
format, offenses = offenses_by.min_by { |_, v| v.length }
register_offenses_with_format(offenses, format)
end

def register_offences_with_format(offences, format)
(offences || []).each do |offence|
add_offense(offence, message: MESSAGES[format]) do |corrector|
delta = column_deltas[alignment_for(offence).first.class][offence]
def register_offenses_with_format(offenses, format)
(offenses || []).each do |offense|
add_offense(offense, message: MESSAGES[format]) do |corrector|
delta = column_deltas[alignment_for(offense).first.class][offense]

correct_node(corrector, offence, delta) unless delta.nil?
correct_node(corrector, offense, delta) unless delta.nil?
end
end
end

def check_delta(delta, node:, alignment:)
offences_by[alignment.class] ||= []
offenses_by[alignment.class] ||= []
return if good_alignment? delta

column_deltas[alignment.class][node] = delta
offences_by[alignment.class].push(node)
offenses_by[alignment.class].push(node)
end

def ignore_hash_argument?(node)
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/layout/indentation_style.rb
Expand Up @@ -43,7 +43,7 @@ def on_new_investigation
str_ranges = string_literal_ranges(processed_source.ast)

processed_source.lines.each.with_index(1) do |line, lineno|
next unless (range = find_offence(line, lineno))
next unless (range = find_offense(line, lineno))
next if in_string_literal?(str_ranges, range)

add_offense(range) { |corrector| autocorrect(corrector, range) }
Expand All @@ -60,7 +60,7 @@ def autocorrect(corrector, range)
end
end

def find_offence(line, lineno)
def find_offense(line, lineno)
match = if style == :spaces
line.match(/\A\s*\t+/)
else
Expand Down
3 changes: 2 additions & 1 deletion lib/rubocop/cop/lint/duplicate_branch.rb
Expand Up @@ -4,7 +4,7 @@ module RuboCop
module Cop
module Lint
# This cop checks that there are no repeated bodies
# within `if/unless`, `case-when` and `rescue` constructs.
# 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,
Expand Down Expand Up @@ -97,6 +97,7 @@ def on_branching_statement(node)
end
alias on_if on_branching_statement
alias on_case on_branching_statement
alias on_case_match on_branching_statement
alias on_rescue on_branching_statement

private
Expand Down
4 changes: 2 additions & 2 deletions lib/rubocop/cop/mixin/check_line_breakable.rb
Expand Up @@ -97,9 +97,9 @@ def first_argument_is_heredoc?(node)
# If a send node contains a heredoc argument, splitting cannot happen
# after the heredoc or else it will cause a syntax error.
def shift_elements_for_heredoc_arg(node, elements, index)
return index unless node.send_type?
return index unless node.send_type? || node.array_type?

heredoc_index = elements.index { |arg| (arg.str_type? || arg.dstr_type?) && arg.heredoc? }
heredoc_index = elements.index { |arg| arg.respond_to?(:heredoc?) && arg.heredoc? }
return index unless heredoc_index
return nil if heredoc_index.zero?

Expand Down
7 changes: 6 additions & 1 deletion lib/rubocop/cop/mixin/hash_transform_method.rb
Expand Up @@ -175,7 +175,12 @@ def set_new_arg_name(transformed_argname, corrector)
end

def set_new_body_expression(transforming_body_expr, corrector)
corrector.replace(block_node.body, transforming_body_expr.loc.expression.source)
body_source = transforming_body_expr.loc.expression.source
if transforming_body_expr.hash_type? && !transforming_body_expr.braces?
body_source = "{ #{body_source} }"
end

corrector.replace(block_node.body, body_source)
end
end
end
Expand Down
8 changes: 1 addition & 7 deletions lib/rubocop/cop/style/double_cop_disable_directive.rb
Expand Up @@ -36,13 +36,7 @@ def on_new_investigation
next unless comment.text.scan(/# rubocop:(?:disable|todo)/).size > 1

add_offense(comment) do |corrector|
prefix = if comment.text.start_with?('# rubocop:disable')
'# rubocop:disable'
else
'# rubocop:todo'
end

corrector.replace(comment, comment.text[/#{prefix} \S+/])
corrector.replace(comment, comment.text.gsub(%r{ # rubocop:(disable|todo)}, ','))
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/cop/style/eval_with_location.rb
Expand Up @@ -43,7 +43,7 @@ module Style
# RUBY
#
# This cop works only when a string literal is given as a code string.
# No offence is reported if a string variable is given as below:
# No offense is reported if a string variable is given as below:
#
# @example
# # not checked
Expand Down
2 changes: 1 addition & 1 deletion lib/rubocop/formatter/git_hub_actions_formatter.rb
Expand Up @@ -33,7 +33,7 @@ def report_offense(file, offense)
output.printf(
"\n::%<severity>s file=%<file>s,line=%<line>d,col=%<column>d::%<message>s\n",
severity: github_severity(offense),
file: file,
file: PathUtil.smart_path(file),
line: offense.line,
column: offense.real_column,
message: github_escape(offense.message)
Expand Down
2 changes: 1 addition & 1 deletion rubocop.gemspec
Expand Up @@ -35,7 +35,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency('rainbow', '>= 2.2.2', '< 4.0')
s.add_runtime_dependency('regexp_parser', '>= 1.8', '< 3.0')
s.add_runtime_dependency('rexml')
s.add_runtime_dependency('rubocop-ast', '>= 1.7.0', '< 2.0')
s.add_runtime_dependency('rubocop-ast', '>= 1.8.0', '< 2.0')
s.add_runtime_dependency('ruby-progressbar', '~> 1.7')
s.add_runtime_dependency('unicode-display_width', '>= 1.4.0', '< 3.0')

Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cli/disable_uncorrectable_spec.rb
Expand Up @@ -177,7 +177,7 @@ def choose_move(who_to_move)
class Chess
# rubocop:todo Metrics/MethodLength
# rubocop:todo Metrics/AbcSize
def choose_move(who_to_move) # rubocop:todo Metrics/CyclomaticComplexity
def choose_move(who_to_move) # rubocop:todo Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/MethodLength
legal_moves = all_legal_moves_that_dont_put_me_in_check(who_to_move)
return nil if legal_moves.empty?
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/cli/options_spec.rb
Expand Up @@ -1806,7 +1806,7 @@ def f
$stdin = STDIN
end

it 'prints offence reports to stderr and corrected code to stdout if --auto-correct-all and --stderr are used' do
it 'prints offense reports to stderr and corrected code to stdout if --auto-correct-all and --stderr are used' do
$stdin = StringIO.new('p $/')
argv = ['--auto-correct-all',
'--only=Style/SpecialGlobalVars',
Expand Down
12 changes: 8 additions & 4 deletions spec/rubocop/cli_spec.rb
Expand Up @@ -1380,6 +1380,8 @@ def meow_at_4am?
Layout/LyneLenth:
Enabled: true
Max: 100
Linth:
Enabled: false
Lint/LiteralInCondition:
Enabled: true
Style/AlignHash:
Expand All @@ -1389,11 +1391,13 @@ def meow_at_4am?
expect(cli.run(%w[--format simple example])).to eq(2)
expect($stderr.string)
.to eq(<<~OUTPUT)
Error: unrecognized cop Layout/LyneLenth found in example/.rubocop.yml
Error: unrecognized cop or department Layout/LyneLenth found in example/.rubocop.yml
Did you mean `Layout/LineLength`?
unrecognized cop Lint/LiteralInCondition found in example/.rubocop.yml
unrecognized cop or department Linth found in example/.rubocop.yml
Did you mean `Lint`?
unrecognized cop or department Lint/LiteralInCondition found in example/.rubocop.yml
Did you mean `Lint/LiteralAsCondition`?
unrecognized cop Style/AlignHash found in example/.rubocop.yml
unrecognized cop or department Style/AlignHash found in example/.rubocop.yml
Did you mean `Style/Alias`, `Style/OptionHash`?
OUTPUT
end
Expand Down Expand Up @@ -1688,7 +1692,7 @@ def method(foo, bar, qux, fred, arg5, f) end #{'#' * 85}
YAML
expect(cli.run(['example1.rb'])).to eq(2)
expect($stderr.string.strip).to eq(
'Error: unrecognized cop Syntax/Whatever found in .rubocop.yml'
'Error: unrecognized cop or department Syntax/Whatever found in .rubocop.yml'
)
end
end
Expand Down
23 changes: 17 additions & 6 deletions spec/rubocop/config_loader_spec.rb
Expand Up @@ -540,11 +540,12 @@
context 'when a department is disabled', :restore_registry do
let(:file_path) { '.rubocop.yml' }

shared_examples 'resolves enabled/disabled for all cops' do |enabled_by_default, disabled_by_default|
shared_examples 'resolves enabled/disabled for all ' \
'cops' do |enabled_by_default, disabled_by_default, custom_dept_to_disable|
before { stub_cop_class('RuboCop::Cop::Foo::Bar::Baz') }

it "handles EnabledByDefault: #{enabled_by_default}, " \
"DisabledByDefault: #{disabled_by_default}" do
"DisabledByDefault: #{disabled_by_default} with disabled #{custom_dept_to_disable}" do
create_file('grandparent_rubocop.yml', <<~YAML)
Naming/FileName:
Enabled: pending
Expand Down Expand Up @@ -573,7 +574,7 @@
Naming:
Enabled: false
Foo/Bar:
#{custom_dept_to_disable}:
Enabled: false
YAML
create_file(file_path, <<~YAML)
Expand Down Expand Up @@ -603,6 +604,15 @@ def enabled?(cop)
configuration_from_file.for_cop(cop)['Enabled']
end

if custom_dept_to_disable == 'Foo'
message = <<~'OUTPUT'.chomp
unrecognized cop or department Foo found in parent_rubocop.yml
Foo is not a department. Use `Foo/Bar`.
OUTPUT
expect { enabled?('Foo/Bar/Baz') }.to raise_error(RuboCop::ValidationError, message)
next
end

# Department disabled in parent config, cop enabled in child.
expect(enabled?('Metrics/MethodLength')).to be(true)

Expand Down Expand Up @@ -641,9 +651,10 @@ def enabled?(cop)
end
end

include_examples 'resolves enabled/disabled for all cops', false, false
include_examples 'resolves enabled/disabled for all cops', false, true
include_examples 'resolves enabled/disabled for all cops', true, false
include_examples 'resolves enabled/disabled for all cops', false, false, 'Foo/Bar'
include_examples 'resolves enabled/disabled for all cops', false, true, 'Foo/Bar'
include_examples 'resolves enabled/disabled for all cops', true, false, 'Foo/Bar'
include_examples 'resolves enabled/disabled for all cops', false, false, 'Foo'
end

context 'when a third party require defines a new gem', :restore_registry do
Expand Down
2 changes: 1 addition & 1 deletion spec/rubocop/config_spec.rb
Expand Up @@ -31,7 +31,7 @@
it 'raises an validation error' do
expect { configuration }.to raise_error(
RuboCop::ValidationError,
'unrecognized cop LyneLenth found in .rubocop.yml'
'unrecognized cop or department LyneLenth found in .rubocop.yml'
)
end
end
Expand Down

0 comments on commit a68088a

Please sign in to comment.