From e5fdc2ac331b153a662e67ef797a3c9291f4185b Mon Sep 17 00:00:00 2001 From: Ufuk Kayserilioglu Date: Sat, 17 Sep 2022 00:44:08 +0300 Subject: [PATCH] Start matching pathname directory prefixes more rigorously Fixes #1174 The simplistic `start_with?` check was not sufficient to match that a given file/folder was under a given folder, since we were not explicitly checking for full folder name matches. For example, if `path = "/foo/bar-gem/baz"` and `folder = "/foo/bar"`, then `path.start_with?(folder)` would return `true`, but `path` is not under the `folder` directory. This commit fixes the problem by matching `folder` to any of the parent directories of `path` by using the `Pathname#ascend` method to get all parent directory prefixes of a `path`. --- lib/tapioca/gemfile.rb | 2 +- lib/tapioca/helpers/gem_helper.rb | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/tapioca/gemfile.rb b/lib/tapioca/gemfile.rb index 81ce04f539..b83dbb69ce 100644 --- a/lib/tapioca/gemfile.rb +++ b/lib/tapioca/gemfile.rb @@ -201,7 +201,7 @@ def contains_path?(path) if default_gem? files.any? { |file| file.to_s == to_realpath(path) } else - to_realpath(path).start_with?(full_gem_path) || has_parent_gemspec?(path) + path_in_dir?(to_realpath(path), full_gem_path) || has_parent_gemspec?(path) end end diff --git a/lib/tapioca/helpers/gem_helper.rb b/lib/tapioca/helpers/gem_helper.rb index 3b1d0a8617..120315dfe2 100644 --- a/lib/tapioca/helpers/gem_helper.rb +++ b/lib/tapioca/helpers/gem_helper.rb @@ -8,12 +8,13 @@ module GemHelper sig { params(gemfile_dir: String, full_gem_path: String).returns(T::Boolean) } def gem_in_app_dir?(gemfile_dir, full_gem_path) !gem_in_bundle_path?(to_realpath(full_gem_path)) && - full_gem_path.start_with?(to_realpath(gemfile_dir)) + path_in_dir?(to_realpath(gemfile_dir), full_gem_path) end sig { params(full_gem_path: String).returns(T::Boolean) } def gem_in_bundle_path?(full_gem_path) - full_gem_path.start_with?(Bundler.bundle_path.to_s, Bundler.app_cache.to_s) + path_in_dir?(full_gem_path, Bundler.bundle_path) || + path_in_dir?(full_gem_path, Bundler.app_cache) end sig { params(path: T.any(String, Pathname)).returns(String) } @@ -22,5 +23,14 @@ def to_realpath(path) path_string = File.realpath(path_string) if File.exist?(path_string) path_string end + + private + + sig { params(path: T.any(Pathname, String), dir: T.any(Pathname, String)).returns(T::Boolean) } + def path_in_dir?(path, dir) + dir = Pathname.new(dir) + path = Pathname.new(path) + path.ascend.any?(dir) + end end end