im 0.1.3 → 0.1.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: 3f60f56fa26101e6aeec8d3a9123f1ce8196a60ff559931ec91418316cef13e2
4
- data.tar.gz: 445bf0961717077dd35e5ab900b1ab235b25a834a0b1123ed6936c2770439872
3
+ metadata.gz: 99d5cc6d355489148cd6f39fee0e50ce1a25d0e770e4f06c4918fdd41b05935b
4
+ data.tar.gz: ec2372445636beac68c84c0249b68e7e454dda3b0c49293bea4e8f14bfa52053
5
5
  SHA512:
6
- metadata.gz: d0c2063a12bc66f6e86565a27d1e58e2079a88466a61c42a9830fbb0705864ee33f1c780f367dbe61e55b1e21a741cd6c05fc2e4cb7c50ee2bca1625096898c1
7
- data.tar.gz: 4ba1c608ba252e26625ddd136fcaddb3ac8b9f6a5f79db80796ce82ebd8b96da1560b946c79d31a8e658c1fbe5e727d6e68c793dd6a8944e6ceb60b62dd01182
6
+ metadata.gz: f9099a8d43b9772952916c21bd84da42da3eeac2541c0b4fe675fd7c373988d00a9522fc7dc2ce662ea7d0f3231ec4aec11941ab8f079350529d6476e535a19f
7
+ data.tar.gz: 764b1d2454d0158deba3cd4244453aab0d194036b0fe4104c0cb40bced64d5a0bdb6099db3f5c0b9d98cf75c1417707949f353524b8061c5db18ef96ea0aad2d
data/CHANGELOG.md CHANGED
@@ -1,6 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.2] - 2022-09-16
3
+ ## [0.1.4] - 2022-09-19
4
+ - Correctly assign constants imported via recursive requires
5
+
6
+ ## [0.1.3] - 2022-09-16
4
7
  - Fix gemspec
5
8
 
6
9
  ## [0.1.1] - 2022-09-16
data/Gemfile CHANGED
@@ -6,3 +6,4 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "rspec", "~> 3.0"
9
+ gem "rails"
data/Gemfile.lock CHANGED
@@ -1,12 +1,144 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- im (0.1.2)
4
+ im (0.1.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ actioncable (7.0.4)
10
+ actionpack (= 7.0.4)
11
+ activesupport (= 7.0.4)
12
+ nio4r (~> 2.0)
13
+ websocket-driver (>= 0.6.1)
14
+ actionmailbox (7.0.4)
15
+ actionpack (= 7.0.4)
16
+ activejob (= 7.0.4)
17
+ activerecord (= 7.0.4)
18
+ activestorage (= 7.0.4)
19
+ activesupport (= 7.0.4)
20
+ mail (>= 2.7.1)
21
+ net-imap
22
+ net-pop
23
+ net-smtp
24
+ actionmailer (7.0.4)
25
+ actionpack (= 7.0.4)
26
+ actionview (= 7.0.4)
27
+ activejob (= 7.0.4)
28
+ activesupport (= 7.0.4)
29
+ mail (~> 2.5, >= 2.5.4)
30
+ net-imap
31
+ net-pop
32
+ net-smtp
33
+ rails-dom-testing (~> 2.0)
34
+ actionpack (7.0.4)
35
+ actionview (= 7.0.4)
36
+ activesupport (= 7.0.4)
37
+ rack (~> 2.0, >= 2.2.0)
38
+ rack-test (>= 0.6.3)
39
+ rails-dom-testing (~> 2.0)
40
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
41
+ actiontext (7.0.4)
42
+ actionpack (= 7.0.4)
43
+ activerecord (= 7.0.4)
44
+ activestorage (= 7.0.4)
45
+ activesupport (= 7.0.4)
46
+ globalid (>= 0.6.0)
47
+ nokogiri (>= 1.8.5)
48
+ actionview (7.0.4)
49
+ activesupport (= 7.0.4)
50
+ builder (~> 3.1)
51
+ erubi (~> 1.4)
52
+ rails-dom-testing (~> 2.0)
53
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
54
+ activejob (7.0.4)
55
+ activesupport (= 7.0.4)
56
+ globalid (>= 0.3.6)
57
+ activemodel (7.0.4)
58
+ activesupport (= 7.0.4)
59
+ activerecord (7.0.4)
60
+ activemodel (= 7.0.4)
61
+ activesupport (= 7.0.4)
62
+ activestorage (7.0.4)
63
+ actionpack (= 7.0.4)
64
+ activejob (= 7.0.4)
65
+ activerecord (= 7.0.4)
66
+ activesupport (= 7.0.4)
67
+ marcel (~> 1.0)
68
+ mini_mime (>= 1.1.0)
69
+ activesupport (7.0.4)
70
+ concurrent-ruby (~> 1.0, >= 1.0.2)
71
+ i18n (>= 1.6, < 2)
72
+ minitest (>= 5.1)
73
+ tzinfo (~> 2.0)
74
+ builder (3.2.4)
75
+ concurrent-ruby (1.1.10)
76
+ crass (1.0.6)
9
77
  diff-lcs (1.5.0)
78
+ digest (3.1.0)
79
+ erubi (1.11.0)
80
+ globalid (1.0.0)
81
+ activesupport (>= 5.0)
82
+ i18n (1.12.0)
83
+ concurrent-ruby (~> 1.0)
84
+ loofah (2.19.0)
85
+ crass (~> 1.0.2)
86
+ nokogiri (>= 1.5.9)
87
+ mail (2.7.1)
88
+ mini_mime (>= 0.1.1)
89
+ marcel (1.0.2)
90
+ method_source (1.0.0)
91
+ mini_mime (1.1.2)
92
+ mini_portile2 (2.8.0)
93
+ minitest (5.16.3)
94
+ net-imap (0.2.3)
95
+ digest
96
+ net-protocol
97
+ strscan
98
+ net-pop (0.1.1)
99
+ digest
100
+ net-protocol
101
+ timeout
102
+ net-protocol (0.1.3)
103
+ timeout
104
+ net-smtp (0.3.1)
105
+ digest
106
+ net-protocol
107
+ timeout
108
+ nio4r (2.5.8)
109
+ nokogiri (1.13.8)
110
+ mini_portile2 (~> 2.8.0)
111
+ racc (~> 1.4)
112
+ racc (1.6.0)
113
+ rack (2.2.4)
114
+ rack-test (2.0.2)
115
+ rack (>= 1.3)
116
+ rails (7.0.4)
117
+ actioncable (= 7.0.4)
118
+ actionmailbox (= 7.0.4)
119
+ actionmailer (= 7.0.4)
120
+ actionpack (= 7.0.4)
121
+ actiontext (= 7.0.4)
122
+ actionview (= 7.0.4)
123
+ activejob (= 7.0.4)
124
+ activemodel (= 7.0.4)
125
+ activerecord (= 7.0.4)
126
+ activestorage (= 7.0.4)
127
+ activesupport (= 7.0.4)
128
+ bundler (>= 1.15.0)
129
+ railties (= 7.0.4)
130
+ rails-dom-testing (2.0.3)
131
+ activesupport (>= 4.2.0)
132
+ nokogiri (>= 1.6)
133
+ rails-html-sanitizer (1.4.3)
134
+ loofah (~> 2.3)
135
+ railties (7.0.4)
136
+ actionpack (= 7.0.4)
137
+ activesupport (= 7.0.4)
138
+ method_source
139
+ rake (>= 12.2)
140
+ thor (~> 1.0)
141
+ zeitwerk (~> 2.5)
10
142
  rake (13.0.6)
11
143
  rake-compiler (1.2.0)
12
144
  rake
@@ -23,12 +155,22 @@ GEM
23
155
  diff-lcs (>= 1.2.0, < 2.0)
24
156
  rspec-support (~> 3.11.0)
25
157
  rspec-support (3.11.0)
158
+ strscan (3.0.4)
159
+ thor (1.2.1)
160
+ timeout (0.3.0)
161
+ tzinfo (2.0.5)
162
+ concurrent-ruby (~> 1.0)
163
+ websocket-driver (0.7.5)
164
+ websocket-extensions (>= 0.1.0)
165
+ websocket-extensions (0.1.5)
166
+ zeitwerk (2.6.0)
26
167
 
27
168
  PLATFORMS
28
169
  x86_64-linux
29
170
 
30
171
  DEPENDENCIES
31
172
  im!
173
+ rails
32
174
  rake (~> 13.0)
33
175
  rake-compiler
34
176
  rspec (~> 3.0)
data/lib/im/autoload.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Im
4
4
  module Autoload
5
5
  def autoload(name, path)
6
- Im.autoloads[path] = Im.current_import if Im.current_import
6
+ Im.autoloads[path] = Im.current_import if Im.importing?
7
7
  super(name, path)
8
8
  end
9
9
  end
data/lib/im/constants.rb CHANGED
@@ -97,6 +97,7 @@ module Im
97
97
  :UnboundMethod,
98
98
  :UncaughtThrowError,
99
99
  :UnicodeNormalize,
100
+ :URI,
100
101
  :Warning,
101
102
  :ZeroDivisionError,
102
103
  ]
data/lib/im/kernel.rb CHANGED
@@ -5,31 +5,38 @@ module Kernel
5
5
 
6
6
  def require(path)
7
7
  if Im.autoloads.key?(path)
8
- return Im.with_context(Im.autoloads.delete(path)) do |_context|
8
+ return Im.with_import(Im.autoloads.delete(path)) do |_context|
9
9
  !!Im.import(path)
10
10
  end
11
11
  end
12
12
 
13
+ if Im.importing? && (resolved = $LOAD_PATH.resolve_feature_path(path))
14
+ resolved_path = resolved[1]
15
+ Im.registry[resolved_path] ||= Im::Dependency.new(resolved_path, Im.current_import)
16
+ end
17
+
13
18
  loaded = im_original_require(path)
14
- return loaded unless Im.current_import
19
+ return loaded unless Im.importing?
20
+
21
+ if resolved
22
+ dependency = Im.registry[resolved_path]
23
+
24
+ if loaded && Im.registry.key?(location = caller_locations(1, 1).first.path)
25
+ Im.registry[location].dependencies << dependency
26
+ end
15
27
 
16
- if resolved = $LOAD_PATH.resolve_feature_path(path)
17
- if Im.registry.key?(resolved_path = resolved[1])
18
- _, modules = Im.registry[resolved_path]
28
+ dependency.dependencies.each { |d| require d.path }
19
29
 
20
- modules.each do |m|
21
- next unless name = m.name
30
+ dependency.modules.each do |m|
31
+ name = m.name
22
32
 
23
- # Do not assign constants that are aliased to root namespace
24
- root = name.split("::", 2)[0]
25
- next if Object.const_defined?(root) &&
26
- Im.current_import.const_defined?(root, false) &&
27
- Object.const_get(root) == Im.current_import.const_get(root)
33
+ # Do not assign constants that are aliased to root namespace
34
+ root = name.split("::", 2)[0]
35
+ next if Object.const_defined?(root) &&
36
+ Im.current_import.const_defined?(root, false) &&
37
+ Object.const_get(root) == Im.current_import.const_get(root)
28
38
 
29
- Im.current_import.const_set(name, m) unless Im.current_import.const_defined?(name, false)
30
- end
31
- else
32
- Im.registry[resolved_path] ||= [Im.current_import, []] if Im.current_import
39
+ Im.current_import.const_set(name, m) unless Im.current_import.const_defined?(name, false)
33
40
  end
34
41
  end
35
42
 
data/lib/im/module.rb CHANGED
@@ -2,7 +2,7 @@ class Module
2
2
  alias_method :im_original_autoload, :autoload
3
3
 
4
4
  def autoload(name, path)
5
- Im.autoloads[path] = Im.current_import if Im.current_import
5
+ Im.autoloads[path] = Im.current_import if Im.importing?
6
6
  im_original_autoload(name, path)
7
7
  end
8
8
  end
data/lib/im/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Im
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.4"
5
5
  end
data/lib/im.rb CHANGED
@@ -7,14 +7,20 @@ module Im
7
7
 
8
8
  class << self
9
9
  attr_reader :current_import
10
- attr_reader :tracer
11
10
 
12
- def with_context(context)
13
- original_context = current_import
14
- @current_import = context
15
- yield(context)
11
+ def with_import(import)
12
+ original_import = current_import
13
+ @current_import = import
14
+
15
+ unless tracer_originally_enabled = @tracer.enabled?
16
+ @tracer.enable
17
+ end
18
+
19
+ yield(import)
20
+
16
21
  ensure
17
- @current_import = original_context
22
+ @current_import = original_import
23
+ @tracer.disable unless tracer_originally_enabled
18
24
  end
19
25
 
20
26
  def registry
@@ -24,6 +30,10 @@ module Im
24
30
  def autoloads
25
31
  @autoloads ||= {}
26
32
  end
33
+
34
+ def importing?
35
+ !!Im.current_import
36
+ end
27
37
  end
28
38
 
29
39
  class Import < Module
@@ -40,6 +50,12 @@ module Im
40
50
  end
41
51
  end
42
52
 
53
+ Dependency = Struct.new(:path, :import, :modules, :dependencies) do
54
+ def initialize(path, import, modules = [], dependencies = [])
55
+ super(path, import, modules, dependencies)
56
+ end
57
+ end
58
+
43
59
  def import(path)
44
60
  if resolved = $LOAD_PATH.resolve_feature_path(path)
45
61
  resolved_path = resolved[1]
@@ -54,23 +70,30 @@ module Im
54
70
 
55
71
  $LOADED_FEATURES << resolved_path
56
72
 
57
- context = Im.current_import || Import.new(path)
58
-
59
- Im.with_context(context) do
60
- originally_enabled = Im.tracer.enabled?
61
- Im.tracer.enable
62
- load resolved_path, context
63
- Im.tracer.disable unless originally_enabled
73
+ import = Im.current_import || Import.new(path)
74
+ (Im.registry[resolved_path] ||= Dependency.new(resolved_path, import)).tap do
75
+ Im.with_import(import) do
76
+ load resolved_path, import
77
+ end
64
78
  end
65
-
66
- Im.registry[resolved_path] ||= [context, []]
67
- end[0]
79
+ end&.import
68
80
  end
69
81
 
82
+ # This is a hack to catch references to top-level constants (`::Foo`) and, if
83
+ # the calling line is a key in the Im registry, replace the toplevel constant
84
+ # reference with its corresponding constant under the import namespace.
85
+ #
86
+ # By doing this, a reference to `::Foo` in an imported file will resolve to
87
+ # `mod::Foo`, where `mod` is the import module. Ideally this should
88
+ # ultimately happen at the Ruby implementation level.
70
89
  module RootNamespaceRedirect
71
90
  def const_missing(name)
72
- if Im.current_import && Im.current_import.const_defined?(name)
73
- Im.current_import.const_get(name)
91
+
92
+ # Take top five locations to allow for other `const_missing` overrides
93
+ # in the backtrace. If there are more than five, then this will no longer
94
+ # work. This is currently very inefficient.
95
+ if location = caller_locations(1, 5).find { |l| Im.registry.key?(l.path) }
96
+ Im.registry[location.path].import.const_get(name)
74
97
  else
75
98
  super
76
99
  end
@@ -78,12 +101,15 @@ module Im
78
101
  end
79
102
 
80
103
  @tracer = TracePoint.new(:class) do |event|
104
+ next unless (name = event.self.name)
105
+ next if Im::CONSTANTS.include?(name.to_sym)
106
+
81
107
  if resolved = $LOAD_PATH.resolve_feature_path(event.path)
82
108
  resolved_path = resolved[1]
83
109
  if Im.registry.key?(resolved_path)
84
- (Im.registry[resolved_path][1] << event.self).uniq!
110
+ (Im.registry[resolved_path].modules << event.self).uniq!
85
111
  else
86
- Im.registry[resolved_path] = [Im.current_import, [event.self]]
112
+ Im.registry[resolved_path] = Dependency.new(resolved_path, Im.current_import, [event.self])
87
113
  end
88
114
  end
89
115
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: im
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Salzberg
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-16 00:00:00.000000000 Z
11
+ date: 2022-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake