Skip to content

Commit

Permalink
Start returning Indexables from Configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock committed Aug 29, 2023
1 parent 7147b06 commit e62652f
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 39 deletions.
42 changes: 27 additions & 15 deletions lib/ruby_indexer/lib/ruby_indexer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ def initialize

@excluded_gems = T.let(excluded_gem_names, T::Array[String])
@included_gems = T.let([], T::Array[String])
@excluded_patterns = T.let(["**/*_test.rb"], T::Array[String])
@excluded_patterns = T.let([File.join("**", "*_test.rb")], T::Array[String])
path = Bundler.settings["path"]
@excluded_patterns << "#{File.expand_path(path, Dir.pwd)}/**/*.rb" if path
@excluded_patterns << File.join(File.expand_path(path, Dir.pwd), "**", "*.rb") if path

@included_patterns = T.let(["#{Dir.pwd}/**/*.rb"], T::Array[String])
@included_patterns = T.let([File.join(Dir.pwd, "**", "*.rb")], T::Array[String])
@excluded_magic_comments = T.let(
[
"frozen_string_literal:",
Expand Down Expand Up @@ -61,28 +61,31 @@ def load_config
raise e, "Syntax error while loading .index.yml configuration: #{e.message}"
end

sig { returns(T::Array[String]) }
def files_to_index
sig { returns(T::Array[Indexable]) }
def indexables
excluded_gems = @excluded_gems - @included_gems
locked_gems = Bundler.locked_gems&.specs

# NOTE: indexing the patterns (both included and excluded) needs to happen before indexing gems, otherwise we risk
# having duplicates if BUNDLE_PATH is set to a folder inside the project structure

# Add user specified patterns
files_to_index = @included_patterns.flat_map do |pattern|
Dir.glob(pattern, File::FNM_PATHNAME | File::FNM_EXTGLOB)
indexables = @included_patterns.flat_map do |pattern|
Dir.glob(pattern, File::FNM_PATHNAME | File::FNM_EXTGLOB).map! do |path|
base_path = $LOAD_PATH.find { |load_path| path.start_with?(load_path) }
Indexable.new(base_path, path)
end
end

# Remove user specified patterns
files_to_index.reject! do |path|
indexables.reject! do |indexable|
@excluded_patterns.any? do |pattern|
File.fnmatch?(pattern, path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
File.fnmatch?(pattern, indexable.full_path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
end
end

# Add default gems to the list of files to be indexed
Dir.glob("#{RbConfig::CONFIG["rubylibdir"]}/*").each do |default_path|
Dir.glob(File.join(RbConfig::CONFIG["rubylibdir"], "*")).each do |default_path|
# The default_path might be a Ruby file or a folder with the gem's name. For example:
# bundler/
# bundler.rb
Expand All @@ -103,10 +106,14 @@ def files_to_index

if pathname.directory?
# If the default_path is a directory, we index all the Ruby files in it
files_to_index.concat(Dir.glob("#{default_path}/**/*.rb", File::FNM_PATHNAME | File::FNM_EXTGLOB))
indexables.concat(
Dir.glob(File.join(default_path, "**", "*.rb"), File::FNM_PATHNAME | File::FNM_EXTGLOB).map! do |path|
Indexable.new(RbConfig::CONFIG["rubylibdir"], path)
end,
)
else
# If the default_path is a Ruby file, we index it
files_to_index << default_path
indexables << Indexable.new(RbConfig::CONFIG["rubylibdir"], default_path)
end
end

Expand All @@ -121,15 +128,20 @@ def files_to_index
# duplicates or accidentally ignoring exclude patterns
next if spec.full_gem_path == Dir.pwd

files_to_index.concat(Dir.glob("#{spec.full_gem_path}/{#{spec.require_paths.join(",")}}/**/*.rb"))
indexables.concat(
spec.require_paths.flat_map do |require_path|
base_path = File.join(spec.full_gem_path, require_path)
Dir.glob(File.join(base_path, "**", "*.rb")).map! { |path| Indexable.new(base_path, path) }
end,
)
rescue Gem::MissingSpecError
# If a gem is scoped only to some specific platform, then its dependencies may not be installed either, but they
# are still listed in locked_gems. We can't index them because they are not installed for the platform, so we
# just ignore if they're missing
end

files_to_index.uniq!
files_to_index
indexables.uniq!
indexables
end

sig { returns(Regexp) }
Expand Down
54 changes: 30 additions & 24 deletions lib/ruby_indexer/test/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,55 +11,57 @@ def setup

def test_load_configuration_executes_configure_block
@config.load_config
files_to_index = @config.files_to_index
indexables = @config.indexables

assert(files_to_index.none? { |path| path.include?("test/fixtures") })
assert(files_to_index.none? { |path| path.include?("minitest-reporters") })
assert(files_to_index.none? { |path| path == __FILE__ })
assert(indexables.none? { |indexable| indexable.full_path.include?("test/fixtures") })
assert(indexables.none? { |indexable| indexable.full_path.include?("minitest-reporters") })
assert(indexables.none? { |indexable| indexable.full_path == __FILE__ })
end

def test_files_to_index_only_includes_gem_require_paths
def test_indexables_only_includes_gem_require_paths
@config.load_config
files_to_index = @config.files_to_index
indexables = @config.indexables

Bundler.locked_gems.specs.each do |lazy_spec|
next if lazy_spec.name == "ruby-lsp"

spec = Gem::Specification.find_by_name(lazy_spec.name)
assert(files_to_index.none? { |path| path.start_with?("#{spec.full_gem_path}/test/") })
assert(indexables.none? { |indexable| indexable.full_path.start_with?("#{spec.full_gem_path}/test/") })
rescue Gem::MissingSpecError
# Transitive dependencies might be missing when running tests on Windows
end
end

def test_files_to_index_does_not_include_default_gem_path_when_in_bundle
def test_indexables_does_not_include_default_gem_path_when_in_bundle
@config.load_config
files_to_index = @config.files_to_index
indexables = @config.indexables

assert(files_to_index.none? { |path| path.start_with?("#{RbConfig::CONFIG["rubylibdir"]}/psych") })
assert(
indexables.none? { |indexable| indexable.full_path.start_with?("#{RbConfig::CONFIG["rubylibdir"]}/psych") },
)
end

def test_files_to_index_includes_default_gems
def test_indexables_includes_default_gems
@config.load_config
files_to_index = @config.files_to_index
indexables = @config.indexables.map(&:full_path)

assert_includes(files_to_index, "#{RbConfig::CONFIG["rubylibdir"]}/pathname.rb")
assert_includes(files_to_index, "#{RbConfig::CONFIG["rubylibdir"]}/ipaddr.rb")
assert_includes(files_to_index, "#{RbConfig::CONFIG["rubylibdir"]}/abbrev.rb")
assert_includes(indexables, "#{RbConfig::CONFIG["rubylibdir"]}/pathname.rb")
assert_includes(indexables, "#{RbConfig::CONFIG["rubylibdir"]}/ipaddr.rb")
assert_includes(indexables, "#{RbConfig::CONFIG["rubylibdir"]}/abbrev.rb")
end

def test_files_to_index_includes_project_files
def test_indexables_includes_project_files
@config.load_config
files_to_index = @config.files_to_index
indexables = @config.indexables.map(&:full_path)

Dir.glob("#{Dir.pwd}/lib/**/*.rb").each do |path|
next if path.end_with?("_test.rb")

assert_includes(files_to_index, path)
assert_includes(indexables, path)
end
end

def test_files_to_index_avoids_duplicates_if_bundle_path_is_inside_project
def test_indexables_avoids_duplicates_if_bundle_path_is_inside_project
Bundler.settings.set_global("path", "vendor/bundle")
config = Configuration.new
config.load_config
Expand All @@ -69,18 +71,22 @@ def test_files_to_index_avoids_duplicates_if_bundle_path_is_inside_project
Bundler.settings.set_global("path", nil)
end

def test_files_to_index_does_not_include_gems_own_installed_files
def test_indexables_does_not_include_gems_own_installed_files
@config.load_config
files_to_index = @config.files_to_index
indexables = @config.indexables

assert(files_to_index.none? { |path| path.start_with?(Bundler.bundle_path.join("gems", "ruby-lsp").to_s) })
assert(
indexables.none? do |indexable|
indexable.full_path.start_with?(Bundler.bundle_path.join("gems", "ruby-lsp").to_s)
end,
)
end

def test_paths_are_unique
@config.load_config
files_to_index = @config.files_to_index
indexables = @config.indexables

assert_equal(files_to_index.uniq.length, files_to_index.length)
assert_equal(indexables.uniq.length, indexables.length)
end

def test_configuration_raises_for_unknown_keys
Expand Down

0 comments on commit e62652f

Please sign in to comment.