zeitwerk 2.2.2 → 2.3.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 +58 -15
- 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: b8fd1828e8e92937af8b1e46033442f517c65c07a443a9a265b67c03f22b8b86
|
4
|
+
data.tar.gz: 4e04076d6ac82d1bff9bf3db8604ca7e826afad753fb1268116cd115f15d301b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cacd0d2c43a566a5e3be7dfb98585e9598a9fda8e930bb0f97a96180db332d6303fb1cfbf850f85dd822071968fc624262b94c27db85ad3e1236f1e243df64c2
|
7
|
+
data.tar.gz: 0f9c90d543eae10edade4777f63c02a0f5ef30ecfdfe752fc9f11e5f6e3c835d2b893b0e8074e4cd068859e41dcf6e5374527c73499876deab3a9974cd0d2bf4
|
data/README.md
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
- [File structure](#file-structure)
|
13
13
|
- [Implicit namespaces](#implicit-namespaces)
|
14
14
|
- [Explicit namespaces](#explicit-namespaces)
|
15
|
+
- [Collapsing directories](#collapsing-directories)
|
15
16
|
- [Nested root directories](#nested-root-directories)
|
16
17
|
- [Usage](#usage)
|
17
18
|
- [Setup](#setup)
|
@@ -165,6 +166,32 @@ end
|
|
165
166
|
|
166
167
|
An explicit namespace must be managed by one single loader. Loaders that reopen namespaces owned by other projects are responsible for loading their constants before setup.
|
167
168
|
|
169
|
+
<a id="markdown-collapsing-directories" name="collapsing-directories"></a>
|
170
|
+
### Collapsing directories
|
171
|
+
|
172
|
+
Say some directories in a project exist for organizational purposes only, and you prefer not to have them as namespaces. For example, the `actions` subdirectory in the next example is not meant to represent a namespace, it is there only to group all actions related to bookings:
|
173
|
+
|
174
|
+
```
|
175
|
+
booking.rb -> Booking
|
176
|
+
booking/actions/create.rb -> Booking::Create
|
177
|
+
```
|
178
|
+
|
179
|
+
To make it work that way, configure Zeitwerk to collapse said directory:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
loader.collapse("booking/actions")
|
183
|
+
```
|
184
|
+
|
185
|
+
This method accepts an arbitrary number of strings or `Pathname` objects, and also an array of them.
|
186
|
+
|
187
|
+
You can pass directories and glob patterns. Glob patterns are expanded when they are added, and again on each reload.
|
188
|
+
|
189
|
+
To illustrate usage of glob patterns, if `actions` in the example above is part of a standardized structure, you could use a wildcard:
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
loader.collapse("*/actions")
|
193
|
+
```
|
194
|
+
|
168
195
|
<a id="markdown-nested-root-directories" name="nested-root-directories"></a>
|
169
196
|
### Nested root directories
|
170
197
|
|
data/lib/zeitwerk/loader.rb
CHANGED
@@ -39,7 +39,7 @@ module Zeitwerk
|
|
39
39
|
# @return [<String>]
|
40
40
|
attr_reader :preloads
|
41
41
|
|
42
|
-
# Absolute paths of files, directories,
|
42
|
+
# Absolute paths of files, directories, or glob patterns to be totally
|
43
43
|
# ignored.
|
44
44
|
#
|
45
45
|
# @private
|
@@ -54,6 +54,19 @@ module Zeitwerk
|
|
54
54
|
# @return [Set<String>]
|
55
55
|
attr_reader :ignored_paths
|
56
56
|
|
57
|
+
# Absolute paths of directories or glob patterns to be collapsed.
|
58
|
+
#
|
59
|
+
# @private
|
60
|
+
# @return [Set<String>]
|
61
|
+
attr_reader :collapse_glob_patterns
|
62
|
+
|
63
|
+
# The actual collection of absolute directory names at the time the collapse
|
64
|
+
# glob patterns were expanded. Computed on setup, and recomputed on reload.
|
65
|
+
#
|
66
|
+
# @private
|
67
|
+
# @return [Set<String>]
|
68
|
+
attr_reader :collapse_dirs
|
69
|
+
|
57
70
|
# Maps real absolute paths for which an autoload has been set ---and not
|
58
71
|
# executed--- to their corresponding parent class or module and constant
|
59
72
|
# name.
|
@@ -131,15 +144,17 @@ module Zeitwerk
|
|
131
144
|
@inflector = Inflector.new
|
132
145
|
@logger = self.class.default_logger
|
133
146
|
|
134
|
-
@root_dirs
|
135
|
-
@preloads
|
136
|
-
@ignored_glob_patterns
|
137
|
-
@ignored_paths
|
138
|
-
@
|
139
|
-
@
|
140
|
-
@
|
141
|
-
@
|
142
|
-
@
|
147
|
+
@root_dirs = {}
|
148
|
+
@preloads = []
|
149
|
+
@ignored_glob_patterns = Set.new
|
150
|
+
@ignored_paths = Set.new
|
151
|
+
@collapse_glob_patterns = Set.new
|
152
|
+
@collapse_dirs = Set.new
|
153
|
+
@autoloads = {}
|
154
|
+
@autoloaded_dirs = []
|
155
|
+
@to_unload = {}
|
156
|
+
@lazy_subdirs = {}
|
157
|
+
@eager_load_exclusions = Set.new
|
143
158
|
|
144
159
|
# TODO: find a better name for these mutexes.
|
145
160
|
@mutex = Mutex.new
|
@@ -154,6 +169,7 @@ module Zeitwerk
|
|
154
169
|
|
155
170
|
# Sets a tag for the loader, useful for logging.
|
156
171
|
#
|
172
|
+
# @param tag [#to_s]
|
157
173
|
# @return [void]
|
158
174
|
def tag=(tag)
|
159
175
|
@tag = tag.to_s
|
@@ -233,6 +249,18 @@ module Zeitwerk
|
|
233
249
|
end
|
234
250
|
end
|
235
251
|
|
252
|
+
# Configure directories or glob patterns to be collapsed.
|
253
|
+
#
|
254
|
+
# @param paths [<String, Pathname, <String, Pathname>>]
|
255
|
+
# @return [void]
|
256
|
+
def collapse(*glob_patterns)
|
257
|
+
glob_patterns = expand_paths(glob_patterns)
|
258
|
+
mutex.synchronize do
|
259
|
+
collapse_glob_patterns.merge(glob_patterns)
|
260
|
+
collapse_dirs.merge(expand_glob_patterns(glob_patterns))
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
236
264
|
# Sets autoloads in the root namespace and preloads files, if any.
|
237
265
|
#
|
238
266
|
# @return [void]
|
@@ -306,7 +334,8 @@ module Zeitwerk
|
|
306
334
|
Registry.on_unload(self)
|
307
335
|
ExplicitNamespace.unregister(self)
|
308
336
|
|
309
|
-
@setup
|
337
|
+
@setup = false
|
338
|
+
@eager_loaded = false
|
310
339
|
end
|
311
340
|
end
|
312
341
|
|
@@ -322,6 +351,7 @@ module Zeitwerk
|
|
322
351
|
if reloading_enabled?
|
323
352
|
unload
|
324
353
|
recompute_ignored_paths
|
354
|
+
recompute_collapse_dirs
|
325
355
|
setup
|
326
356
|
else
|
327
357
|
raise ReloadingDisabledError, "can't reload, please call loader.enable_reloading before setup"
|
@@ -351,8 +381,12 @@ module Zeitwerk
|
|
351
381
|
cref[0].const_get(cref[1], false)
|
352
382
|
end
|
353
383
|
elsif dir?(abspath) && !root_dirs.key?(abspath)
|
354
|
-
|
355
|
-
|
384
|
+
if collapse_dirs.member?(abspath)
|
385
|
+
queue << [namespace, abspath]
|
386
|
+
else
|
387
|
+
cname = inflector.camelize(basename, abspath)
|
388
|
+
queue << [namespace.const_get(cname, false), abspath]
|
389
|
+
end
|
356
390
|
end
|
357
391
|
end
|
358
392
|
end
|
@@ -476,7 +510,7 @@ module Zeitwerk
|
|
476
510
|
ls(dir) do |basename, abspath|
|
477
511
|
begin
|
478
512
|
if ruby?(basename)
|
479
|
-
basename
|
513
|
+
basename[-3..-1] = ''
|
480
514
|
cname = inflector.camelize(basename, abspath).to_sym
|
481
515
|
autoload_file(parent, cname, abspath)
|
482
516
|
elsif dir?(abspath)
|
@@ -488,7 +522,11 @@ module Zeitwerk
|
|
488
522
|
# it counts only as root. The guard checks that.
|
489
523
|
unless root_dirs.key?(abspath)
|
490
524
|
cname = inflector.camelize(basename, abspath).to_sym
|
491
|
-
|
525
|
+
if collapse_dirs.member?(abspath)
|
526
|
+
set_autoloads_in_dir(abspath, parent)
|
527
|
+
else
|
528
|
+
autoload_subdir(parent, cname, abspath)
|
529
|
+
end
|
492
530
|
end
|
493
531
|
end
|
494
532
|
rescue ::NameError => error
|
@@ -717,6 +755,11 @@ module Zeitwerk
|
|
717
755
|
ignored_paths.replace(expand_glob_patterns(ignored_glob_patterns))
|
718
756
|
end
|
719
757
|
|
758
|
+
# @return [void]
|
759
|
+
def recompute_collapse_dirs
|
760
|
+
collapse_dirs.replace(expand_glob_patterns(collapse_glob_patterns))
|
761
|
+
end
|
762
|
+
|
720
763
|
# @param message [String]
|
721
764
|
# @return [void]
|
722
765
|
def log(message)
|
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.
|
4
|
+
version: 2.3.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:
|
11
|
+
date: 2020-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
Zeitwerk implements constant autoloading with Ruby semantics. Each gem
|