diff --git a/CHANGELOG.md b/CHANGELOG.md index ba35ccac..b11e190e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Unreleased +* Ignore absolute paths in the loaded feature index. (#385) + This fixes a compatibility issue with Zeitwerk when Zeitwerk is loaded before bootsnap. It also should + reduce the memory usage and improve load performance of Zeitwerk managed files. + * Automatically invalidate the load path cache whenever the Ruby version change. (#387) This is to avoid issues in case the same installation path is re-used for subsequent ruby patch releases. diff --git a/lib/bootsnap.rb b/lib/bootsnap.rb index 06a32e85..842973d9 100644 --- a/lib/bootsnap.rb +++ b/lib/bootsnap.rb @@ -123,4 +123,14 @@ def self.default_setup end end end + + if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ + def self.absolute_path?(path) + path[1] == ':' + end + else + def self.absolute_path?(path) + path.start_with?('/') + end + end end diff --git a/lib/bootsnap/load_path_cache/cache.rb b/lib/bootsnap/load_path_cache/cache.rb index b1e82328..33ea1967 100644 --- a/lib/bootsnap/load_path_cache/cache.rb +++ b/lib/bootsnap/load_path_cache/cache.rb @@ -48,7 +48,7 @@ def find(feature, try_extensions: true) reinitialize if (@has_relative_paths && dir_changed?) || stale? feature = feature.to_s.freeze - return feature if absolute_path?(feature) + return feature if Bootsnap.absolute_path?(feature) if feature.start_with?('./', '../') return try_extensions ? expand_path(feature) : File.expand_path(feature).freeze @@ -98,16 +98,6 @@ def find(feature, try_extensions: true) raise(LoadPathCache::FallbackScan, '', []) if @development_mode end - if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ - def absolute_path?(path) - path[1] == ':' - end - else - def absolute_path?(path) - path.start_with?(SLASH) - end - end - def unshift_paths(sender, *paths) return unless sender == @path_obj @mutex.synchronize { unshift_paths_locked(*paths) } diff --git a/lib/bootsnap/load_path_cache/loaded_features_index.rb b/lib/bootsnap/load_path_cache/loaded_features_index.rb index 769093fe..12cc0fb1 100644 --- a/lib/bootsnap/load_path_cache/loaded_features_index.rb +++ b/lib/bootsnap/load_path_cache/loaded_features_index.rb @@ -83,6 +83,11 @@ def key?(feature) # 2. Inspect $LOADED_FEATURES upon return from yield to find the matching # entry. def register(short, long = nil) + # Absolute paths are not a concern. + if Bootsnap.absolute_path?(short.to_s) + return yield + end + if long.nil? len = $LOADED_FEATURES.size ret = yield diff --git a/test/load_path_cache/loaded_features_index_test.rb b/test/load_path_cache/loaded_features_index_test.rb index 5e5f02d1..ea8da1c2 100644 --- a/test/load_path_cache/loaded_features_index_test.rb +++ b/test/load_path_cache/loaded_features_index_test.rb @@ -136,11 +136,23 @@ def test_derives_initial_state_from_loaded_features end def test_works_with_pathname - path = '/tmp/bundler.rb' + path = 'bundler.rb' pathname = Pathname.new(path) @index.register(pathname, path) { true } assert(@index.key?(pathname)) end + + def test_ignores_absolute_paths + path = "#{Dir.mktmpdir}/bundler.rb" + @index.register(path) { true } + refute(@index.key?(path)) + + path = "#{Dir.mktmpdir}/bundler.rb" + pathname = Pathname.new(path) + @index.register(pathname, path) { true } + refute(@index.key?(path)) + refute(@index.key?(pathname)) + end end end end