zeitwerk 2.6.3 → 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: a554ef9e7a26b8edb48779c400a620aa694e54313626505d231fa3c72d4f66fe
4
- data.tar.gz: 779e40bff86dbb627aef9dfd3ed897620994f7578a3673b640fad2a449c61a61
3
+ metadata.gz: 8c7bbcbb7fa03b5ef6389335805145cabf2a4fdd203c15b3c6ecdf68f229e499
4
+ data.tar.gz: 3581c99a8d4431eeeed3b6139aca5363f9c13d136dddb22aa5c88b55d2ff2dac
5
5
  SHA512:
6
- metadata.gz: a9038b69db15d5800aec43f5e6d2367df5ea04f19b00f0cd9a76c36eebac1f7cc2e085442e05b4ece448ef0a717b8f10c5c75367d63dbdbfb916a3e2bf505fed
7
- data.tar.gz: 065c3b61d2cc6fb82ae3e98ddca31c4d6842cb3d7f68187c822c7b6c97720cdbfa8de9c11b5b1ff749fc655d408cc98f72dd1107e08979a5249ba6451e2539ed
6
+ metadata.gz: 3575d2cd414fe45f4c42ce286fbf9cbf648ed0cf5c3643db82167023adde590058cbe88c2348fe2c9f6f8d56f04858ef49441115544dca88b18b48f2eb36d886
7
+ data.tar.gz: 4d9fc1a1c72df9233e742f22ad2a0bd636301e55cd9078e856cdfb9a8b2727345d86f278e592fb0294959e9aad92895619e69133050afa943192a61477bad64d
@@ -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,16 +441,17 @@ 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
- suffixed_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 suffixed_dir.start_with?(root_dir) || root_dir.start_with?(suffixed_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
457
  "loader\n\n#{pretty_inspect}\n\nwants to manage directory #{dir}," \
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Zeitwerk
4
- VERSION = "2.6.3"
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.3
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