class Bootsnap::LoadPathCache::Path
Constants
- RUBY_LIBDIR
Built-in ruby lib stuff doesn’t change, but things can occasionally be installed into sitedir, which generally lives under rubylibdir.
- RUBY_SITEDIR
- STABLE
a
Pathcan be either stable of volatile, depending on how frequently we expect its contents may change. Stable paths aren’t rescanned nearly as often.- VOLATILE
Attributes
Public Class Methods
# File lib/bootsnap/load_path_cache/path.rb, line 24 def initialize(path, real: false) @path = path.to_s.freeze @real = real end
Public Instance Methods
Return a list of all the requirable files of this Path.
# File lib/bootsnap/load_path_cache/path.rb, line 58 def entries(store) if stable? # the cached_mtime field is unused for 'stable' paths, but is # set to zero anyway, just in case we change the stability heuristics. _, entries, = store.get(expanded_path) return entries if entries # cache hit entries = PathScanner.call(expanded_path) store.set(expanded_path, [0, entries]) return entries end cached_mtime, entries = store.get(expanded_path) current_mtime = latest_mtime(expanded_path, entries || []) return [] if current_mtime == -1 # path does not exist return entries if cached_mtime == current_mtime entries = PathScanner.call(expanded_path) store.set(expanded_path, [current_mtime, entries]) entries end
# File lib/bootsnap/load_path_cache/path.rb, line 81 def expanded_path if @real path else @expanded_path ||= File.expand_path(path).freeze end end
True if the path exists, but represents a non-directory object
# File lib/bootsnap/load_path_cache/path.rb, line 47 def non_directory? !File.stat(path).directory? rescue Errno::ENOENT, Errno::ENOTDIR, Errno::EINVAL false end
# File lib/bootsnap/load_path_cache/path.rb, line 53 def relative? !path.start_with?(SLASH) end
A path is considered ‘stable’ if it is part of a Gem.path or the ruby distribution. When adding or removing files in these paths, the cache must be cleared before the change will be noticed.
# File lib/bootsnap/load_path_cache/path.rb, line 11 def stable? stability == STABLE end
# File lib/bootsnap/load_path_cache/path.rb, line 29 def to_realpath return self if @real realpath = begin File.realpath(path) rescue Errno::ENOENT return self end if realpath == path @real = true self else Path.new(realpath, real: true) end end
A path is considered volatile if it doesn’t live under a Gem.path or the ruby distribution root. These paths are scanned for new additions more frequently.
# File lib/bootsnap/load_path_cache/path.rb, line 18 def volatile? stability == VOLATILE end
Private Instance Methods
last time a directory was modified in this subtree. dirs should be a list of relative paths to directories under path. e.g. for /a/b and /a/b/c, pass (‘/a/b’, [‘c’])
# File lib/bootsnap/load_path_cache/path.rb, line 94 def latest_mtime(root_path, entries) max = begin File.mtime(root_path).to_i rescue Errno::ENOENT, Errno::ENOTDIR, Errno::EINVAL -1 end visited = {"." => true} entries.each do |relpath| dirname = File.dirname(relpath) visited[dirname] ||= begin begin current = File.mtime(File.join(root_path, dirname)).to_i max = current if current > max rescue Errno::ENOENT, Errno::ENOTDIR, Errno::EINVAL # ignore end true end end max end
# File lib/bootsnap/load_path_cache/path.rb, line 130 def stability @stability ||= if Gem.path.detect { |p| expanded_path.start_with?(p.to_s) } STABLE elsif Bootsnap.bundler? && expanded_path.start_with?(Bundler.bundle_path.to_s) STABLE elsif expanded_path.start_with?(RUBY_LIBDIR) && !expanded_path.start_with?(RUBY_SITEDIR) STABLE else VOLATILE end end