From 1b2efe5a111941d57edbaf2be7f3a94eb02b5f9d Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Tue, 23 Apr 2019 00:36:14 +0200 Subject: [PATCH] upgrades Zeitwerk to 2.1.4 This commit more or less undoes 9b5401f, restores autoloaded? not to touch the descendants tracker, and autoloaded_constants because it is documented in the guide. --- Gemfile.lock | 4 +- activesupport/activesupport.gemspec | 2 +- .../dependencies/zeitwerk_integration.rb | 9 ++- .../lib/active_support/descendants_tracker.rb | 11 +-- .../application/zeitwerk_integration_test.rb | 72 ++++++------------- 5 files changed, 33 insertions(+), 65 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 784774577e..4e80d5a36f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -71,7 +71,7 @@ PATH i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - zeitwerk (~> 2.1, >= 2.1.2) + zeitwerk (~> 2.1, >= 2.1.4) rails (6.0.0.beta3) actioncable (= 6.0.0.beta3) actionmailbox (= 6.0.0.beta3) @@ -528,7 +528,7 @@ GEM websocket-extensions (0.1.3) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.1.2) + zeitwerk (2.1.4) PLATFORMS java diff --git a/activesupport/activesupport.gemspec b/activesupport/activesupport.gemspec index dd2340cdd3..7ecbafc911 100644 --- a/activesupport/activesupport.gemspec +++ b/activesupport/activesupport.gemspec @@ -34,5 +34,5 @@ Gem::Specification.new do |s| s.add_dependency "tzinfo", "~> 1.1" s.add_dependency "minitest", "~> 5.1" s.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2" - s.add_dependency "zeitwerk", "~> 2.1", ">= 2.1.2" + s.add_dependency "zeitwerk", "~> 2.1", ">= 2.1.4" end diff --git a/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb b/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb index d5dc7c2ff4..fd39ad6e55 100644 --- a/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb +++ b/activesupport/lib/active_support/dependencies/zeitwerk_integration.rb @@ -23,8 +23,13 @@ module ActiveSupport ActiveSupport::Inflector.safe_constantize(cpath) end - def to_unload?(cpath) - Rails.autoloaders.main.to_unload?(cpath) + def autoloaded_constants + Rails.autoloaders.main.unloadable_cpaths + end + + def autoloaded?(object) + cpath = object.is_a?(Module) ? object.name : object.to_s + Rails.autoloaders.main.unloadable_cpath?(cpath) end def verbose=(verbose) diff --git a/activesupport/lib/active_support/descendants_tracker.rb b/activesupport/lib/active_support/descendants_tracker.rb index fe0c6991aa..21565138a7 100644 --- a/activesupport/lib/active_support/descendants_tracker.rb +++ b/activesupport/lib/active_support/descendants_tracker.rb @@ -22,18 +22,11 @@ module ActiveSupport def clear if defined? ActiveSupport::Dependencies - # to_unload? is only defined in Zeitwerk mode. - to_unload = if Dependencies.respond_to?(:to_unload?) - ->(klass) { Dependencies.to_unload?(klass.name) } - else - ->(klass) { Dependencies.autoloaded?(klass) } - end - @@direct_descendants.each do |klass, descendants| - if to_unload[klass] + if Dependencies.autoloaded?(klass) @@direct_descendants.delete(klass) else - descendants.reject! { |v| to_unload[v] } + descendants.reject! { |v| Dependencies.autoloaded?(v) } end end else diff --git a/railties/test/application/zeitwerk_integration_test.rb b/railties/test/application/zeitwerk_integration_test.rb index 40d06ee999..9146222f73 100644 --- a/railties/test/application/zeitwerk_integration_test.rb +++ b/railties/test/application/zeitwerk_integration_test.rb @@ -98,35 +98,47 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase assert_nil deps.safe_constantize("Admin") end - test "to_unload? says if a constant would be unloaded (main)" do + test "unloadable constants (main)" do app_file "app/models/user.rb", "class User; end" app_file "app/models/post.rb", "class Post; end" boot assert Post - assert deps.to_unload?("Post") - assert_not deps.to_unload?("User") + + assert deps.autoloaded?("Post") + assert deps.autoloaded?(Post) + assert_not deps.autoloaded?("User") + + assert_equal ["Post"], deps.autoloaded_constants end - test "to_unload? says if a constant would be unloaded (once)" do + test "unloadable constants (once)" do add_to_config 'config.autoload_once_paths << "#{Rails.root}/extras"' app_file "extras/foo.rb", "class Foo; end" app_file "extras/bar.rb", "class Bar; end" boot assert Foo - assert_not deps.to_unload?("Foo") - assert_not deps.to_unload?("Bar") + + assert_not deps.autoloaded?("Foo") + assert_not deps.autoloaded?(Foo) + assert_not deps.autoloaded?("Bar") + + assert_empty deps.autoloaded_constants end - test "to_unload? says if a constant would be unloaded (reloading disabled)" do + test "unloadable constants (reloading disabled)" do app_file "app/models/user.rb", "class User; end" app_file "app/models/post.rb", "class Post; end" boot("production") assert Post - assert_not deps.to_unload?("Post") - assert_not deps.to_unload?("User") + + assert_not deps.autoloaded?("Post") + assert_not deps.autoloaded?(Post) + assert_not deps.autoloaded?("User") + + assert_empty deps.autoloaded_constants end test "eager loading loads the application code" do @@ -335,46 +347,4 @@ class ZeitwerkIntegrationTest < ActiveSupport::TestCase assert_nil autoloader.logger end end - - # This is here because to guarantee classic mode works as always, Zeitwerk - # integration does not touch anything in classic. The descendants tracker is a - # very small one-liner exception. We leave its main test suite untouched, and - # add some minimal safety net here. - # - # When time passes, things are going to be reorganized (famous last words). - test "descendants tracker" do - class ::ZeitwerkDTIntegrationTestRoot - extend ActiveSupport::DescendantsTracker - end - class ::ZeitwerkDTIntegrationTestChild < ::ZeitwerkDTIntegrationTestRoot; end - class ::ZeitwerkDTIntegrationTestGrandchild < ::ZeitwerkDTIntegrationTestChild; end - - begin - app_file "app/models/user.rb", "class User < ZeitwerkDTIntegrationTestRoot; end" - app_file "app/models/post.rb", "class Post < ZeitwerkDTIntegrationTestRoot; end" - app_file "app/models/tutorial.rb", "class Tutorial < Post; end" - boot - - assert User - assert Tutorial - - direct_descendants = [ZeitwerkDTIntegrationTestChild, User, Post].to_set - assert_equal direct_descendants, ZeitwerkDTIntegrationTestRoot.direct_descendants.to_set - - descendants = direct_descendants.merge([ZeitwerkDTIntegrationTestGrandchild, Tutorial]) - assert_equal descendants, ZeitwerkDTIntegrationTestRoot.descendants.to_set - - ActiveSupport::DescendantsTracker.clear - - direct_descendants = [ZeitwerkDTIntegrationTestChild].to_set - assert_equal direct_descendants, ZeitwerkDTIntegrationTestRoot.direct_descendants.to_set - - descendants = direct_descendants.merge([ZeitwerkDTIntegrationTestGrandchild]) - assert_equal descendants, ZeitwerkDTIntegrationTestRoot.descendants.to_set - ensure - Object.send(:remove_const, :ZeitwerkDTIntegrationTestRoot) - Object.send(:remove_const, :ZeitwerkDTIntegrationTestChild) - Object.send(:remove_const, :ZeitwerkDTIntegrationTestGrandchild) - end - end end