zeitwerk 2.1.5 → 2.1.6
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 +9 -1
- data/lib/zeitwerk/loader.rb +48 -22
- data/lib/zeitwerk/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43750607caaaa5d4fff5bd52204cafb98fbd5109b51a24d9099ba83c6a2a4990
|
4
|
+
data.tar.gz: 8ad3251fd93af9e66a9102c13556beff5805a38660d69e4c5de37e2808e76d8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6e87877104078f564686a15b81882a8e20a560a36999e0f8b9916aa520dd46fe1a2b7f65cacdb7b6c62d252472b6ce1370939054f026a335e21652881820814
|
7
|
+
data.tar.gz: 3641d412ab4b9176861b9ed9b28ea7964b6a814ebb72804c96967e511562fb87f424c48d7780345be8ccd2c53bdacfe095e3e5173e166a4185bf389740258ca6
|
data/README.md
CHANGED
@@ -338,7 +338,15 @@ This needs to be done before calling `setup`.
|
|
338
338
|
<a id="markdown-logging" name="logging"></a>
|
339
339
|
### Logging
|
340
340
|
|
341
|
-
Zeitwerk is silent by default, but you can
|
341
|
+
Zeitwerk is silent by default, but you can ask loaders to trace their activity. Logging is meant just for troubleshooting, shouldn't normally be enabled.
|
342
|
+
|
343
|
+
The `log!` mehtod is a quick shortcut to let the loader log to `$stdout`:
|
344
|
+
|
345
|
+
```
|
346
|
+
loader.log!
|
347
|
+
```
|
348
|
+
|
349
|
+
If you want more control, a logger can be configured as a callable
|
342
350
|
|
343
351
|
```ruby
|
344
352
|
loader.logger = method(:puts)
|
data/lib/zeitwerk/loader.rb
CHANGED
@@ -53,6 +53,23 @@ module Zeitwerk
|
|
53
53
|
# @return [Set<String>]
|
54
54
|
attr_reader :ignored_paths
|
55
55
|
|
56
|
+
# A _shadowed file_ is a file managed by this loader that is ignored when
|
57
|
+
# setting autoloads because its matching constant is taken. Either the
|
58
|
+
# constant is already defined, or there exists an autoload for it.
|
59
|
+
#
|
60
|
+
# Think $LOAD_PATH and require, only the first occurrence of a given
|
61
|
+
# relative name is loaded.
|
62
|
+
#
|
63
|
+
# This set keeps track of the absolute path of shadowed files, to be able to
|
64
|
+
# skip them while eager loading.
|
65
|
+
#
|
66
|
+
# Note this cannot be implemented with do_not_eager_load because these
|
67
|
+
# files are not autoloadable.
|
68
|
+
#
|
69
|
+
# @private
|
70
|
+
# @return [Set<String>]
|
71
|
+
attr_reader :shadowed_files
|
72
|
+
|
56
73
|
# Maps real absolute paths for which an autoload has been set ---and not
|
57
74
|
# executed--- to their corresponding parent class or module and constant
|
58
75
|
# name.
|
@@ -138,6 +155,7 @@ module Zeitwerk
|
|
138
155
|
@autoloaded_dirs = []
|
139
156
|
@to_unload = {}
|
140
157
|
@lazy_subdirs = {}
|
158
|
+
@shadowed_files = Set.new
|
141
159
|
@eager_load_exclusions = Set.new
|
142
160
|
|
143
161
|
# TODO: find a better name for these mutexes.
|
@@ -306,6 +324,7 @@ module Zeitwerk
|
|
306
324
|
autoloaded_dirs.clear
|
307
325
|
to_unload.clear
|
308
326
|
lazy_subdirs.clear
|
327
|
+
shadowed_files.clear
|
309
328
|
|
310
329
|
Registry.on_unload(self)
|
311
330
|
ExplicitNamespace.unregister(self)
|
@@ -343,19 +362,19 @@ module Zeitwerk
|
|
343
362
|
|
344
363
|
queue = actual_root_dirs.reject { |dir| eager_load_exclusions.member?(dir) }
|
345
364
|
while dir = queue.shift
|
346
|
-
|
347
|
-
|
348
|
-
each_abspath(dir) do |abspath|
|
365
|
+
ls(dir) do |_basename, abspath|
|
349
366
|
next if eager_load_exclusions.member?(abspath)
|
350
367
|
|
351
368
|
if ruby?(abspath)
|
352
|
-
|
369
|
+
require abspath unless shadowed_files.member?(abspath)
|
353
370
|
elsif dir?(abspath)
|
354
371
|
queue << abspath
|
355
372
|
end
|
356
373
|
end
|
357
374
|
end
|
358
375
|
|
376
|
+
shadowed_files.clear
|
377
|
+
|
359
378
|
autoloaded_dirs.each do |autoloaded_dir|
|
360
379
|
Registry.unregister_autoload(autoloaded_dir)
|
361
380
|
end
|
@@ -391,6 +410,13 @@ module Zeitwerk
|
|
391
410
|
to_unload.keys.freeze
|
392
411
|
end
|
393
412
|
|
413
|
+
# Logs to `$stdout`, handy shortcut for debugging.
|
414
|
+
#
|
415
|
+
# @return [void]
|
416
|
+
def log!
|
417
|
+
@logger = ->(msg) { puts msg }
|
418
|
+
end
|
419
|
+
|
394
420
|
# --- Class methods ---------------------------------------------------------------------------
|
395
421
|
|
396
422
|
class << self
|
@@ -414,7 +440,7 @@ module Zeitwerk
|
|
414
440
|
#
|
415
441
|
# @return [Zeitwerk::Loader]
|
416
442
|
def for_gem
|
417
|
-
called_from = caller_locations.first.path
|
443
|
+
called_from = caller_locations(1, 1).first.path
|
418
444
|
Registry.loader_for_gem(called_from)
|
419
445
|
end
|
420
446
|
|
@@ -449,9 +475,10 @@ module Zeitwerk
|
|
449
475
|
# @param parent [Module]
|
450
476
|
# @return [void]
|
451
477
|
def set_autoloads_in_dir(dir, parent)
|
452
|
-
|
453
|
-
|
454
|
-
|
478
|
+
ls(dir) do |basename, abspath|
|
479
|
+
if ruby?(basename)
|
480
|
+
basename.slice!(-3, 3)
|
481
|
+
cname = inflector.camelize(basename, abspath).to_sym
|
455
482
|
autoload_file(parent, cname, abspath)
|
456
483
|
elsif dir?(abspath)
|
457
484
|
# In a Rails application, `app/models/concerns` is a subdirectory of
|
@@ -460,7 +487,10 @@ module Zeitwerk
|
|
460
487
|
# To resolve the ambiguity file name -> constant path this introduces,
|
461
488
|
# the `app/models/concerns` directory is totally ignored as a namespace,
|
462
489
|
# it counts only as root. The guard checks that.
|
463
|
-
|
490
|
+
unless root_dirs.key?(abspath)
|
491
|
+
cname = inflector.camelize(basename, abspath).to_sym
|
492
|
+
autoload_subdir(parent, cname, abspath)
|
493
|
+
end
|
464
494
|
end
|
465
495
|
end
|
466
496
|
end
|
@@ -496,6 +526,7 @@ module Zeitwerk
|
|
496
526
|
if autoload_path = autoload_for?(parent, cname)
|
497
527
|
# First autoload for a Ruby file wins, just ignore subsequent ones.
|
498
528
|
if ruby?(autoload_path)
|
529
|
+
shadowed_files.add(file)
|
499
530
|
log("file #{file} is ignored because #{autoload_path} has precedence") if logger
|
500
531
|
else
|
501
532
|
promote_namespace_from_implicit_to_explicit(
|
@@ -506,6 +537,7 @@ module Zeitwerk
|
|
506
537
|
)
|
507
538
|
end
|
508
539
|
elsif cdef?(parent, cname)
|
540
|
+
shadowed_files.add(file)
|
509
541
|
log("file #{file} is ignored because #{cpath(parent, cname)} is already defined") if logger
|
510
542
|
else
|
511
543
|
set_autoload(parent, cname, file)
|
@@ -605,7 +637,7 @@ module Zeitwerk
|
|
605
637
|
# @param dir [String]
|
606
638
|
# @return [void]
|
607
639
|
def do_preload_dir(dir)
|
608
|
-
|
640
|
+
ls(dir) do |_basename, abspath|
|
609
641
|
do_preload_abspath(abspath)
|
610
642
|
end
|
611
643
|
end
|
@@ -625,13 +657,13 @@ module Zeitwerk
|
|
625
657
|
end
|
626
658
|
|
627
659
|
# @param dir [String]
|
628
|
-
# @yieldparam path [String]
|
660
|
+
# @yieldparam path [String, String]
|
629
661
|
# @return [void]
|
630
|
-
def
|
631
|
-
Dir.foreach(dir) do |
|
632
|
-
next if
|
633
|
-
abspath = File.join(dir,
|
634
|
-
yield abspath unless ignored_paths.member?(abspath)
|
662
|
+
def ls(dir)
|
663
|
+
Dir.foreach(dir) do |basename|
|
664
|
+
next if basename.start_with?(".")
|
665
|
+
abspath = File.join(dir, basename)
|
666
|
+
yield basename, abspath unless ignored_paths.member?(abspath)
|
635
667
|
end
|
636
668
|
end
|
637
669
|
|
@@ -664,12 +696,6 @@ module Zeitwerk
|
|
664
696
|
parent.const_defined?(cname, false)
|
665
697
|
end
|
666
698
|
|
667
|
-
def const_get_if_autoload(abspath)
|
668
|
-
if cref = autoloads[File.realpath(abspath)]
|
669
|
-
cref[0].const_get(cref[1], false)
|
670
|
-
end
|
671
|
-
end
|
672
|
-
|
673
699
|
def register_explicit_namespace(cpath)
|
674
700
|
ExplicitNamespace.register(cpath, self)
|
675
701
|
end
|
data/lib/zeitwerk/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zeitwerk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Xavier Noria
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
Zeitwerk implements constant autoloading with Ruby semantics. Each gem
|