zeitwerk 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +27 -0
- data/lib/zeitwerk/loader.rb +62 -48
- data/lib/zeitwerk/registry.rb +1 -0
- 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: ce0c3d755356cd98361bd89b27925a3083632a8e2f25191808e987d0f5a0c40e
|
4
|
+
data.tar.gz: fb21b9d8e59e12b672a464e748157814c265898da26a71225229f29d9ea9023f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3fa972c877ed3c36efc98224088869ec383370bbf002761e0f379550ce31e50cf387a729890fd36e4768d99929a566ef3587a717208aa7d6e8e7abb1c29df1b
|
7
|
+
data.tar.gz: ab0b2b3e11d46e21ce3605f8dcf8dcb6a579ca6ce7438c58d6b87d07f1431f4c346bdc07d5c1ae9601a577d5c592e938f07a56fe583b8fa27a308371afca4fea
|
data/README.md
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
- [Zeitwerk::GemInflector](#zeitwerkgeminflector)
|
23
23
|
- [Custom inflector](#custom-inflector)
|
24
24
|
- [Logging](#logging)
|
25
|
+
- [Loader tag](#loader-tag)
|
25
26
|
- [Ignoring parts of the project](#ignoring-parts-of-the-project)
|
26
27
|
- [Files that do not follow the conventions](#files-that-do-not-follow-the-conventions)
|
27
28
|
- [The adapter pattern](#the-adapter-pattern)
|
@@ -297,8 +298,34 @@ loader.logger = method(:puts)
|
|
297
298
|
|
298
299
|
If there is a logger configured, the loader is going to print traces when autoloads are set, files loaded, and modules autovivified. While reloading, removed autoloads and unloaded objects are also traced.
|
299
300
|
|
301
|
+
It is possible to set a global default this way:
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
Zeitwerk::Loader.default_logger = method(:puts)
|
305
|
+
```
|
306
|
+
|
300
307
|
If your project has namespaces, you'll notice in the traces Zeitwerk sets autoloads for _directories_. That's a technique used to be able to descend into subdirectories on demand, avoiding that way unnecessary tree walks.
|
301
308
|
|
309
|
+
#### Loader tag
|
310
|
+
|
311
|
+
Loaders have a tag that is printed in traces in order to be able to distinguish them in globally logged activity:
|
312
|
+
|
313
|
+
```
|
314
|
+
Zeitwerk@9fa54b: autoload set for User, to be loaded from ...
|
315
|
+
```
|
316
|
+
|
317
|
+
By default, a random tag like the one above is assigned, but you can change it:
|
318
|
+
|
319
|
+
```
|
320
|
+
loader.tag = "grep_me"
|
321
|
+
```
|
322
|
+
|
323
|
+
The tag of a loader returned by `for_gem` is the basename of the root file without extension:
|
324
|
+
|
325
|
+
```
|
326
|
+
Zeitwerk@my_gem: constant MyGem::Foo loaded from ...
|
327
|
+
```
|
328
|
+
|
302
329
|
### Ignoring parts of the project
|
303
330
|
|
304
331
|
Zeitwerk ignores automatically any file or directory whose name starts with a dot, and any files that do not have extension ".rb".
|
data/lib/zeitwerk/loader.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "set"
|
4
|
+
require "securerandom"
|
4
5
|
|
5
6
|
module Zeitwerk
|
6
7
|
class Loader
|
8
|
+
# @return [String]
|
9
|
+
attr_reader :tag
|
10
|
+
|
7
11
|
# @return [#camelize]
|
8
12
|
attr_accessor :inflector
|
9
13
|
|
@@ -94,7 +98,9 @@ module Zeitwerk
|
|
94
98
|
attr_reader :tracer
|
95
99
|
|
96
100
|
def initialize
|
97
|
-
|
101
|
+
@tag = SecureRandom.hex(3)
|
102
|
+
@inflector = Inflector.new
|
103
|
+
@logger = self.class.default_logger
|
98
104
|
|
99
105
|
@root_dirs = {}
|
100
106
|
@preloads = []
|
@@ -119,6 +125,13 @@ module Zeitwerk
|
|
119
125
|
Registry.register_loader(self)
|
120
126
|
end
|
121
127
|
|
128
|
+
# Sets a tag for the loader, useful for logging.
|
129
|
+
#
|
130
|
+
# @return [void]
|
131
|
+
def tag=(tag)
|
132
|
+
@tag = tag.to_s
|
133
|
+
end
|
134
|
+
|
122
135
|
# Absolute paths of the root directories. This is a read-only collection,
|
123
136
|
# please push here via `push_dir`.
|
124
137
|
#
|
@@ -150,13 +163,7 @@ module Zeitwerk
|
|
150
163
|
mutex.synchronize do
|
151
164
|
expand_paths(paths).each do |abspath|
|
152
165
|
preloads << abspath
|
153
|
-
if @setup
|
154
|
-
if ruby?(abspath)
|
155
|
-
do_preload_file(abspath)
|
156
|
-
elsif dir?(abspath)
|
157
|
-
do_preload_dir(abspath)
|
158
|
-
end
|
159
|
-
end
|
166
|
+
do_preload_abspath(abspath) if @setup
|
160
167
|
end
|
161
168
|
end
|
162
169
|
end
|
@@ -264,35 +271,40 @@ module Zeitwerk
|
|
264
271
|
|
265
272
|
# --- Class methods ---------------------------------------------------------------------------
|
266
273
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
274
|
+
class << self
|
275
|
+
# @return [#call, nil]
|
276
|
+
attr_accessor :default_logger
|
277
|
+
|
278
|
+
# This is a shortcut for
|
279
|
+
#
|
280
|
+
# require "zeitwerk"
|
281
|
+
# loader = Zeitwerk::Loader.new
|
282
|
+
# loader.inflector = Zeitwerk::GemInflector.new
|
283
|
+
# loader.push_dir(__dir__)
|
284
|
+
#
|
285
|
+
# except that this method returns the same object in subsequent calls from
|
286
|
+
# the same file, in the unlikely case the gem wants to be able to reload.
|
287
|
+
#
|
288
|
+
# @return [Zeitwerk::Loader]
|
289
|
+
def for_gem
|
290
|
+
called_from = caller[0].split(':')[0]
|
291
|
+
Registry.loader_for_gem(called_from)
|
292
|
+
end
|
282
293
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
294
|
+
# Broadcasts `eager_load` to all loaders.
|
295
|
+
#
|
296
|
+
# @return [void]
|
297
|
+
def eager_load_all
|
298
|
+
Registry.loaders.each(&:eager_load)
|
299
|
+
end
|
289
300
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
301
|
+
# Returns an array with the absolute paths of the root directories of all
|
302
|
+
# registered loaders. This is a read-only collection.
|
303
|
+
#
|
304
|
+
# @return [<String>]
|
305
|
+
def all_dirs
|
306
|
+
Registry.loaders.flat_map(&:dirs).freeze
|
307
|
+
end
|
296
308
|
end
|
297
309
|
|
298
310
|
# --- Callbacks -------------------------------------------------------------------------------
|
@@ -352,7 +364,7 @@ module Zeitwerk
|
|
352
364
|
end
|
353
365
|
|
354
366
|
# @param parent [Module]
|
355
|
-
# @
|
367
|
+
# @param cname [String]
|
356
368
|
# @param subdir [String]
|
357
369
|
# @return [void]
|
358
370
|
def autoload_subdir(parent, cname, subdir)
|
@@ -374,7 +386,7 @@ module Zeitwerk
|
|
374
386
|
end
|
375
387
|
|
376
388
|
# @param parent [Module]
|
377
|
-
# @
|
389
|
+
# @param cname [String]
|
378
390
|
# @param file [String]
|
379
391
|
# @return [void]
|
380
392
|
def autoload_file(parent, cname, file)
|
@@ -449,11 +461,17 @@ module Zeitwerk
|
|
449
461
|
# @return [void]
|
450
462
|
def do_preload
|
451
463
|
preloads.each do |abspath|
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
464
|
+
do_preload_abspath(abspath)
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
# @param abspath [String]
|
469
|
+
# @return [void]
|
470
|
+
def do_preload_abspath(abspath)
|
471
|
+
if ruby?(abspath)
|
472
|
+
do_preload_file(abspath)
|
473
|
+
elsif dir?(abspath)
|
474
|
+
do_preload_dir(abspath)
|
457
475
|
end
|
458
476
|
end
|
459
477
|
|
@@ -461,11 +479,7 @@ module Zeitwerk
|
|
461
479
|
# @return [void]
|
462
480
|
def do_preload_dir(dir)
|
463
481
|
each_abspath(dir) do |abspath|
|
464
|
-
|
465
|
-
do_preload_file(abspath)
|
466
|
-
elsif dir?(abspath)
|
467
|
-
do_preload_dir(abspath)
|
468
|
-
end
|
482
|
+
do_preload_abspath(abspath)
|
469
483
|
end
|
470
484
|
end
|
471
485
|
|
@@ -515,7 +529,7 @@ module Zeitwerk
|
|
515
529
|
# @param message [String]
|
516
530
|
# @return [void]
|
517
531
|
def log(message)
|
518
|
-
logger.call("Zeitwerk: #{message}")
|
532
|
+
logger.call("Zeitwerk@#{tag}: #{message}")
|
519
533
|
end
|
520
534
|
|
521
535
|
def enable_tracer
|
data/lib/zeitwerk/registry.rb
CHANGED
@@ -83,6 +83,7 @@ module Zeitwerk
|
|
83
83
|
def loader_for_gem(root_file)
|
84
84
|
loaders_managing_gems[root_file] ||= begin
|
85
85
|
Loader.new.tap do |loader|
|
86
|
+
loader.tag = File.basename(root_file, ".rb")
|
86
87
|
loader.inflector = GemInflector.new(root_file)
|
87
88
|
loader.push_dir(File.dirname(root_file))
|
88
89
|
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: 1.
|
4
|
+
version: 1.1.0
|
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-02-
|
11
|
+
date: 2019-02-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
Zeitwerk implements constant autoloading with Ruby semantics. Each gem
|