zeitwerk 2.6.2 → 2.6.4
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 +1 -1
- data/lib/zeitwerk/internal.rb +12 -0
- data/lib/zeitwerk/loader/config.rb +38 -39
- data/lib/zeitwerk/loader/eager_load.rb +12 -11
- data/lib/zeitwerk/loader/helpers.rb +1 -1
- data/lib/zeitwerk/loader.rb +9 -8
- data/lib/zeitwerk/version.rb +1 -1
- data/lib/zeitwerk.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c7bbcbb7fa03b5ef6389335805145cabf2a4fdd203c15b3c6ecdf68f229e499
|
4
|
+
data.tar.gz: 3581c99a8d4431eeeed3b6139aca5363f9c13d136dddb22aa5c88b55d2ff2dac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3575d2cd414fe45f4c42ce286fbf9cbf648ed0cf5c3643db82167023adde590058cbe88c2348fe2c9f6f8d56f04858ef49441115544dca88b18b48f2eb36d886
|
7
|
+
data.tar.gz: 4d9fc1a1c72df9233e742f22ad2a0bd636301e55cd9078e856cdfb9a8b2727345d86f278e592fb0294959e9aad92895619e69133050afa943192a61477bad64d
|
data/README.md
CHANGED
@@ -536,7 +536,7 @@ The method `Zeitwerk::Loader.eager_load_namespace` broadcasts `eager_load_namesp
|
|
536
536
|
Zeitwerk::Loader.eager_load_namespace(MyFramework::Routes)
|
537
537
|
```
|
538
538
|
|
539
|
-
This may be handy, for example, if a framework supports plugins and a shared namespace needs to be eager loaded for the
|
539
|
+
This may be handy, for example, if a framework supports plugins and a shared namespace needs to be eager loaded for the framework to function properly.
|
540
540
|
|
541
541
|
Please, note that loaders only eager load namespaces they manage, as documented above. Therefore, this method does not allow you to eager load namespaces not managed by Zeitwerk loaders.
|
542
542
|
|
@@ -4,6 +4,14 @@ require "set"
|
|
4
4
|
require "securerandom"
|
5
5
|
|
6
6
|
module Zeitwerk::Loader::Config
|
7
|
+
extend Zeitwerk::Internal
|
8
|
+
|
9
|
+
# @sig #camelize
|
10
|
+
attr_accessor :inflector
|
11
|
+
|
12
|
+
# @sig #call | #debug | nil
|
13
|
+
attr_accessor :logger
|
14
|
+
|
7
15
|
# Absolute paths of the root directories. Stored in a hash to preserve order,
|
8
16
|
# easily handle duplicates, have a fast lookup needed for detecting nested
|
9
17
|
# paths, and store namespaces as values.
|
@@ -15,74 +23,70 @@ module Zeitwerk::Loader::Config
|
|
15
23
|
# This is a private collection maintained by the loader. The public
|
16
24
|
# interface for it is `push_dir` and `dirs`.
|
17
25
|
#
|
18
|
-
# @private
|
19
26
|
# @sig Hash[String, Module]
|
20
|
-
attr_reader :
|
21
|
-
|
22
|
-
# @sig #camelize
|
23
|
-
attr_accessor :inflector
|
27
|
+
attr_reader :roots
|
28
|
+
internal :roots
|
24
29
|
|
25
30
|
# Absolute paths of files, directories, or glob patterns to be totally
|
26
31
|
# ignored.
|
27
32
|
#
|
28
|
-
# @private
|
29
33
|
# @sig Set[String]
|
30
34
|
attr_reader :ignored_glob_patterns
|
35
|
+
private :ignored_glob_patterns
|
31
36
|
|
32
37
|
# The actual collection of absolute file and directory names at the time the
|
33
38
|
# ignored glob patterns were expanded. Computed on setup, and recomputed on
|
34
39
|
# reload.
|
35
40
|
#
|
36
|
-
# @private
|
37
41
|
# @sig Set[String]
|
38
42
|
attr_reader :ignored_paths
|
43
|
+
private :ignored_paths
|
39
44
|
|
40
45
|
# Absolute paths of directories or glob patterns to be collapsed.
|
41
46
|
#
|
42
|
-
# @private
|
43
47
|
# @sig Set[String]
|
44
48
|
attr_reader :collapse_glob_patterns
|
49
|
+
private :collapse_glob_patterns
|
45
50
|
|
46
51
|
# The actual collection of absolute directory names at the time the collapse
|
47
52
|
# glob patterns were expanded. Computed on setup, and recomputed on reload.
|
48
53
|
#
|
49
|
-
# @private
|
50
54
|
# @sig Set[String]
|
51
55
|
attr_reader :collapse_dirs
|
56
|
+
private :collapse_dirs
|
52
57
|
|
53
58
|
# Absolute paths of files or directories not to be eager loaded.
|
54
59
|
#
|
55
|
-
# @private
|
56
60
|
# @sig Set[String]
|
57
61
|
attr_reader :eager_load_exclusions
|
62
|
+
private :eager_load_exclusions
|
58
63
|
|
59
64
|
# User-oriented callbacks to be fired on setup and on reload.
|
60
65
|
#
|
61
|
-
# @private
|
62
66
|
# @sig Array[{ () -> void }]
|
63
67
|
attr_reader :on_setup_callbacks
|
68
|
+
private :on_setup_callbacks
|
64
69
|
|
65
70
|
# User-oriented callbacks to be fired when a constant is loaded.
|
66
71
|
#
|
67
|
-
# @private
|
68
72
|
# @sig Hash[String, Array[{ (Object, String) -> void }]]
|
69
73
|
# Hash[Symbol, Array[{ (String, Object, String) -> void }]]
|
70
74
|
attr_reader :on_load_callbacks
|
75
|
+
private :on_load_callbacks
|
71
76
|
|
72
77
|
# User-oriented callbacks to be fired before constants are removed.
|
73
78
|
#
|
74
|
-
# @private
|
75
79
|
# @sig Hash[String, Array[{ (Object, String) -> void }]]
|
76
80
|
# Hash[Symbol, Array[{ (String, Object, String) -> void }]]
|
77
81
|
attr_reader :on_unload_callbacks
|
78
|
-
|
79
|
-
# @sig #call | #debug | nil
|
80
|
-
attr_accessor :logger
|
82
|
+
private :on_unload_callbacks
|
81
83
|
|
82
84
|
def initialize
|
83
|
-
@initialized_at = Time.now
|
84
|
-
@root_dirs = {}
|
85
85
|
@inflector = Zeitwerk::Inflector.new
|
86
|
+
@logger = self.class.default_logger
|
87
|
+
@tag = SecureRandom.hex(3)
|
88
|
+
@initialized_at = Time.now
|
89
|
+
@roots = {}
|
86
90
|
@ignored_glob_patterns = Set.new
|
87
91
|
@ignored_paths = Set.new
|
88
92
|
@collapse_glob_patterns = Set.new
|
@@ -92,8 +96,6 @@ module Zeitwerk::Loader::Config
|
|
92
96
|
@on_setup_callbacks = []
|
93
97
|
@on_load_callbacks = {}
|
94
98
|
@on_unload_callbacks = {}
|
95
|
-
@logger = self.class.default_logger
|
96
|
-
@tag = SecureRandom.hex(3)
|
97
99
|
end
|
98
100
|
|
99
101
|
# Pushes `path` to the list of root directories.
|
@@ -113,7 +115,7 @@ module Zeitwerk::Loader::Config
|
|
113
115
|
abspath = File.expand_path(path)
|
114
116
|
if dir?(abspath)
|
115
117
|
raise_if_conflicting_directory(abspath)
|
116
|
-
|
118
|
+
roots[abspath] = namespace
|
117
119
|
else
|
118
120
|
raise Zeitwerk::Error, "the root directory #{abspath} does not exist"
|
119
121
|
end
|
@@ -146,9 +148,9 @@ module Zeitwerk::Loader::Config
|
|
146
148
|
# @sig () -> Array[String] | Hash[String, Module]
|
147
149
|
def dirs(namespaces: false)
|
148
150
|
if namespaces
|
149
|
-
|
151
|
+
roots.clone
|
150
152
|
else
|
151
|
-
|
153
|
+
roots.keys
|
152
154
|
end.freeze
|
153
155
|
end
|
154
156
|
|
@@ -275,71 +277,68 @@ module Zeitwerk::Loader::Config
|
|
275
277
|
# Returns true if the argument has been configured to be ignored, or is a
|
276
278
|
# descendant of an ignored directory.
|
277
279
|
#
|
278
|
-
# @private
|
279
280
|
# @sig (String) -> bool
|
280
|
-
def ignores?(abspath)
|
281
|
+
internal def ignores?(abspath)
|
281
282
|
# Common use case.
|
282
283
|
return false if ignored_paths.empty?
|
283
284
|
|
284
285
|
walk_up(abspath) do |abspath|
|
285
286
|
return true if ignored_paths.member?(abspath)
|
286
|
-
return false if
|
287
|
+
return false if roots.key?(abspath)
|
287
288
|
end
|
288
289
|
|
289
290
|
false
|
290
291
|
end
|
291
292
|
|
292
|
-
private
|
293
|
-
|
294
293
|
# @sig () -> Array[String]
|
295
|
-
def
|
296
|
-
|
294
|
+
private def actual_roots
|
295
|
+
roots.reject do |root_dir, _root_namespace|
|
297
296
|
!dir?(root_dir) || ignored_paths.member?(root_dir)
|
298
297
|
end
|
299
298
|
end
|
300
299
|
|
301
300
|
# @sig (String) -> bool
|
302
|
-
def root_dir?(dir)
|
303
|
-
|
301
|
+
private def root_dir?(dir)
|
302
|
+
roots.key?(dir)
|
304
303
|
end
|
305
304
|
|
306
305
|
# @sig (String) -> bool
|
307
|
-
def excluded_from_eager_load?(abspath)
|
306
|
+
private def excluded_from_eager_load?(abspath)
|
308
307
|
# Optimize this common use case.
|
309
308
|
return false if eager_load_exclusions.empty?
|
310
309
|
|
311
310
|
walk_up(abspath) do |abspath|
|
312
311
|
return true if eager_load_exclusions.member?(abspath)
|
313
|
-
return false if
|
312
|
+
return false if roots.key?(abspath)
|
314
313
|
end
|
315
314
|
|
316
315
|
false
|
317
316
|
end
|
318
317
|
|
319
318
|
# @sig (String) -> bool
|
320
|
-
def collapse?(dir)
|
319
|
+
private def collapse?(dir)
|
321
320
|
collapse_dirs.member?(dir)
|
322
321
|
end
|
323
322
|
|
324
323
|
# @sig (String | Pathname | Array[String | Pathname]) -> Array[String]
|
325
|
-
def expand_paths(paths)
|
324
|
+
private def expand_paths(paths)
|
326
325
|
paths.flatten.map! { |path| File.expand_path(path) }
|
327
326
|
end
|
328
327
|
|
329
328
|
# @sig (Array[String]) -> Array[String]
|
330
|
-
def expand_glob_patterns(glob_patterns)
|
329
|
+
private def expand_glob_patterns(glob_patterns)
|
331
330
|
# Note that Dir.glob works with regular file names just fine. That is,
|
332
331
|
# glob patterns technically need no wildcards.
|
333
332
|
glob_patterns.flat_map { |glob_pattern| Dir.glob(glob_pattern) }
|
334
333
|
end
|
335
334
|
|
336
335
|
# @sig () -> void
|
337
|
-
def recompute_ignored_paths
|
336
|
+
private def recompute_ignored_paths
|
338
337
|
ignored_paths.replace(expand_glob_patterns(ignored_glob_patterns))
|
339
338
|
end
|
340
339
|
|
341
340
|
# @sig () -> void
|
342
|
-
def recompute_collapse_dirs
|
341
|
+
private def recompute_collapse_dirs
|
343
342
|
collapse_dirs.replace(expand_glob_patterns(collapse_glob_patterns))
|
344
343
|
end
|
345
344
|
end
|
@@ -12,8 +12,8 @@ module Zeitwerk::Loader::EagerLoad
|
|
12
12
|
|
13
13
|
log("eager load start") if logger
|
14
14
|
|
15
|
-
|
16
|
-
actual_eager_load_dir(root_dir,
|
15
|
+
actual_roots.each do |root_dir, root_namespace|
|
16
|
+
actual_eager_load_dir(root_dir, root_namespace, force: force)
|
17
17
|
end
|
18
18
|
|
19
19
|
autoloaded_dirs.each do |autoloaded_dir|
|
@@ -40,7 +40,7 @@ module Zeitwerk::Loader::EagerLoad
|
|
40
40
|
return if ignored_paths.member?(dir)
|
41
41
|
return if eager_load_exclusions.member?(dir)
|
42
42
|
|
43
|
-
break if root_namespace =
|
43
|
+
break if root_namespace = roots[dir]
|
44
44
|
|
45
45
|
unless collapse?(dir)
|
46
46
|
basename = File.basename(dir)
|
@@ -73,23 +73,24 @@ module Zeitwerk::Loader::EagerLoad
|
|
73
73
|
|
74
74
|
return if @eager_loaded
|
75
75
|
|
76
|
-
|
76
|
+
mod_name = real_mod_name(mod)
|
77
|
+
return unless mod_name
|
78
|
+
|
79
|
+
actual_roots.each do |root_dir, root_namespace|
|
77
80
|
if mod.equal?(Object)
|
78
81
|
# A shortcircuiting test depends on the invocation of this method.
|
79
82
|
# Please keep them in sync if refactored.
|
80
83
|
actual_eager_load_dir(root_dir, root_namespace)
|
81
84
|
elsif root_namespace.equal?(Object)
|
82
|
-
eager_load_child_namespace(mod, root_dir, root_namespace)
|
85
|
+
eager_load_child_namespace(mod, mod_name, root_dir, root_namespace)
|
83
86
|
else
|
84
|
-
mod_name = real_mod_name(mod)
|
85
87
|
root_namespace_name = real_mod_name(root_namespace)
|
86
|
-
|
87
88
|
if root_namespace_name.start_with?(mod_name + "::")
|
88
89
|
actual_eager_load_dir(root_dir, root_namespace)
|
89
90
|
elsif mod_name == root_namespace_name
|
90
91
|
actual_eager_load_dir(root_dir, root_namespace)
|
91
92
|
elsif mod_name.start_with?(root_namespace_name + "::")
|
92
|
-
eager_load_child_namespace(mod, root_dir, root_namespace)
|
93
|
+
eager_load_child_namespace(mod, mod_name, root_dir, root_namespace)
|
93
94
|
else
|
94
95
|
# Unrelated constant hierarchies, do nothing.
|
95
96
|
end
|
@@ -121,7 +122,7 @@ module Zeitwerk::Loader::EagerLoad
|
|
121
122
|
walk_up(File.dirname(abspath)) do |dir|
|
122
123
|
raise Zeitwerk::Error.new("#{abspath} is ignored") if ignored_paths.member?(dir)
|
123
124
|
|
124
|
-
break if root_namespace =
|
125
|
+
break if root_namespace = roots[dir]
|
125
126
|
|
126
127
|
unless collapse?(dir)
|
127
128
|
basename = File.basename(dir)
|
@@ -180,8 +181,8 @@ module Zeitwerk::Loader::EagerLoad
|
|
180
181
|
# strict namespace descendendant of `root_namespace`.
|
181
182
|
#
|
182
183
|
# @sig (Module, String, Module, Boolean) -> void
|
183
|
-
private def eager_load_child_namespace(child, root_dir, root_namespace)
|
184
|
-
suffix =
|
184
|
+
private def eager_load_child_namespace(child, child_name, root_dir, root_namespace)
|
185
|
+
suffix = child_name
|
185
186
|
unless root_namespace.equal?(Object)
|
186
187
|
suffix = suffix.delete_prefix(real_mod_name(root_namespace) + "::")
|
187
188
|
end
|
data/lib/zeitwerk/loader.rb
CHANGED
@@ -116,8 +116,8 @@ module Zeitwerk
|
|
116
116
|
mutex.synchronize do
|
117
117
|
break if @setup
|
118
118
|
|
119
|
-
|
120
|
-
set_autoloads_in_dir(root_dir,
|
119
|
+
actual_roots.each do |root_dir, root_namespace|
|
120
|
+
set_autoloads_in_dir(root_dir, root_namespace)
|
121
121
|
end
|
122
122
|
|
123
123
|
on_setup_callbacks.each(&:call)
|
@@ -441,19 +441,20 @@ module Zeitwerk
|
|
441
441
|
# @sig (String) -> void
|
442
442
|
def raise_if_conflicting_directory(dir)
|
443
443
|
MUTEX.synchronize do
|
444
|
+
dir_slash = dir + "/"
|
445
|
+
|
444
446
|
Registry.loaders.each do |loader|
|
445
447
|
next if loader == self
|
446
|
-
next if loader.
|
448
|
+
next if loader.__ignores?(dir)
|
447
449
|
|
448
|
-
|
449
|
-
loader.root_dirs.each do |root_dir, _namespace|
|
450
|
+
loader.__roots.each_key do |root_dir|
|
450
451
|
next if ignores?(root_dir)
|
451
452
|
|
452
|
-
|
453
|
-
if
|
453
|
+
root_dir_slash = root_dir + "/"
|
454
|
+
if dir_slash.start_with?(root_dir_slash) || root_dir_slash.start_with?(dir_slash)
|
454
455
|
require "pp" # Needed for pretty_inspect, even in Ruby 2.5.
|
455
456
|
raise Error,
|
456
|
-
"loader\n\n#{pretty_inspect}\n\nwants to manage directory #{dir
|
457
|
+
"loader\n\n#{pretty_inspect}\n\nwants to manage directory #{dir}," \
|
457
458
|
" which is already managed by\n\n#{loader.pretty_inspect}\n"
|
458
459
|
EOS
|
459
460
|
end
|
data/lib/zeitwerk/version.rb
CHANGED
data/lib/zeitwerk.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.6.
|
4
|
+
version: 2.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Xavier Noria
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
Zeitwerk implements constant autoloading with Ruby semantics. Each gem
|
@@ -28,6 +28,7 @@ files:
|
|
28
28
|
- lib/zeitwerk/gem_inflector.rb
|
29
29
|
- lib/zeitwerk/gem_loader.rb
|
30
30
|
- lib/zeitwerk/inflector.rb
|
31
|
+
- lib/zeitwerk/internal.rb
|
31
32
|
- lib/zeitwerk/kernel.rb
|
32
33
|
- lib/zeitwerk/loader.rb
|
33
34
|
- lib/zeitwerk/loader/callbacks.rb
|