zeitwerk 2.8.0 → 2.8.2
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 +6 -12
- data/lib/zeitwerk/loader/config.rb +25 -8
- data/lib/zeitwerk/loader/constant_path_validator.rb +17 -0
- data/lib/zeitwerk/loader/file_system.rb +2 -2
- data/lib/zeitwerk/loader/helpers.rb +1 -4
- data/lib/zeitwerk/loader.rb +2 -0
- data/lib/zeitwerk/registry/loaders.rb +2 -2
- data/lib/zeitwerk/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bc67ff7496feaaf2e3598809e67733b9be0f92f69820736e3471ae0487c39d85
|
|
4
|
+
data.tar.gz: cecf1045923045d9d11d4f5e6c214a9e6dd14abd742fc1065c6f23a8aec82e13
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 739fe00bce3542defa99e3c7a9014d7c4e00d0aa5a062e996c00dc2c9139e26de055e5aee806807c6da614504275bf2c790904d323d47213c031c291713daad6
|
|
7
|
+
data.tar.gz: 85acfebcb1de71e4c54e94803fb3be1c804960d3ba3754cdb6903a32a61e52f139cc06f7672f2cdcabb189dc9d66975479fc20a6733152e58e3131797fc151e4
|
data/README.md
CHANGED
|
@@ -305,8 +305,8 @@ loader.nsfile = 'ns.rb' # must be set before setup
|
|
|
305
305
|
you can alternatively define the explicit namespace inside its directory:
|
|
306
306
|
|
|
307
307
|
```
|
|
308
|
-
my_component/ns.rb
|
|
309
|
-
my_component/widget.rb
|
|
308
|
+
my_component/ns.rb -> MyComponent
|
|
309
|
+
my_component/widget.rb -> MyComponent::Widget
|
|
310
310
|
```
|
|
311
311
|
|
|
312
312
|
This may be handy for self-contained units for which a `my_component.rb` file in the parent directory would feel unnatural.
|
|
@@ -316,19 +316,19 @@ A loader's nsfile has to be a non-hidden basename with a `.rb` extension, as in
|
|
|
316
316
|
Collapsed directories work as expected. For example, if we assume that `src` is collapsed, and that `assets` and `tests` are ignored, you could have the code organized this way:
|
|
317
317
|
|
|
318
318
|
```
|
|
319
|
-
my_component/src/ns.rb
|
|
320
|
-
my_component/src/widget.rb
|
|
319
|
+
my_component/src/ns.rb -> MyComponent
|
|
320
|
+
my_component/src/widget.rb -> MyComponent::Widget
|
|
321
321
|
my_component/assets/widget.js
|
|
322
322
|
my_component/tests/test_widget.rb
|
|
323
323
|
```
|
|
324
324
|
|
|
325
|
-
Loaders with an nsfile configured also support explicit namespaces defined in ordinary files. The
|
|
325
|
+
Loaders with an nsfile configured also support explicit namespaces defined in ordinary files. The conventions are not exclusive project-wide. Some parts may be component-oriented, while in other parts ordinary files may feel more natural. That works.
|
|
326
326
|
|
|
327
327
|
However, attempting to define the same namespace using an ordinary file and an nsfile is an error condition that raises `Zeitwerk::ConflictingNamespaceDefinitionError`.
|
|
328
328
|
|
|
329
329
|
Nsfiles in root directories raise `Zeitwerk::ConflictingNamespaceDefinitionError` too, since the namespace in a root directory is externally defined.
|
|
330
330
|
|
|
331
|
-
|
|
331
|
+
Non-ignored files whose basename is equal to the nsfile are always considered to be nsfiles. You cannot opt out. Therefore, if we have:
|
|
332
332
|
|
|
333
333
|
```ruby
|
|
334
334
|
loader.nsfile = 'index.rb'
|
|
@@ -336,12 +336,6 @@ loader.nsfile = 'index.rb'
|
|
|
336
336
|
|
|
337
337
|
there is no way `foo/index.rb` can define `Foo::Index` in any part of the project, it must define `Foo`.
|
|
338
338
|
|
|
339
|
-
While configurable, `ns.rb` is the recommended convention:
|
|
340
|
-
|
|
341
|
-
* `ns.rb` is short.
|
|
342
|
-
* `ns.rb` suggests "namespace".
|
|
343
|
-
* Needing an `Ns` constant is unlikely.
|
|
344
|
-
|
|
345
339
|
<a id="markdown-collapsing-directories" name="collapsing-directories"></a>
|
|
346
340
|
### Collapsing directories
|
|
347
341
|
|
|
@@ -7,6 +7,9 @@ module Zeitwerk::Loader::Config
|
|
|
7
7
|
extend Zeitwerk::Internal
|
|
8
8
|
include Zeitwerk::RealModName
|
|
9
9
|
|
|
10
|
+
UNDEFINED = Object.new.freeze
|
|
11
|
+
private_constant :UNDEFINED
|
|
12
|
+
|
|
10
13
|
#: camelize(String, String) -> String
|
|
11
14
|
attr_accessor :inflector
|
|
12
15
|
|
|
@@ -276,12 +279,19 @@ module Zeitwerk::Loader::Config
|
|
|
276
279
|
# # ...
|
|
277
280
|
# end
|
|
278
281
|
#
|
|
279
|
-
#: (String
|
|
280
|
-
|
|
281
|
-
|
|
282
|
+
#: (String) { (top, String) -> void } -> void ! TypeError | NameError
|
|
283
|
+
#| { (String, top, String) -> void } -> void
|
|
284
|
+
def on_load(cpath = UNDEFINED, &block)
|
|
285
|
+
key = if cpath.equal?(UNDEFINED)
|
|
286
|
+
:ANY
|
|
287
|
+
elsif !cpath.is_a?(String)
|
|
288
|
+
raise TypeError, 'on_load only accepts strings'
|
|
289
|
+
else
|
|
290
|
+
@cpv.validate!(cpath)
|
|
291
|
+
end
|
|
282
292
|
|
|
283
293
|
mutex.synchronize do
|
|
284
|
-
(on_load_callbacks[
|
|
294
|
+
(on_load_callbacks[key] ||= []) << block
|
|
285
295
|
end
|
|
286
296
|
end
|
|
287
297
|
|
|
@@ -299,12 +309,19 @@ module Zeitwerk::Loader::Config
|
|
|
299
309
|
# # ...
|
|
300
310
|
# end
|
|
301
311
|
#
|
|
302
|
-
#: (String
|
|
303
|
-
|
|
304
|
-
|
|
312
|
+
#: (String) { (top, String) -> void } -> void ! TypeError | NameError
|
|
313
|
+
#| { (String, top, String) -> void } -> void
|
|
314
|
+
def on_unload(cpath = UNDEFINED, &block)
|
|
315
|
+
key = if cpath.equal?(UNDEFINED)
|
|
316
|
+
:ANY
|
|
317
|
+
elsif !cpath.is_a?(String)
|
|
318
|
+
raise TypeError, 'on_unload only accepts strings'
|
|
319
|
+
else
|
|
320
|
+
@cpv.validate!(cpath)
|
|
321
|
+
end
|
|
305
322
|
|
|
306
323
|
mutex.synchronize do
|
|
307
|
-
(on_unload_callbacks[
|
|
324
|
+
(on_unload_callbacks[key] ||= []) << block
|
|
308
325
|
end
|
|
309
326
|
end
|
|
310
327
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @private
|
|
2
|
+
class Zeitwerk::Loader::ConstantPathValidator # :nodoc
|
|
3
|
+
CNAME_VALIDATOR = Module.new.freeze #: Module
|
|
4
|
+
private_constant :CNAME_VALIDATOR
|
|
5
|
+
|
|
6
|
+
# Technically, this validation works with symbols, but API boundary restricts
|
|
7
|
+
# input to strings, so we assume strings, and we test strings.
|
|
8
|
+
#
|
|
9
|
+
#: (String) -> String ! NameError
|
|
10
|
+
def validate!(possible_cpath)
|
|
11
|
+
# We do this before validating because as of this writing, TruffleRuby
|
|
12
|
+
# raises TypeError if the argument has leading colons.
|
|
13
|
+
possible_cpath = possible_cpath.delete_prefix('::')
|
|
14
|
+
CNAME_VALIDATOR.const_defined?(possible_cpath, false)
|
|
15
|
+
possible_cpath
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -27,7 +27,7 @@ class Zeitwerk::Loader::FileSystem # :nodoc:
|
|
|
27
27
|
# path, and file type, which can only be :file or :directory.
|
|
28
28
|
#
|
|
29
29
|
#: (String) { (String, String, Symbol) -> void } -> void
|
|
30
|
-
def ls(dir, collapse: true, &)
|
|
30
|
+
def ls(dir, collapse: true, &block)
|
|
31
31
|
children = relevant_dir_entries(dir)
|
|
32
32
|
|
|
33
33
|
# The order in which a directory is listed depends on the file system.
|
|
@@ -43,7 +43,7 @@ class Zeitwerk::Loader::FileSystem # :nodoc:
|
|
|
43
43
|
@loader.__log { "directory #{abspath} is ignored because it has no Ruby files" }
|
|
44
44
|
next
|
|
45
45
|
elsif collapse && @loader.__collapse?(abspath)
|
|
46
|
-
ls(abspath, collapse: collapse, &)
|
|
46
|
+
ls(abspath, collapse: collapse, &block)
|
|
47
47
|
next
|
|
48
48
|
end
|
|
49
49
|
end
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Zeitwerk::Loader::Helpers
|
|
4
|
-
CNAME_VALIDATOR = Module.new #: Module
|
|
5
|
-
private_constant :CNAME_VALIDATOR
|
|
6
|
-
|
|
7
4
|
#: (String, String) -> Symbol ! Zeitwerk::NameError
|
|
8
5
|
private def cname_for(basename, abspath)
|
|
9
6
|
cname = inflector.camelize(basename, abspath)
|
|
@@ -23,7 +20,7 @@ module Zeitwerk::Loader::Helpers
|
|
|
23
20
|
end
|
|
24
21
|
|
|
25
22
|
begin
|
|
26
|
-
|
|
23
|
+
@cpv.validate!(cname)
|
|
27
24
|
rescue ::NameError => error
|
|
28
25
|
path_type = @fs.rb_extension?(abspath) ? 'file' : 'directory'
|
|
29
26
|
|
data/lib/zeitwerk/loader.rb
CHANGED
|
@@ -10,6 +10,7 @@ module Zeitwerk
|
|
|
10
10
|
require_relative 'loader/config'
|
|
11
11
|
require_relative 'loader/eager_load'
|
|
12
12
|
require_relative 'loader/file_system'
|
|
13
|
+
require_relative 'loader/constant_path_validator'
|
|
13
14
|
|
|
14
15
|
extend Internal
|
|
15
16
|
|
|
@@ -115,6 +116,7 @@ module Zeitwerk
|
|
|
115
116
|
@setup = false
|
|
116
117
|
@eager_loaded = false
|
|
117
118
|
@fs = FileSystem.new(self)
|
|
119
|
+
@cpv = ConstantPathValidator.new
|
|
118
120
|
|
|
119
121
|
@mutex = Mutex.new
|
|
120
122
|
@dirs_autoload_monitor = Monitor.new
|
data/lib/zeitwerk/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zeitwerk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.8.
|
|
4
|
+
version: 2.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Xavier Noria
|
|
@@ -34,6 +34,7 @@ files:
|
|
|
34
34
|
- lib/zeitwerk/loader.rb
|
|
35
35
|
- lib/zeitwerk/loader/callbacks.rb
|
|
36
36
|
- lib/zeitwerk/loader/config.rb
|
|
37
|
+
- lib/zeitwerk/loader/constant_path_validator.rb
|
|
37
38
|
- lib/zeitwerk/loader/eager_load.rb
|
|
38
39
|
- lib/zeitwerk/loader/file_system.rb
|
|
39
40
|
- lib/zeitwerk/loader/helpers.rb
|