Module: RequireHooks
- Defined in:
- lib/require-hooks/api.rb,
lib/require-hooks/iseq.rb,
lib/require-hooks/version.rb,
lib/require-hooks/mode/bootsnap.rb,
lib/require-hooks/mode/load_iseq.rb,
lib/require-hooks/mode/kernel_patch.rb
Defined Under Namespace
Modules: Bootsnap, Iseq, KernelPatch, LoadIseq Classes: Context
Constant Summary collapse
- VERSION =
"0.4.0"- EMPTY_ISEQ =
RubyVM::InstructionSequence.compile("").freeze
- @@default_context =
Context.new
- @@noop_context =
Context.new
- @@contexts =
{}
Class Attribute Summary collapse
-
.print_warnings ⇒ Object
Returns the value of attribute print_warnings.
Class Method Summary collapse
-
.around_load(patterns: nil, exclude_patterns: nil, &block) ⇒ Object
Define a block to wrap the code loading.
- .context_for(path) ⇒ Object
- .contexts ⇒ Object
-
.hijack_load(patterns: nil, exclude_patterns: nil, &block) ⇒ Object
This hook should be used to manually compile byte code to be loaded by the VM.
-
.setup_path_coverage(path, contents = nil) ⇒ Object
Hack to enable coverage for hooked files.
-
.source_transform(patterns: nil, exclude_patterns: nil, &block) ⇒ Object
Define hooks to perform source-to-source transformations.
Class Attribute Details
.print_warnings ⇒ Object
Returns the value of attribute print_warnings.
93 94 95 |
# File 'lib/require-hooks/api.rb', line 93 def print_warnings @print_warnings end |
Class Method Details
.around_load(patterns: nil, exclude_patterns: nil, &block) ⇒ Object
Define a block to wrap the code loading. The return value MUST be a result of calling the passed block. For example, you can use such hooks for instrumentation, debugging purposes.
RequireHooks.around_load do |path, &block|
puts "Loading #{path}"
block.call.tap { puts "Loaded #{path}" }
end
103 104 105 |
# File 'lib/require-hooks/api.rb', line 103 def around_load(patterns: nil, exclude_patterns: nil, &block) register_hook(:around_load, block, patterns: patterns, exclude_patterns: exclude_patterns) end |
.context_for(path) ⇒ Object
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/require-hooks/api.rb', line 139 def context_for(path) # Fast-track in case we have just a single non-global context defined if @@default_context return @@default_context if @@default_context.match?(path) return @@noop_context end matching = @@contexts.values.select { |ctx| ctx.match?(path) } return matching[0] || @@noop_context if matching.size < 2 ctx = Context.new matching.each { |mctx| ctx.merge!(mctx) } ctx end |
.contexts ⇒ Object
168 169 170 |
# File 'lib/require-hooks/api.rb', line 168 def contexts @@contexts end |
.hijack_load(patterns: nil, exclude_patterns: nil, &block) ⇒ Object
This hook should be used to manually compile byte code to be loaded by the VM. The arguments are (path, source = nil), where source is only defined if transformations took place. Otherwise, you MUST read the source code from the file yourself.
The return value MUST be either nil (continue to the next hook or default behavior) or a platform-specific bytecode object (e.g., RubyVM::InstructionSequence).
RequireHooks.hijack_load do |path, source|
source ||= File.read(path)
if defined?(RubyVM::InstructionSequence)
RubyVM::InstructionSequence.compile(source)
elsif defined?(JRUBY_VERSION)
JRuby.compile(source)
end
end
135 136 137 |
# File 'lib/require-hooks/api.rb', line 135 def hijack_load(patterns: nil, exclude_patterns: nil, &block) register_hook(:hijack_load, block, patterns: patterns, exclude_patterns: exclude_patterns) end |
.setup_path_coverage(path, contents = nil) ⇒ Object
Hack to enable coverage for hooked files. Requires eval coverage to be on. See bugs.ruby-lang.org/issues/22018 (github.com/ruby/ruby/pull/16805)
160 161 162 163 164 165 166 |
# File 'lib/require-hooks/api.rb', line 160 def setup_path_coverage(path, contents = nil) return unless defined?(Coverage) && Coverage.running? return unless eval_coverage_enabled? Kernel.eval("\n" * (contents || File.read(path)).lines.size, TOPLEVEL_BINDING, path, 1) # rubocop:disable Style/EvalWithLocation,Security/Eval end |
.source_transform(patterns: nil, exclude_patterns: nil, &block) ⇒ Object
Define hooks to perform source-to-source transformations. The return value MUST be either String (new source code) or nil (indicating that no transformations were performed).
NOTE: The second argument (‘source`) MAY be nil, indicating that no transformer tried to transform the source code.
For example, you can prepend each file with ‘# frozen_string_literal: true` pragma:
RequireHooks.source_transform do |path, source|
"# frozen_string_literal: true\n#{source}"
end
117 118 119 |
# File 'lib/require-hooks/api.rb', line 117 def source_transform(patterns: nil, exclude_patterns: nil, &block) register_hook(:source_transform, block, patterns: patterns, exclude_patterns: exclude_patterns) end |