@@ -29,13 +29,11 @@ def load; end
2929 def load_bundle ( gemfile , initialize_file , require_file , halt_upon_load_error )
3030 require_helper ( initialize_file )
3131
32- load_rails_application ( halt_upon_load_error : halt_upon_load_error )
32+ load_rails_application ( environment_load : true , halt_upon_load_error : halt_upon_load_error )
3333
3434 gemfile . require_bundle
3535
3636 require_helper ( require_file )
37-
38- load_rails_engines
3937 end
4038
4139 sig do
@@ -85,116 +83,6 @@ def load_rails_application(environment_load: false, eager_load: false, app_root:
8583 say ( "Continuing RBI generation without loading the Rails application." )
8684 end
8785
88- sig { void }
89- def load_rails_engines
90- return if engines . empty?
91-
92- with_rails_application do
93- run_initializers
94-
95- if zeitwerk_mode?
96- load_engines_in_zeitwerk_mode
97- else
98- load_engines_in_classic_mode
99- end
100- end
101- end
102-
103- def run_initializers
104- engines . each do |engine |
105- engine . instance . initializers . tsort_each do |initializer |
106- initializer . run ( Rails . application )
107- rescue ScriptError , StandardError
108- nil
109- end
110- end
111- end
112-
113- sig { void }
114- def load_engines_in_zeitwerk_mode
115- # Collect all the directories that are already managed by all existing Zeitwerk loaders.
116- managed_dirs = Zeitwerk ::Registry . loaders . flat_map ( &:dirs ) . to_set
117- # We use a fresh loader to load the engine directories, so that we don't interfere with
118- # any of the existing loaders.
119- autoloader = Zeitwerk ::Loader . new
120-
121- engines . each do |engine |
122- eager_load_paths ( engine ) . each do |path |
123- # Zeitwerk only accepts existing directories in `push_dir`.
124- next unless File . directory? ( path )
125- # We should not add directories that are already managed by a Zeitwerk loader.
126- next if managed_dirs . member? ( path )
127-
128- autoloader . push_dir ( path )
129- end
130- end
131-
132- autoloader . setup
133- end
134-
135- sig { void }
136- def load_engines_in_classic_mode
137- # This is code adapted from `Rails::Engine#eager_load!` in
138- # https://github.com/rails/rails/blob/d9e188dbab81b412f73dfb7763318d52f360af49/railties/lib/rails/engine.rb#L489-L495
139- #
140- # We can't use `Rails::Engine#eager_load!` directly because it will raise as soon as it encounters
141- # an error, which is not what we want. We want to try to load as much as we can.
142- engines . each do |engine |
143- eager_load_paths ( engine ) . each do |load_path |
144- Dir . glob ( "#{ load_path } /**/*.rb" ) . sort . each do |file |
145- require_dependency file
146- end
147- rescue ScriptError , StandardError
148- nil
149- end
150- end
151- end
152-
153- sig { returns ( T ::Boolean ) }
154- def zeitwerk_mode?
155- Rails . respond_to? ( :autoloaders ) &&
156- Rails . autoloaders . respond_to? ( :zeitwerk_enabled? ) &&
157- Rails . autoloaders . zeitwerk_enabled?
158- end
159-
160- sig { params ( blk : T . proc . void ) . void }
161- def with_rails_application ( &blk )
162- # Store the current Rails.application object so that we can restore it
163- rails_application = T . unsafe ( Rails . application )
164-
165- # Create a new Rails::Application object, so that we can load the engines.
166- # Some engines and the `Rails.autoloaders` call might expect `Rails.application`
167- # to be set, so we need to create one here.
168- unless rails_application
169- Rails . application = Class . new ( Rails ::Application )
170- end
171-
172- blk . call
173- ensure
174- Rails . app_class = Rails . application = rails_application
175- end
176-
177- T ::Sig ::WithoutRuntime . sig { returns ( T ::Array [ T . class_of ( Rails ::Engine ) ] ) }
178- def engines
179- return [ ] unless defined? ( Rails ::Engine )
180-
181- safe_require ( "active_support/core_ext/class/subclasses" )
182-
183- project_path = Bundler . default_gemfile . parent . expand_path
184- # We can use `Class#descendants` here, since we know Rails is loaded
185- Rails ::Engine
186- . descendants
187- . reject ( &:abstract_railtie? )
188- . reject { |engine | gem_in_app_dir? ( project_path , engine . config . root . to_path ) }
189- end
190-
191- sig { params ( path : String ) . void }
192- def safe_require ( path )
193- require path
194- rescue LoadError
195- nil
196- end
197-
19886 sig { void }
19987 def eager_load_rails_app
20088 application = Rails . application
0 commit comments