require-hooks 0.5.0 → 0.5.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9357c7e14301ad7ab541c2e2fabbda1f03df56e748aee55245dfc44ef98519f4
4
- data.tar.gz: 87b05cf3ec16a3c9c4e9c1a46a3ec267ca03717923fe8abdccd4e46deb212791
3
+ metadata.gz: 9e75b55ac6829e71745efc569fd472288bfc17f85b569413c947f145c8f3a866
4
+ data.tar.gz: 72a6083f17c215f429b7f1ae14b637c38c613cd2f7dffe2a8ead2ce8be2de956
5
5
  SHA512:
6
- metadata.gz: a9e828449e13517a11c03d9521c4170507f08862e6a4e75fa01360a2c17191dbecfa3a745a1433bd7546f190c1599f17be7a4dc76869bbd798fd1e47e859a130
7
- data.tar.gz: e1e80635ac8c7ceb90c1580797145c3c15636d463635f3ccf57578024619af150f4dbe94eb279aff7dc62c231ed1de3733b5db3e7a1b38a21002e8ef0ca8a063
6
+ metadata.gz: ccb59bc078a1bd1b748b721427240fb136ccc269148472b4963d5db052f7696b2ba8356bb3a14228561ca4f6e3e830962f182a834d6ae0dd036d0c73faac22d8
7
+ data.tar.gz: 47cd3bc2f622f9062361099e64dd179166f2d72f02e8d1366fa548b14fd62265f1a35b4db046755b84feafc34dab3bbcaa9eb28430600da3ccb09edf2a9db5bb
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.5.1 (2026-08-26)
6
+
7
+ - Add `RequireHooks::Bootsnap.add_version_hash` for external cache inputs.
8
+
5
9
  ## 0.5.0 (2026-08-26)
6
10
 
7
11
  - Use Bootsnap compiler namespaces for cache invalidation without changing Bootsnap's cache directory.
data/README.md CHANGED
@@ -126,6 +126,14 @@ The _around load_ hooks are executed for all files independently of whether they
126
126
 
127
127
  Require Hooks separates cached instructions by hook configuration. New source transformers and hijackers invalidate affected cache entries automatically.
128
128
 
129
+ If a transform depends on an external library or configuration, add that input to the cache key:
130
+
131
+ ```ruby
132
+ RequireHooks::Bootsnap.add_version_hash { "parser-#{Parser::VERSION}-#{options_digest}" }
133
+ ```
134
+
135
+ The value can be a String or a callable that returns a String. Require Hooks hashes each contribution and combines all contributions with its hook key. The callable runs when Require Hooks computes the key, so it does not freeze the key before later hooks register.
136
+
129
137
  ## Limitations
130
138
 
131
139
  - Coverage tracking is only supported in Ruby 4.0.4+ (or 3.4.10+ for 3.4.x series); for older versions in 3.4 and 4.0 series, you can enable `eval` coverage tracking to make it work with Require Hooks (`Coverage.start(eval: true, ...)` or `SimpleCov.enable_coverage :eval`). For Ruby 3.2.x and 3.3.x, only around hooks are supported.
@@ -41,11 +41,12 @@ module RequireHooks
41
41
  # Bootsnap 1.24+ compiler wrapper. Its namespace isolates transformed ISeqs
42
42
  # without changing Bootsnap's process-wide cache directory.
43
43
  class VersionedCompiler
44
- attr_reader :namespace
44
+ attr_reader :namespace, :version_hash
45
45
 
46
- def initialize(compiler)
46
+ def initialize(compiler, version_hash)
47
47
  @compiler = compiler
48
- @namespace = "#{compiler.namespace}-require-hooks-#{RequireHooks::Bootsnap.version_hash}"
48
+ @version_hash = version_hash
49
+ @namespace = "#{compiler.namespace}-require-hooks-#{version_hash}"
49
50
  end
50
51
 
51
52
  def input_to_storage(source, path, *args)
@@ -120,11 +121,37 @@ module RequireHooks
120
121
  compiler = @original_compiler_selector&.call(path) || iseq.default_compiler
121
122
  return compiler if RequireHooks.context_for(path).empty?
122
123
 
123
- @compilers[compiler] ||= VersionedCompiler.new(compiler)
124
+ version_hash = RequireHooks::Bootsnap.version_hash
125
+ cached = @compilers[compiler]
126
+ return cached if cached&.version_hash == version_hash
127
+
128
+ @compilers[compiler] = VersionedCompiler.new(compiler, version_hash)
129
+ end
130
+
131
+ def add_version_hash(value = nil, &block)
132
+ contributor = block || value
133
+ unless contributor.is_a?(String) || contributor.respond_to?(:call)
134
+ raise ArgumentError, "version hash contribution must be a String or callable"
135
+ end
136
+
137
+ @version_hash_contributors ||= []
138
+ @version_hash_contributors << (contributor.is_a?(String) ? contributor.dup.freeze : contributor)
139
+ @compilers&.clear
140
+ contributor
124
141
  end
125
142
 
126
143
  def version_hash
127
- @version_hash ||= RequireHooks.contexts.values.map(&:to_cache_key).join("-")
144
+ return @version_hash unless @version_hash.nil?
145
+
146
+ context_keys = RequireHooks.contexts.values.map(&:to_cache_key)
147
+ contribution_keys = Array(@version_hash_contributors).map do |contributor|
148
+ value = contributor.respond_to?(:call) ? contributor.call : contributor
149
+ raise TypeError, "version hash contribution must return a String" unless value.is_a?(String)
150
+
151
+ Zlib.crc32(value).to_s
152
+ end.sort
153
+
154
+ (context_keys + contribution_keys).join("-")
128
155
  end
129
156
 
130
157
  def version_hash=(version_hash)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RequireHooks
4
- VERSION = "0.5.0"
4
+ VERSION = "0.5.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: require-hooks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev