Module: VirtFS::Kernel

Defined in:
lib/virtfs/kernel.rb

Overview

rubocop:disable ModuleLength

Class Method Summary collapse

Class Method Details

.already_loaded(canonical_name) ⇒ Object



137
138
139
# File 'lib/virtfs/kernel.rb', line 137

def self.already_loaded(canonical_name)
  $LOADED_FEATURES.include?(canonical_name.to_path)
end

.canonical_path(path) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/virtfs/kernel.rb', line 120

def self.canonical_path(path)
  has_ext = path.extname != ""
  return path if path.absolute?
  $LOAD_PATH.each do |dir|
    full_path = path.expand_path(dir)
    if has_ext
      return full_path if full_path.file?
    else
      %w(.rb .so .o .dll).each do |ext|
        ext_path = full_path.sub_ext(ext)
        return ext_path if ext_path.file?
      end
    end
  end
  nil
end

.disableObject



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/virtfs/kernel.rb', line 83

def self.disable
  @kernel_mutex.synchronize do
    return false unless @enabled

    ::Kernel.module_exec(@rubygems_active) do |gems_active|
      if gems_active
        alias_method :gem_original_require, :virtfs_original_require
      else
        alias_method :require, :virtfs_original_require
      end

      alias_method :load, :virtfs_original_load
    end
    @enabled = false
  end
  true
end

.enableObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/virtfs/kernel.rb', line 63

def self.enable
  @kernel_mutex.synchronize do
    return false if @enabled

    inject unless @injected

    ::Kernel.module_exec(@rubygems_active) do |gems_active|
      if gems_active
        alias_method :gem_original_require, :virtfs_require
      else
        alias_method :require, :virtfs_require
      end

      alias_method :load, :virtfs_load
    end
    @enabled = true
  end
  true
end

.eval_file(file_path, wrap) ⇒ Object



141
142
143
144
# File 'lib/virtfs/kernel.rb', line 141

def self.eval_file(file_path, wrap)
  eval_binding = wrap ? Module.new.send(:binding) : TOPLEVEL_BINDING
  eval(file_path.read, eval_binding, file_path.to_path) # rubocop:disable Lint/Eval
end

.injectObject

rubocop:disable AbcSize



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/virtfs/kernel.rb', line 7

def self.inject # rubocop:disable AbcSize
  @kernel_mutex.synchronize do
    return false if @injected

    #
    # If the 'require' method is implemented in ruby (method(:require).source_location != nil)
    # and 'gem_original_require' is defined, then rubygems is active. Replace gem_original_require
    # with our VirtFS aware implementation of require - the rubygems require will call us.
    #
    # If the 'require' method is implemented in 'C' (method(:require).source_location == nil)
    # then rubygems is not active (even if 'gem_original_require' is defined). Replace 'require'
    # with our VirtFS aware implementation of require
    #
    @rubygems_active = method(:require).source_location && private_method_defined?(:gem_original_require)

    ::Kernel.module_exec(@rubygems_active) do |gems_active|
      if gems_active
        alias_method :virtfs_original_require, :gem_original_require
      else
        alias_method :virtfs_original_require, :require
      end
      private :virtfs_original_require

      alias_method :virtfs_original_load, :load
      private :virtfs_original_load

      define_method(:virtfs_require) do |file_name|
        VirtFS::Kernel.virtfs_require(file_name)
      end
      private :virtfs_require

      define_method(:virtfs_load) do |file_name, wrap = false|
        VirtFS::Kernel.virtfs_load(file_name, wrap)
      end
      private :virtfs_load
    end
    @injected = true
  end
end

.virtfs_load(file_name, wrap) ⇒ Object

Raises:

  • (LoadError)


101
102
103
104
105
106
107
108
# File 'lib/virtfs/kernel.rb', line 101

def self.virtfs_load(file_name, wrap)
  file_path = ::Pathname.new(file_name)
  return virtfs_original_load(file_name, wrap) unless file_path.extname == ".rb"
  file_path = canonical_path(file_path)
  raise LoadError, "cannot load such file -- #{file_name}" unless file_path
  eval_file(file_path, wrap)
  true
end

.virtfs_require(lib_name) ⇒ Object

Raises:

  • (LoadError)


110
111
112
113
114
115
116
117
118
# File 'lib/virtfs/kernel.rb', line 110

def self.virtfs_require(lib_name)
  lib_path = canonical_path(::Pathname.new(lib_name))
  raise LoadError, "cannot load such file -- #{lib_name}" unless lib_path
  return virtfs_original_require(lib_name) unless lib_path.extname == ".rb"
  return false if already_loaded(lib_path)
  eval_file(lib_path, false)
  $LOADED_FEATURES << lib_path.to_path
  true
end

.withdrawObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/virtfs/kernel.rb', line 47

def self.withdraw
  @kernel_mutex.synchronize do
    return false unless @injected
    raise "Cannot withdraw while VirtFS::Kernel is enabled" if @enabled

    ::Kernel.module_eval do
      remove_method :virtfs_original_require
      remove_method :virtfs_original_load
      remove_method :virtfs_require
      remove_method :virtfs_load
    end
    @injected = false
  end
  true
end