zeitwerk 2.6.2 → 2.6.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a7faace5f41a2ea580759f539f13136531f9291010d68821fe430ee0e0b89cbb
4
- data.tar.gz: c1da4a297fc7339d19bbfecf453972576b22f27498a780cc2534ff4d1a2731e7
3
+ metadata.gz: 8c7bbcbb7fa03b5ef6389335805145cabf2a4fdd203c15b3c6ecdf68f229e499
4
+ data.tar.gz: 3581c99a8d4431eeeed3b6139aca5363f9c13d136dddb22aa5c88b55d2ff2dac
5
5
  SHA512:
6
- metadata.gz: dc9ba4bd627b775bdd01bcc0ef5d902c348519b63ac12d4bfb3177f1da1f9b4c0308a611327cad9c092b84ebecc50b72e419ad51e4c44f95c8ed029d2f073a8e
7
- data.tar.gz: addc0120d3b187668e0a8128eaf904dbe406f9bd78bd1192eef4ada7bcc35c252396a9f01c2e07bf7e1ba5d1aff3ae5646ca05cec498d7cc4b659f1f6ebd5388
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 project to function properly.
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
 
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is a private module.
4
+ module Zeitwerk::Internal
5
+ def internal(method_name)
6
+ private method_name
7
+
8
+ mangled = "__#{method_name}"
9
+ alias_method mangled, method_name
10
+ public mangled
11
+ end
12
+ end
@@ -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 :root_dirs
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
- root_dirs[abspath] = namespace
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
- root_dirs.clone
151
+ roots.clone
150
152
  else
151
- root_dirs.keys
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 root_dirs.key?(abspath)
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 actual_root_dirs
296
- root_dirs.reject do |root_dir, _namespace|
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
- root_dirs.key?(dir)
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 root_dirs.key?(abspath)
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
- actual_root_dirs.each do |root_dir, namespace|
16
- actual_eager_load_dir(root_dir, namespace, force: force)
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 = root_dirs[dir]
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
- actual_root_dirs.each do |root_dir, root_namespace|
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 = root_dirs[dir]
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 = real_mod_name(child)
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
@@ -31,7 +31,7 @@ module Zeitwerk::Loader::Helpers
31
31
  next if ignored_paths.member?(abspath)
32
32
 
33
33
  if dir?(abspath)
34
- next if root_dirs.key?(abspath)
34
+ next if roots.key?(abspath)
35
35
  next if !has_at_least_one_ruby_file?(abspath)
36
36
  else
37
37
  next unless ruby?(abspath)
@@ -116,8 +116,8 @@ module Zeitwerk
116
116
  mutex.synchronize do
117
117
  break if @setup
118
118
 
119
- actual_root_dirs.each do |root_dir, namespace|
120
- set_autoloads_in_dir(root_dir, namespace)
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.ignores?(dir)
448
+ next if loader.__ignores?(dir)
447
449
 
448
- dir = dir + "/"
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
- root_dir = root_dir + "/"
453
- if dir.start_with?(root_dir) || root_dir.start_with?(dir)
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.chop}," \
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zeitwerk
4
- VERSION = "2.6.2"
4
+ VERSION = "2.6.4"
5
5
  end
data/lib/zeitwerk.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Zeitwerk
4
4
  require_relative "zeitwerk/real_mod_name"
5
+ require_relative "zeitwerk/internal"
5
6
  require_relative "zeitwerk/loader"
6
7
  require_relative "zeitwerk/gem_loader"
7
8
  require_relative "zeitwerk/registry"
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.2
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-10-31 00:00:00.000000000 Z
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