diff --git a/changelog/fix_make_lint_non_deterministic_require_order_aware_of_require_relative.md b/changelog/fix_make_lint_non_deterministic_require_order_aware_of_require_relative.md new file mode 100644 index 00000000000..ed0db0a9d8a --- /dev/null +++ b/changelog/fix_make_lint_non_deterministic_require_order_aware_of_require_relative.md @@ -0,0 +1 @@ +* [#10614](https://github.com/rubocop/rubocop/issues/10614): Make `Lint/NonDeterministicRequireOrder` aware of `require_relative`. ([@koic][]) diff --git a/lib/rubocop/cop/lint/non_deterministic_require_order.rb b/lib/rubocop/cop/lint/non_deterministic_require_order.rb index b3c860dd61e..df9bc2494e3 100644 --- a/lib/rubocop/cop/lint/non_deterministic_require_order.rb +++ b/lib/rubocop/cop/lint/non_deterministic_require_order.rb @@ -143,19 +143,19 @@ def unsorted_dir_pass?(node) # @!method method_require?(node) def_node_matcher :method_require?, <<~PATTERN - (block-pass (send nil? :method (sym :require))) + (block-pass (send nil? :method (sym {:require :require_relative}))) PATTERN # @!method unsorted_dir_glob_pass?(node) def_node_matcher :unsorted_dir_glob_pass?, <<~PATTERN (send (const {nil? cbase} :Dir) :glob ... - (block-pass (send nil? :method (sym :require)))) + (block-pass (send nil? :method (sym {:require :require_relative})))) PATTERN # @!method unsorted_dir_each_pass?(node) def_node_matcher :unsorted_dir_each_pass?, <<~PATTERN (send (send (const {nil? cbase} :Dir) {:[] :glob} ...) :each - (block-pass (send nil? :method (sym :require)))) + (block-pass (send nil? :method (sym {:require :require_relative})))) PATTERN # @!method loop_variable(node) @@ -165,7 +165,7 @@ def unsorted_dir_pass?(node) # @!method var_is_required?(node, name) def_node_search :var_is_required?, <<~PATTERN - (send nil? :require (lvar %1)) + (send nil? {:require :require_relative} (lvar %1)) PATTERN end end diff --git a/spec/rubocop/cop/lint/non_deterministic_require_order_spec.rb b/spec/rubocop/cop/lint/non_deterministic_require_order_spec.rb index 411c20fecd2..2328b8cf13a 100644 --- a/spec/rubocop/cop/lint/non_deterministic_require_order_spec.rb +++ b/spec/rubocop/cop/lint/non_deterministic_require_order_spec.rb @@ -116,7 +116,7 @@ context 'when Ruby 2.7 or lower', :ruby27 do context 'with unsorted index' do - it 'registers an offsense and autocorrects to add .sort' do + it 'registers an offsense and autocorrects to add .sort when the block has `require`' do expect_offense(<<~RUBY) Dir["./lib/**/*.rb"].each do |file| ^^^^^^^^^^^^^^^^^^^^^^^^^ Sort files before requiring them. @@ -131,6 +131,21 @@ RUBY end + it 'registers an offsense and autocorrects to add .sort when the block has `require_relative`' do + expect_offense(<<~RUBY) + Dir["./lib/**/*.rb"].each do |file| + ^^^^^^^^^^^^^^^^^^^^^^^^^ Sort files before requiring them. + require_relative file + end + RUBY + + expect_correction(<<~RUBY) + Dir["./lib/**/*.rb"].sort.each do |file| + require_relative file + end + RUBY + end + it 'registers an offsense with extra logic' do expect_offense(<<~RUBY) Dir["./lib/**/*.rb"].each do |file| @@ -167,6 +182,19 @@ end end + context 'with require_relative block passed as parameter' do + it 'registers an offense an autocorrects to add sort' do + expect_offense(<<~RUBY) + Dir["./lib/**/*.rb"].each(&method(:require_relative)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sort files before requiring them. + RUBY + + expect_correction(<<~RUBY) + Dir["./lib/**/*.rb"].sort.each(&method(:require_relative)) + RUBY + end + end + context 'with top-level ::Dir' do it 'registers an offense and corrects to add .sort' do expect_offense(<<~RUBY) @@ -268,6 +296,26 @@ end end + context 'with require_relative block passed as parameter' do + it 'registers an offense and autocorrects to add sort' do + expect_offense(<<~RUBY) + Dir.glob( + ^^^^^^^^^ Sort files before requiring them. + Rails.root.join('./lib/**/*.rb'), + File::FNM_DOTMATCH, + &method(:require_relative) + ) + RUBY + + expect_correction(<<~RUBY) + Dir.glob( + Rails.root.join('./lib/**/*.rb'), + File::FNM_DOTMATCH + ).sort.each(&method(:require_relative)) + RUBY + end + end + context 'with top-level ::Dir' do it 'registers an offense and corrects to add .sort.each' do expect_offense(<<~RUBY)