class Bootsnap::LoadPathCache::Cache
def find(feature, try_extensions: true)
Try to resolve this feature to an absolute path without traversing the
def find(feature, try_extensions: true) reinitialize if (@has_relative_paths && dir_changed?) || stale? feature = feature.to_s.freeze return feature if Bootsnap.absolute_path?(feature) if feature.start_with?("./", "../") return try_extensions ? expand_path(feature) : File.expand_path(feature).freeze end @mutex.synchronize do x = search_index(feature, try_extensions: try_extensions) return x if x return unless try_extensions # Ruby has some built-in features that require lies about. # For example, 'enumerator' is built in. If you require it, ruby # returns false as if it were already loaded; however, there is no # file to find on disk. We've pre-built a list of these, and we # return false if any of them is loaded. return false if BUILTIN_FEATURES.key?(feature) # The feature wasn't found on our preliminary search through the index. # We resolve this differently depending on what the extension was. case File.extname(feature) # If the extension was one of the ones we explicitly cache (.rb and the # native dynamic extension, e.g. .bundle or .so), we know it was a # failure and there's nothing more we can do to find the file. # no extension, .rb, (.bundle or .so) when "", *CACHED_EXTENSIONS nil # Ruby allows specifying native extensions as '.so' even when DLEXT # is '.bundle'. This is where we handle that case. when DOT_SO x = search_index(feature[0..-4] + DLEXT) return x if x if DLEXT2 x = search_index(feature[0..-4] + DLEXT2) return x if x end else # other, unknown extension. For example, `.rake`. Since we haven't # cached these, we legitimately need to run the load path search. return FALLBACK_SCAN end end # In development mode, we don't want to confidently return failures for # cases where the file doesn't appear to be on the load path. We should # be able to detect newly-created files without rebooting the # application. return FALLBACK_SCAN if @development_mode end