zeitwerk 2.7.5 → 2.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +125 -71
- data/lib/zeitwerk/core_ext/kernel.rb +1 -1
- data/lib/zeitwerk/cref/map.rb +1 -1
- data/lib/zeitwerk/cref.rb +8 -1
- data/lib/zeitwerk/error.rb +12 -1
- data/lib/zeitwerk/gem_inflector.rb +3 -3
- data/lib/zeitwerk/gem_loader.rb +4 -4
- data/lib/zeitwerk/inflector.rb +8 -8
- data/lib/zeitwerk/loader/callbacks.rb +1 -1
- data/lib/zeitwerk/loader/config.rb +87 -24
- data/lib/zeitwerk/loader/constant_path_validator.rb +17 -0
- data/lib/zeitwerk/loader/eager_load.rb +23 -27
- data/lib/zeitwerk/loader/file_system.rb +72 -25
- data/lib/zeitwerk/loader/helpers.rb +3 -6
- data/lib/zeitwerk/loader.rb +166 -126
- data/lib/zeitwerk/registry/loaders.rb +2 -2
- data/lib/zeitwerk/registry.rb +6 -6
- data/lib/zeitwerk/version.rb +1 -1
- data/lib/zeitwerk.rb +13 -13
- metadata +2 -1
data/lib/zeitwerk/loader.rb
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'monitor'
|
|
4
|
+
require 'set'
|
|
5
5
|
|
|
6
6
|
module Zeitwerk
|
|
7
7
|
class Loader
|
|
8
|
-
require_relative
|
|
9
|
-
require_relative
|
|
10
|
-
require_relative
|
|
11
|
-
require_relative
|
|
12
|
-
require_relative
|
|
8
|
+
require_relative 'loader/helpers'
|
|
9
|
+
require_relative 'loader/callbacks'
|
|
10
|
+
require_relative 'loader/config'
|
|
11
|
+
require_relative 'loader/eager_load'
|
|
12
|
+
require_relative 'loader/file_system'
|
|
13
|
+
require_relative 'loader/constant_path_validator'
|
|
13
14
|
|
|
14
15
|
extend Internal
|
|
15
16
|
|
|
@@ -22,8 +23,8 @@ module Zeitwerk
|
|
|
22
23
|
# Maps absolute paths for which an autoload has been set ---and not
|
|
23
24
|
# executed--- to their corresponding Zeitwerk::Cref object.
|
|
24
25
|
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
26
|
+
# '/Users/fxn/blog/app/models/user.rb' => #<Zeitwerk::Cref:... @mod=Object, @cname=:User, ...>,
|
|
27
|
+
# '/Users/fxn/blog/app/models/hotel/pricing.rb' => #<Zeitwerk::Cref:... @mod=Hotel, @cname=:Pricing, ...>,
|
|
27
28
|
# ...
|
|
28
29
|
#
|
|
29
30
|
#: Hash[String, Zeitwerk::Cref]
|
|
@@ -102,6 +103,7 @@ module Zeitwerk
|
|
|
102
103
|
attr_reader :dirs_autoload_monitor
|
|
103
104
|
private :dirs_autoload_monitor
|
|
104
105
|
|
|
106
|
+
#: () -> void
|
|
105
107
|
def initialize
|
|
106
108
|
super
|
|
107
109
|
|
|
@@ -114,6 +116,7 @@ module Zeitwerk
|
|
|
114
116
|
@setup = false
|
|
115
117
|
@eager_loaded = false
|
|
116
118
|
@fs = FileSystem.new(self)
|
|
119
|
+
@cpv = ConstantPathValidator.new
|
|
117
120
|
|
|
118
121
|
@mutex = Mutex.new
|
|
119
122
|
@dirs_autoload_monitor = Monitor.new
|
|
@@ -129,7 +132,7 @@ module Zeitwerk
|
|
|
129
132
|
break if @setup
|
|
130
133
|
|
|
131
134
|
actual_roots.each do |root_dir, root_namespace|
|
|
132
|
-
define_autoloads_for_dir(root_dir, root_namespace)
|
|
135
|
+
define_autoloads_for_dir(root_dir, root_namespace, external: true)
|
|
133
136
|
end
|
|
134
137
|
|
|
135
138
|
on_setup_callbacks.each(&:call)
|
|
@@ -153,73 +156,79 @@ module Zeitwerk
|
|
|
153
156
|
def unload
|
|
154
157
|
mutex.synchronize do
|
|
155
158
|
raise SetupRequired unless @setup
|
|
159
|
+
__unload
|
|
160
|
+
end
|
|
161
|
+
end
|
|
156
162
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
else
|
|
169
|
-
# Could happen if loaded with require_relative. That is unsupported,
|
|
170
|
-
# and the constant path would escape unloadable_cpath? This is just
|
|
171
|
-
# defensive code to clean things up as much as we are able to.
|
|
172
|
-
unload_cref(cref)
|
|
173
|
-
unloaded_files.add(abspath) if @fs.rb_extension?(abspath)
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
to_unload.each do |abspath, cref|
|
|
178
|
-
unless on_unload_callbacks.empty?
|
|
179
|
-
begin
|
|
180
|
-
value = cref.get
|
|
181
|
-
rescue ::NameError
|
|
182
|
-
# Perhaps the user deleted the constant by hand, or perhaps an
|
|
183
|
-
# autoload failed to define the expected constant but the user
|
|
184
|
-
# rescued the exception.
|
|
185
|
-
else
|
|
186
|
-
run_on_unload_callbacks(cref, value, abspath)
|
|
187
|
-
end
|
|
188
|
-
end
|
|
163
|
+
# This is an internal method.
|
|
164
|
+
#
|
|
165
|
+
#: () -> void
|
|
166
|
+
def __unload
|
|
167
|
+
# We are going to keep track of the files that were required by our
|
|
168
|
+
# autoloads to later remove them from $LOADED_FEATURES, thus making them
|
|
169
|
+
# loadable by Kernel#require again.
|
|
170
|
+
#
|
|
171
|
+
# Directories are not stored in $LOADED_FEATURES, keeping track of files
|
|
172
|
+
# is enough.
|
|
173
|
+
unloaded_files = Set.new
|
|
189
174
|
|
|
175
|
+
autoloads.each do |abspath, cref|
|
|
176
|
+
if cref.autoload?
|
|
177
|
+
unload_autoload(cref)
|
|
178
|
+
else
|
|
179
|
+
# Could happen if loaded with require_relative. That is unsupported,
|
|
180
|
+
# and the constant path would escape unloadable_cpath? This is just
|
|
181
|
+
# defensive code to clean things up as much as we are able to.
|
|
190
182
|
unload_cref(cref)
|
|
191
183
|
unloaded_files.add(abspath) if @fs.rb_extension?(abspath)
|
|
192
184
|
end
|
|
185
|
+
end
|
|
193
186
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
# one of those methods.
|
|
206
|
-
$LOADED_FEATURES.reject! { |file| unloaded_files.member?(file) }
|
|
187
|
+
to_unload.each do |abspath, cref|
|
|
188
|
+
unless on_unload_callbacks.empty?
|
|
189
|
+
begin
|
|
190
|
+
value = cref.get
|
|
191
|
+
rescue ::NameError
|
|
192
|
+
# Perhaps the user deleted the constant by hand, or perhaps an
|
|
193
|
+
# autoload failed to define the expected constant but the user
|
|
194
|
+
# rescued the exception.
|
|
195
|
+
else
|
|
196
|
+
run_on_unload_callbacks(cref, value, abspath)
|
|
197
|
+
end
|
|
207
198
|
end
|
|
208
199
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
namespace_dirs.clear
|
|
213
|
-
shadowed_files.clear
|
|
200
|
+
unload_cref(cref)
|
|
201
|
+
unloaded_files.add(abspath) if @fs.rb_extension?(abspath)
|
|
202
|
+
end
|
|
214
203
|
|
|
215
|
-
|
|
216
|
-
|
|
204
|
+
unless unloaded_files.empty?
|
|
205
|
+
# Bootsnap decorates Kernel#require to speed it up using a cache and
|
|
206
|
+
# this optimization does not check if $LOADED_FEATURES has the file.
|
|
207
|
+
#
|
|
208
|
+
# To make it aware of changes, the gem defines singleton methods in
|
|
209
|
+
# $LOADED_FEATURES:
|
|
210
|
+
#
|
|
211
|
+
# https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb
|
|
212
|
+
#
|
|
213
|
+
# Rails applications may depend on bootsnap, so for unloading to work
|
|
214
|
+
# in that setting it is preferable that we restrict our API choice to
|
|
215
|
+
# one of those methods.
|
|
216
|
+
$LOADED_FEATURES.reject! { |file| unloaded_files.member?(file) }
|
|
217
|
+
end
|
|
217
218
|
|
|
218
|
-
|
|
219
|
+
autoloads.clear
|
|
220
|
+
autoloaded_dirs.clear
|
|
221
|
+
to_unload.clear
|
|
222
|
+
namespace_dirs.clear
|
|
223
|
+
shadowed_files.clear
|
|
219
224
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
225
|
+
unregister_inceptions
|
|
226
|
+
unregister_explicit_namespaces
|
|
227
|
+
|
|
228
|
+
Registry.autoloads.unregister_loader(self)
|
|
229
|
+
|
|
230
|
+
@setup = false
|
|
231
|
+
@eager_loaded = false
|
|
223
232
|
end
|
|
224
233
|
|
|
225
234
|
# Unloads all loaded code, and calls setup again so that the loader is able
|
|
@@ -234,8 +243,11 @@ module Zeitwerk
|
|
|
234
243
|
raise SetupRequired unless @setup
|
|
235
244
|
|
|
236
245
|
unload
|
|
246
|
+
|
|
237
247
|
recompute_ignored_paths
|
|
238
248
|
recompute_collapse_dirs
|
|
249
|
+
recompute_collapse_parents
|
|
250
|
+
|
|
239
251
|
setup
|
|
240
252
|
end
|
|
241
253
|
|
|
@@ -252,18 +264,20 @@ module Zeitwerk
|
|
|
252
264
|
while (dir, cpath = queue.shift)
|
|
253
265
|
result[dir] = cpath
|
|
254
266
|
|
|
255
|
-
prefix = cpath ==
|
|
267
|
+
prefix = cpath == 'Object' ? '' : cpath + '::'
|
|
256
268
|
|
|
257
|
-
@fs.ls(dir) do |basename, abspath, ftype|
|
|
269
|
+
@fs.ls(dir, collapse: false) do |basename, abspath, ftype|
|
|
258
270
|
if ftype == :file
|
|
259
|
-
basename
|
|
260
|
-
|
|
261
|
-
else
|
|
262
|
-
if collapse?(abspath)
|
|
263
|
-
queue << [abspath, cpath]
|
|
271
|
+
if basename == @nsfile
|
|
272
|
+
result[abspath] = cpath
|
|
264
273
|
else
|
|
265
|
-
|
|
274
|
+
basename.delete_suffix!('.rb')
|
|
275
|
+
result[abspath] = "#{prefix}#{cname_for(basename, abspath)}"
|
|
266
276
|
end
|
|
277
|
+
elsif collapse?(abspath)
|
|
278
|
+
queue.unshift([abspath, cpath])
|
|
279
|
+
else
|
|
280
|
+
queue.push([abspath, "#{prefix}#{cname_for(basename, abspath)}"])
|
|
267
281
|
end
|
|
268
282
|
end
|
|
269
283
|
end
|
|
@@ -285,11 +299,11 @@ module Zeitwerk
|
|
|
285
299
|
|
|
286
300
|
paths = []
|
|
287
301
|
|
|
288
|
-
if
|
|
289
|
-
basename = File.basename(abspath
|
|
302
|
+
if ftype == :file
|
|
303
|
+
basename = File.basename(abspath)
|
|
290
304
|
return if @fs.hidden?(basename)
|
|
291
305
|
|
|
292
|
-
paths << [basename, abspath]
|
|
306
|
+
paths << [basename.delete_suffix('.rb'), abspath] unless basename == @nsfile
|
|
293
307
|
walk_up_from = File.dirname(abspath)
|
|
294
308
|
else
|
|
295
309
|
walk_up_from = abspath
|
|
@@ -315,9 +329,9 @@ module Zeitwerk
|
|
|
315
329
|
cnames = paths.reverse_each.map { cname_for(_1, _2) }
|
|
316
330
|
|
|
317
331
|
if root_namespace == Object
|
|
318
|
-
cnames.join(
|
|
332
|
+
cnames.join('::')
|
|
319
333
|
else
|
|
320
|
-
"#{real_mod_name(root_namespace)}::#{cnames.join(
|
|
334
|
+
"#{real_mod_name(root_namespace)}::#{cnames.join('::')}"
|
|
321
335
|
end
|
|
322
336
|
end
|
|
323
337
|
end
|
|
@@ -384,10 +398,10 @@ module Zeitwerk
|
|
|
384
398
|
|
|
385
399
|
# This is a shortcut for
|
|
386
400
|
#
|
|
387
|
-
# require
|
|
401
|
+
# require 'zeitwerk'
|
|
388
402
|
#
|
|
389
403
|
# loader = Zeitwerk::Loader.new
|
|
390
|
-
# loader.tag = File.basename(__FILE__,
|
|
404
|
+
# loader.tag = File.basename(__FILE__, '.rb')
|
|
391
405
|
# loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
|
|
392
406
|
# loader.push_dir(__dir__)
|
|
393
407
|
#
|
|
@@ -405,10 +419,10 @@ module Zeitwerk
|
|
|
405
419
|
|
|
406
420
|
# This is a shortcut for
|
|
407
421
|
#
|
|
408
|
-
# require
|
|
422
|
+
# require 'zeitwerk'
|
|
409
423
|
#
|
|
410
424
|
# loader = Zeitwerk::Loader.new
|
|
411
|
-
# loader.tag = namespace.name +
|
|
425
|
+
# loader.tag = namespace.name + '-' + File.basename(__FILE__, '.rb')
|
|
412
426
|
# loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
|
|
413
427
|
# loader.push_dir(__dir__, namespace: namespace)
|
|
414
428
|
#
|
|
@@ -425,7 +439,7 @@ module Zeitwerk
|
|
|
425
439
|
end
|
|
426
440
|
|
|
427
441
|
unless real_mod_name(namespace)
|
|
428
|
-
raise Zeitwerk::Error,
|
|
442
|
+
raise Zeitwerk::Error, 'extending anonymous namespaces is unsupported'
|
|
429
443
|
end
|
|
430
444
|
|
|
431
445
|
called_from = caller_locations(1, 1).first.path
|
|
@@ -473,68 +487,94 @@ module Zeitwerk
|
|
|
473
487
|
end
|
|
474
488
|
end
|
|
475
489
|
|
|
476
|
-
|
|
477
|
-
|
|
490
|
+
# Scans `dir` and sets autoloads in `mod` for the constants its contents are
|
|
491
|
+
# expected to define.
|
|
492
|
+
#
|
|
493
|
+
# The `external` flag indicates whether `mod` has been externally defined,
|
|
494
|
+
# as is the case with root namespaces or reopened third-party namespaces.
|
|
495
|
+
#
|
|
496
|
+
#: (String, Module, external: boolish) -> void
|
|
497
|
+
private def define_autoloads_for_dir(dir, mod, external:)
|
|
478
498
|
@fs.ls(dir) do |basename, abspath, ftype|
|
|
479
499
|
if ftype == :file
|
|
480
|
-
basename
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
autoload_subdir(cref, abspath)
|
|
500
|
+
if basename == @nsfile
|
|
501
|
+
if external
|
|
502
|
+
cpath = real_mod_name(mod)
|
|
503
|
+
location = Object.const_source_location(cpath)&.join(':')
|
|
504
|
+
location = nil if location&.empty?
|
|
505
|
+
raise Zeitwerk::ConflictingNamespaceDefinitionError.new(cpath, location: location, conflicting_file: abspath)
|
|
506
|
+
end
|
|
507
|
+
next # Pass if this is a managed namespace, the nsfile was already probed when visiting the parent directory.
|
|
489
508
|
end
|
|
509
|
+
|
|
510
|
+
basename.delete_suffix!('.rb')
|
|
511
|
+
cref = Cref.new(mod, cname_for(basename, abspath))
|
|
512
|
+
visit_file(cref, abspath)
|
|
513
|
+
else
|
|
514
|
+
cref = Cref.new(mod, cname_for(basename, abspath))
|
|
515
|
+
visit_subdir(cref, abspath, external:)
|
|
490
516
|
end
|
|
491
517
|
end
|
|
492
518
|
end
|
|
493
519
|
|
|
494
520
|
#: (Zeitwerk::Cref, String) -> void
|
|
495
|
-
private def
|
|
521
|
+
private def visit_file(cref, file)
|
|
522
|
+
if autoload_path = cref.autoload? || Registry.inceptions.registered?(cref)
|
|
523
|
+
if @fs.rb_extension?(autoload_path)
|
|
524
|
+
if File.basename(autoload_path) == @nsfile && autoload_path_set_by_me_for?(cref)
|
|
525
|
+
raise Zeitwerk::ConflictingNamespaceDefinitionError.new(cref.path, location: autoload_path, conflicting_file: file)
|
|
526
|
+
end
|
|
527
|
+
shadowed_files << file
|
|
528
|
+
log { "file #{file} is ignored because #{autoload_path} has precedence" }
|
|
529
|
+
else
|
|
530
|
+
promote_namespace_from_implicit_to_explicit(dir: autoload_path, file: file, cref: cref)
|
|
531
|
+
end
|
|
532
|
+
elsif cref.defined?
|
|
533
|
+
shadowed_files << file
|
|
534
|
+
if location = cref.location
|
|
535
|
+
log { "file #{file} is ignored because #{cref} is already defined in #{location}" }
|
|
536
|
+
else
|
|
537
|
+
log { "file #{file} is ignored because #{cref} is already defined (unknown location)" }
|
|
538
|
+
end
|
|
539
|
+
else
|
|
540
|
+
define_autoload(cref, file)
|
|
541
|
+
end
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
#: (Zeitwerk::Cref, String, external: boolish) -> void
|
|
545
|
+
private def visit_subdir(cref, subdir, external:)
|
|
496
546
|
if autoload_path = autoload_path_set_by_me_for?(cref)
|
|
497
547
|
if @fs.rb_extension?(autoload_path)
|
|
548
|
+
# The namespace that corresponds to this subdirectory is defined in a
|
|
549
|
+
# file, either regular or nsfile. Therefore, a nsfile would be a
|
|
550
|
+
# duplication.
|
|
551
|
+
if nsfile_abspath = @fs.has_exactly_one_nsfile?(cref, subdir)
|
|
552
|
+
raise Zeitwerk::ConflictingNamespaceDefinitionError.new(cref.path, location: autoload_path, conflicting_file: nsfile_abspath)
|
|
553
|
+
end
|
|
498
554
|
# Scanning visited a Ruby file first, and now a directory for the same
|
|
499
|
-
# constant has been found. This
|
|
500
|
-
# namespace whose definition was seen first.
|
|
555
|
+
# constant has been found. This is an explicit namespace.
|
|
501
556
|
#
|
|
502
|
-
#
|
|
503
|
-
#
|
|
504
|
-
# on, no big deal.
|
|
557
|
+
# The namespace may be spread over multiple directories and perhaps it
|
|
558
|
+
# was already registered, but registering is idempotent, just do it.
|
|
505
559
|
register_explicit_namespace(cref)
|
|
560
|
+
elsif nsfile_abspath = @fs.has_exactly_one_nsfile?(cref, subdir)
|
|
561
|
+
# Scanning found a matching directory first, and now we saw a nsfile.
|
|
562
|
+
promote_namespace_from_implicit_to_explicit(dir: subdir, file: nsfile_abspath, cref: cref)
|
|
506
563
|
end
|
|
507
|
-
# If the existing autoload points to a file, it has to be preserved, if
|
|
508
|
-
# not, it is fine as it is. In either case, we do not need to override.
|
|
509
|
-
# Just remember the subdirectory conforms this namespace.
|
|
510
564
|
namespace_dirs.get_or_set(cref) { [] } << subdir
|
|
511
565
|
elsif !cref.defined?
|
|
512
|
-
|
|
566
|
+
if nsfile_abspath = @fs.has_exactly_one_nsfile?(cref, subdir)
|
|
567
|
+
define_autoload(cref, nsfile_abspath)
|
|
568
|
+
register_explicit_namespace(cref)
|
|
569
|
+
else
|
|
570
|
+
define_autoload(cref, subdir)
|
|
571
|
+
end
|
|
513
572
|
namespace_dirs.get_or_set(cref) { [] } << subdir
|
|
514
|
-
define_autoload(cref, subdir)
|
|
515
573
|
else
|
|
516
574
|
# For whatever reason the constant that corresponds to this namespace has
|
|
517
575
|
# already been defined, we have to recurse.
|
|
518
576
|
log { "the namespace #{cref} already exists, descending into #{subdir}" }
|
|
519
|
-
define_autoloads_for_dir(subdir, cref.get)
|
|
520
|
-
end
|
|
521
|
-
end
|
|
522
|
-
|
|
523
|
-
#: (Zeitwerk::Cref, String) -> void
|
|
524
|
-
private def autoload_file(cref, file)
|
|
525
|
-
if autoload_path = cref.autoload? || Registry.inceptions.registered?(cref)
|
|
526
|
-
# First autoload for a Ruby file wins, just ignore subsequent ones.
|
|
527
|
-
if @fs.rb_extension?(autoload_path)
|
|
528
|
-
shadowed_files << file
|
|
529
|
-
log { "file #{file} is ignored because #{autoload_path} has precedence" }
|
|
530
|
-
else
|
|
531
|
-
promote_namespace_from_implicit_to_explicit(dir: autoload_path, file: file, cref: cref)
|
|
532
|
-
end
|
|
533
|
-
elsif cref.defined?
|
|
534
|
-
shadowed_files << file
|
|
535
|
-
log { "file #{file} is ignored because #{cref} is already defined" }
|
|
536
|
-
else
|
|
537
|
-
define_autoload(cref, file)
|
|
577
|
+
define_autoloads_for_dir(subdir, cref.get, external:)
|
|
538
578
|
end
|
|
539
579
|
end
|
|
540
580
|
|
|
@@ -608,7 +648,7 @@ module Zeitwerk
|
|
|
608
648
|
#: (String) -> void
|
|
609
649
|
private def raise_if_conflicting_root_dir(root_dir)
|
|
610
650
|
if loader = Registry.conflicting_root_dir?(self, root_dir)
|
|
611
|
-
require
|
|
651
|
+
require 'pp' # Needed to have pretty_inspect available.
|
|
612
652
|
raise Error,
|
|
613
653
|
"loader\n\n#{pretty_inspect}\n\nwants to manage directory #{root_dir}," \
|
|
614
654
|
" which is already managed by\n\n#{loader.pretty_inspect}\n"
|
data/lib/zeitwerk/registry.rb
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Zeitwerk
|
|
4
4
|
module Registry # :nodoc: all
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
5
|
+
require_relative 'registry/autoloads'
|
|
6
|
+
require_relative 'registry/explicit_namespaces'
|
|
7
|
+
require_relative 'registry/inceptions'
|
|
8
|
+
require_relative 'registry/loaders'
|
|
9
9
|
|
|
10
10
|
class << self
|
|
11
11
|
# Keeps track of all loaders. Useful to broadcast messages and to prevent
|
|
@@ -54,8 +54,8 @@ module Zeitwerk
|
|
|
54
54
|
# Conflicting directories are rare, optimize for the common case.
|
|
55
55
|
next if !new_root_dir.start_with?(existing_root_dir) && !existing_root_dir.start_with?(new_root_dir)
|
|
56
56
|
|
|
57
|
-
new_root_dir_slash = new_root_dir +
|
|
58
|
-
existing_root_dir_slash = existing_root_dir +
|
|
57
|
+
new_root_dir_slash = new_root_dir + '/'
|
|
58
|
+
existing_root_dir_slash = existing_root_dir + '/'
|
|
59
59
|
next if !new_root_dir_slash.start_with?(existing_root_dir_slash) && !existing_root_dir_slash.start_with?(new_root_dir_slash)
|
|
60
60
|
|
|
61
61
|
next if loader.__ignores?(existing_root_dir)
|
data/lib/zeitwerk/version.rb
CHANGED
data/lib/zeitwerk.rb
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Zeitwerk
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
9
|
-
require_relative
|
|
10
|
-
require_relative
|
|
11
|
-
require_relative
|
|
12
|
-
require_relative
|
|
13
|
-
require_relative
|
|
14
|
-
require_relative
|
|
4
|
+
require_relative 'zeitwerk/real_mod_name'
|
|
5
|
+
require_relative 'zeitwerk/internal'
|
|
6
|
+
require_relative 'zeitwerk/cref'
|
|
7
|
+
require_relative 'zeitwerk/loader'
|
|
8
|
+
require_relative 'zeitwerk/gem_loader'
|
|
9
|
+
require_relative 'zeitwerk/registry'
|
|
10
|
+
require_relative 'zeitwerk/inflector'
|
|
11
|
+
require_relative 'zeitwerk/gem_inflector'
|
|
12
|
+
require_relative 'zeitwerk/null_inflector'
|
|
13
|
+
require_relative 'zeitwerk/error'
|
|
14
|
+
require_relative 'zeitwerk/version'
|
|
15
15
|
|
|
16
|
-
require_relative
|
|
17
|
-
require_relative
|
|
16
|
+
require_relative 'zeitwerk/core_ext/kernel'
|
|
17
|
+
require_relative 'zeitwerk/core_ext/module'
|
|
18
18
|
|
|
19
19
|
# This is a dangerous method.
|
|
20
20
|
#
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zeitwerk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Xavier Noria
|
|
@@ -34,6 +34,7 @@ files:
|
|
|
34
34
|
- lib/zeitwerk/loader.rb
|
|
35
35
|
- lib/zeitwerk/loader/callbacks.rb
|
|
36
36
|
- lib/zeitwerk/loader/config.rb
|
|
37
|
+
- lib/zeitwerk/loader/constant_path_validator.rb
|
|
37
38
|
- lib/zeitwerk/loader/eager_load.rb
|
|
38
39
|
- lib/zeitwerk/loader/file_system.rb
|
|
39
40
|
- lib/zeitwerk/loader/helpers.rb
|