Class: DeepCover::CustomRequirer
- Inherits:
-
Object
- Object
- DeepCover::CustomRequirer
- Defined in:
- lib/deep_cover/custom_requirer.rb
Defined Under Namespace
Classes: LoadPathsSubset
Instance Attribute Summary collapse
-
#filter ⇒ Object
readonly
Returns the value of attribute filter.
-
#load_paths ⇒ Object
readonly
Returns the value of attribute load_paths.
-
#loaded_features ⇒ Object
readonly
Returns the value of attribute loaded_features.
Instance Method Summary collapse
-
#initialize(load_paths: $LOAD_PATH, loaded_features: $LOADED_FEATURES, lookup_paths: nil, &filter) ⇒ CustomRequirer
constructor
A new instance of CustomRequirer.
-
#load(path) ⇒ Object
Homemade #load to be able to instrument the code before it gets executed.
-
#require(path) ⇒ Object
Homemade #require to be able to instrument the code before it gets executed.
-
#resolve_path(path) ⇒ Object
Returns a path to an existing file or nil if none can be found.
Constructor Details
#initialize(load_paths: $LOAD_PATH, loaded_features: $LOADED_FEATURES, lookup_paths: nil, &filter) ⇒ CustomRequirer
Returns a new instance of CustomRequirer.
47 48 49 50 51 52 53 54 |
# File 'lib/deep_cover/custom_requirer.rb', line 47 def initialize(load_paths: $LOAD_PATH, loaded_features: $LOADED_FEATURES, lookup_paths: nil, &filter) @load_paths = load_paths lookup_paths ||= Dir.getwd lookup_paths = Array(lookup_paths) @load_paths_subset = LoadPathsSubset.new(load_paths: load_paths, lookup_paths: lookup_paths) unless lookup_paths.include? '/' @loaded_features = loaded_features @filter = filter end |
Instance Attribute Details
#filter ⇒ Object (readonly)
Returns the value of attribute filter.
46 47 48 |
# File 'lib/deep_cover/custom_requirer.rb', line 46 def filter @filter end |
#load_paths ⇒ Object (readonly)
Returns the value of attribute load_paths.
46 47 48 |
# File 'lib/deep_cover/custom_requirer.rb', line 46 def load_paths @load_paths end |
#loaded_features ⇒ Object (readonly)
Returns the value of attribute loaded_features.
46 47 48 |
# File 'lib/deep_cover/custom_requirer.rb', line 46 def loaded_features @loaded_features end |
Instance Method Details
#load(path) ⇒ Object
Homemade #load to be able to instrument the code before it gets executed. Note, this doesn’t support the ‘wrap` parameter that ruby’s #load has. Same return/throw as CustomRequirer#require, except: Cannot return false since #load doesn’t care about a file already being executed.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/deep_cover/custom_requirer.rb', line 111 def load(path) found_path = resolve_path(path) if found_path.nil? # #load has a final fallback of always trying relative to current work directory of process possible_path = File.absolute_path(path) found_path = possible_path if (@load_paths_subset || File).exist?(possible_path) end throw :use_fallback, :not_found unless found_path cover_and_execute(found_path) true end |
#require(path) ⇒ Object
Homemade #require to be able to instrument the code before it gets executed. Returns true when everything went right. (Same as regular ruby) Returns false when the found file was already required. (Same as regular ruby) Throws :use_fallback in case caller should delegate to the default #require. Reasons given could be:
- :not_found if the file couldn't be found.
- :cover_failed if DeepCover couldn't apply instrumentation the file found.
- :not_supported for files that are not supported (such as ike .so files)
- :skipped if the filter block returned `true`
Exceptions raised by the required code bubble up as normal.
It is *NOT* recommended to simply delegate to the default #require, since it
might not be safe to run part of the code again.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/deep_cover/custom_requirer.rb', line 88 def require(path) ext = File.extname(path) throw :use_fallback, :not_supported if ext == '.so' path += '.rb' if ext != '.rb' return false if @loaded_features.include?(path) found_path = resolve_path(path) throw :use_fallback, :not_found unless found_path return false if @loaded_features.include?(found_path) throw :use_fallback, :skipped if filter && filter.call(found_path) cover_and_execute(found_path) @loaded_features << found_path true end |
#resolve_path(path) ⇒ Object
Returns a path to an existing file or nil if none can be found. The search follows how ruby search for files using the $LOAD_PATH
An absolute path is returned directly if it exists, otherwise nil is returned without searching anywhere else.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/deep_cover/custom_requirer.rb', line 61 def resolve_path(path) path = File.absolute_path(path) if path.start_with?('./', '../') abs_path = File.absolute_path(path) if path == abs_path path if (@load_paths_subset || File).exist?(path) else (@load_paths_subset || self).load_paths.each do |load_path| possible_path = File.absolute_path(path, load_path) return possible_path if (@load_paths_subset || File).exist?(possible_path) end nil end end |