Skip to content

Commit

Permalink
+ Refactored GemPathSearcher entirely out. RIPMF
Browse files Browse the repository at this point in the history
  • Loading branch information
zenspider committed Apr 13, 2011
1 parent 048ed59 commit 155275b
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 82 deletions.
19 changes: 11 additions & 8 deletions lib/rubygems.rb
Expand Up @@ -201,7 +201,7 @@ def self.try_activate path

# TODO: use find_all and bork if ambiguous

spec = Gem.searcher.find_spec_for_file path
spec = Gem::Specification.find_by_path path
return false unless spec

begin
Expand Down Expand Up @@ -231,11 +231,14 @@ def self.try_activate path
# Gem::Requirement and Gem::Version documentation.

def self.activate(dep, *requirements)
Gem::Specification.find(dep, *requirements).activate
raise ArgumentError, "Deprecated use of Gem.activate(dep)" if
Gem::Dependency === dep

Gem::Specification.find_by_name(dep, *requirements).activate
end

def self.activate_dep dep, *requirements # :nodoc:
Gem::Specification.find(dep, *requirements).activate
dep.to_spec.activate
end

def self.activate_spec spec # :nodoc:
Expand Down Expand Up @@ -346,6 +349,7 @@ def self.clear_paths
@paths = nil
@user_home = nil
@searcher = nil
Gem::Specification.reset
end

##
Expand Down Expand Up @@ -464,11 +468,9 @@ def self.find_files(glob, check_load_path=true)
}.flatten.select { |file| File.file? file.untaint }
end

specs = searcher.find_all glob

specs.each do |spec|
files.concat searcher.matching_files(spec, glob)
end
files.concat Gem::Specification.map { |spec|
spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}")
}.flatten

# $LOAD_PATH might contain duplicate entries or reference
# the spec dirs directly, so we prune.
Expand Down Expand Up @@ -790,6 +792,7 @@ def self.promote_load_path(gem_name, over_name)
def self.refresh
source_index.refresh!

Gem::Specification.reset
@searcher = nil
end

Expand Down
14 changes: 5 additions & 9 deletions lib/rubygems/commands/which_command.rb
@@ -1,10 +1,6 @@
require 'rubygems/command'
require 'rubygems/gem_path_searcher'

class Gem::Commands::WhichCommand < Gem::Command

EXT = %w[.rb .rbw .so .dll .bundle] # HACK

def initialize
super 'which', 'Find the location of a library file you can require',
:search_gems_first => false, :show_all => false
Expand All @@ -28,14 +24,13 @@ def defaults_str # :nodoc:
end

def execute
searcher = Gem::GemPathSearcher.new

found = false

options[:args].each do |arg|
arg = arg.sub(/#{Regexp.union(*EXT)}$/, '')
arg = arg.sub(/#{Regexp.union(*Gem.suffixes)}$/, '')
dirs = $LOAD_PATH
spec = searcher.find arg

spec = Gem::Specification.find_by_path arg

if spec then
if options[:search_gems_first] then
Expand All @@ -45,6 +40,7 @@ def execute
end
end

# TODO: this is totally redundant and stupid
paths = find_paths arg, dirs

if paths.empty? then
Expand All @@ -62,7 +58,7 @@ def find_paths(package_name, dirs)
result = []

dirs.each do |dir|
EXT.each do |ext|
Gem.suffixes.each do |ext|
full_path = File.join dir, "#{package_name}#{ext}"
if File.exist? full_path then
result << full_path
Expand Down
8 changes: 5 additions & 3 deletions lib/rubygems/custom_require.rb
Expand Up @@ -35,14 +35,16 @@ def require path
if Gem.unresolved_deps.empty? or Gem.loaded_path? path then
gem_original_require path
else
spec = Gem.searcher.find_active path
spec = Gem::Specification.find { |spec|
spec.loaded? and spec.contains_requirable_file? path
}

unless spec then
found_specs = Gem.searcher.find_in_unresolved path
found_specs = Gem::Specification.find_in_unresolved path
unless found_specs.empty? then
found_specs = [found_specs.last]
else
found_specs = Gem.searcher.find_in_unresolved_tree path
found_specs = Gem::Specification.find_in_unresolved_tree path
end

found_specs.each do |found_spec|
Expand Down
9 changes: 8 additions & 1 deletion lib/rubygems/gem_path_searcher.rb
Expand Up @@ -159,5 +159,12 @@ def lib_dirs_for(spec)
spec.require_paths
end

extend Deprecate

deprecate :find, :none, 2011, 10
deprecate :find_active, :none, 2011, 10
deprecate :find_all, :none, 2011, 10
deprecate :find_in_unresolved, :none, 2011, 10
deprecate :find_in_unresolved_tree, :none, 2011, 10
deprecate :find_spec_for_file, :none, 2011, 10
end

104 changes: 89 additions & 15 deletions lib/rubygems/specification.rb
Expand Up @@ -451,21 +451,6 @@ def self.normalize_yaml_input(input)
result.gsub(/ !!null \n/, " \n")
end

##
# Find the best specification matching a dependency or a name +
# requirements.

def self.find name_or_dep, *requirements
dep = name_or_dep

unless Gem::Dependency === dep then
requirements = Gem::Requirement.default if requirements.empty?
dep = Gem::Dependency.new(dep, requirements)
end

dep.to_spec
end

##
# Sets the rubygems_version to the current RubyGems version

Expand Down Expand Up @@ -1637,6 +1622,95 @@ def contains_requirable_file?(file)
return false
end

def self.reset
@@all = nil
end

extend Enumerable

def self.each
unless block_given? then
enum_for(:each)
else
self.all.each do |x|
yield x
end
end
end

def self.all
# FIX: zomg deps broken
@@all ||= Gem.source_index.map { |_, spec| spec }.sort { |a, b|
names = a.name <=> b.name
next names if names.nonzero?
b.version <=> a.version
}
end

def self.find_by_path path
self.find { |spec|
spec.contains_requirable_file? path
}
end

##
# Find the best specification matching a name + requirements. Raises
# if the dependency doesn't resolve to a valid specification.

def self.find_by_name name, *requirements
requirements = Gem::Requirement.default if requirements.empty?

Gem::Dependency.new(name, *requirements).to_spec
end

def lib_dirs_glob
dirs = if self.require_paths.size > 1 then
"{#{self.require_paths.join(',')}}"
else
self.require_paths.first
end

"#{self.full_gem_path}/#{dirs}"
end

def matches_for_glob glob # TODO: rename?
glob = File.join(self.lib_dirs_glob, glob)

Dir[glob].map { |f| f.untaint } # FIX our tests are brokey
end

def self.find_in_unresolved(path)
specs = Gem.unresolved_deps.values.map { |dep|
# TODO: nuke this:
Gem.source_index.search dep, true
}.flatten

specs.find_all { |spec|
spec.contains_requirable_file? path
}
end

def self.find_in_unresolved_tree path
specs = Gem.unresolved_deps.values.map { |dep|
# TODO: nuke this:
Gem.source_index.search dep, true
}.flatten

specs.reverse_each do |spec|
trails = []
spec.traverse do |from_spec, dep, to_spec, trail|
next unless to_spec.conflicts.empty?
trails << trail if to_spec.contains_requirable_file? path
end

next if trails.empty?

return trails.map(&:reverse).sort.first.reverse
end

[]
end

extend Deprecate

deprecate :test_suite_file, :test_file, 2011, 10
Expand Down
1 change: 1 addition & 0 deletions lib/rubygems/test_case.rb
Expand Up @@ -396,6 +396,7 @@ def util_clear_gems
FileUtils.rm_rf @gemhome.gems
FileUtils.rm_rf @gemhome.specifications
Gem.source_index.refresh!
Gem::Specification.reset
end

##
Expand Down
13 changes: 8 additions & 5 deletions test/rubygems/test_gem.rb
Expand Up @@ -23,12 +23,12 @@ def setup
def assert_activate expected, *specs
specs.each do |spec|
case spec
when Array
Gem::Specification.find(*spec).activate
when String
Gem::Specification.find(spec).activate
else
when String then
Gem::Specification.find_by_name(spec).activate
when Gem::Specification then
spec.activate
else
flunk spec.inspect
end
end

Expand Down Expand Up @@ -677,7 +677,9 @@ def test_self_find_files

Gem.source_index = util_setup_spec_fetcher foo1, foo2

# HACK should be Gem.refresh
Gem.searcher = nil
Gem::Specification.reset

expected = [
File.expand_path('test/rubygems/sff/discover.rb', @@project_dir),
Expand Down Expand Up @@ -1044,6 +1046,7 @@ def test_load_plugins

Gem.source_index = nil
Gem.searcher = nil
Gem::Specification.reset

gem 'foo'

Expand Down
7 changes: 5 additions & 2 deletions test/rubygems/test_gem_commands_which_command.rb
Expand Up @@ -5,6 +5,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase

def setup
super
Gem::Specification.reset
@cmd = Gem::Commands::WhichCommand.new
end

Expand All @@ -22,6 +23,8 @@ def test_execute
end

def test_execute_one_missing
# TODO: this test fails in isolation

util_foo_bar

@cmd.handle_options %w[foo_bar missing]
Expand All @@ -31,7 +34,7 @@ def test_execute_one_missing
end

assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
assert_match %r%Can't find ruby library file or shared library missing\n%,
assert_match %r%Can.t find ruby library file or shared library missing\n%,
@ui.error
end

Expand All @@ -45,7 +48,7 @@ def test_execute_missing
end

assert_equal '', @ui.output
assert_match %r%Can't find ruby library file or shared library missing\n%,
assert_match %r%Can.t find ruby library file or shared library missing\n%,
@ui.error
end

Expand Down

1 comment on commit 155275b

@evanphx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very happy how small this ended up being! huzzah!

Please sign in to comment.