Skip to content

Commit

Permalink
Begin refactoring of SpecFetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
evanphx committed Feb 28, 2012
1 parent 228aea5 commit e5769be
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 227 deletions.
11 changes: 3 additions & 8 deletions lib/rubygems/commands/dependency_command.rb
Expand Up @@ -71,14 +71,9 @@ def execute
if remote? and not options[:reverse_dependencies] then
fetcher = Gem::SpecFetcher.fetcher

# REFACTOR: fetcher.find_specs_matching => specs
specs_and_sources = fetcher.find_matching(dependency,
dependency.specific?, true,
dependency.prerelease?)

specs.concat specs_and_sources.map { |spec_tuple, source_uri|
fetcher.fetch_spec spec_tuple, URI.parse(source_uri)
}
ss, err = fetcher.spec_for_dependency dependency

ss.each { |s,o| specs << s }
end

if specs.empty? then
Expand Down
18 changes: 2 additions & 16 deletions lib/rubygems/commands/fetch_command.rb
Expand Up @@ -42,27 +42,13 @@ def execute
dep = Gem::Dependency.new gem_name, version
dep.prerelease = options[:prerelease]

# Because of the madness that is SpecFetcher, you can't
# set both all and prerelease to true. If you do, prerelease
# is ignored.

if dep.prerelease? and all
specs_and_sources, errors =
Gem::SpecFetcher.fetcher.fetch_with_errors(dep, false, true,
dep.prerelease?)
else
specs_and_sources, errors =
Gem::SpecFetcher.fetcher.fetch_with_errors(dep, all, true,
dep.prerelease?)
end


specs_and_sources, errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep
if platform then
filtered = specs_and_sources.select { |s,| s.platform == platform }
specs_and_sources = filtered unless filtered.empty?
end

spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.last
spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.first

if spec.nil? then
show_lookup_failure gem_name, version, errors, options[:domain]
Expand Down
9 changes: 6 additions & 3 deletions lib/rubygems/commands/outdated_command.rb
Expand Up @@ -19,12 +19,15 @@ def execute
Gem::Specification.outdated.sort.each do |name|
local = Gem::Specification.find_all_by_name(name).max
dep = Gem::Dependency.new local.name, ">= #{local.version}"
remotes = Gem::SpecFetcher.fetcher.fetch dep
remotes, e = Gem::SpecFetcher.fetcher.spec_for_dependency dep

next if remotes.empty?

remote = remotes.last.first
say "#{local.name} (#{local.version} < #{remote.version})"
remotes.sort! { |a,b| a[0].version <=> b[0].version }

highest = remotes.last.first

say "#{local.name} (#{local.version} < #{highest.version})"
end
end
end
25 changes: 20 additions & 5 deletions lib/rubygems/commands/query_command.rb
Expand Up @@ -80,6 +80,7 @@ def execute
req = Gem::Requirement.default
# TODO: deprecate for real
dep = Gem::Deprecate.skip_during { Gem::Dependency.new name, req }
dep.prerelease = prerelease

if local? then
if prerelease and not both? then
Expand Down Expand Up @@ -110,13 +111,27 @@ def execute
say
end

all = options[:all]

fetcher = Gem::SpecFetcher.fetcher
spec_tuples = fetcher.find_matching dep, all, false, prerelease

spec_tuples += fetcher.find_matching dep, false, false, true if
prerelease and all
type = if options[:all]
if options[:prerelease]
:complete
else
:released
end
elsif options[:prerelease]
:prerelease
else
:latest
end

if options[:name].source.empty?
spec_tuples = fetcher.detect(type) { true }
else
spec_tuples = fetcher.detect(type) do |name, ver, plat|
options[:name] === name
end
end

output_query_results spec_tuples
end
Expand Down
11 changes: 2 additions & 9 deletions lib/rubygems/commands/specification_command.rb
Expand Up @@ -81,15 +81,8 @@ def execute
end

if remote? then
if !options[:version] or options[:version].none?
found = Gem::SpecFetcher.fetcher.fetch dep, false, false,
options[:prerelease]
else
# .fetch is super weird. The last true is there so that
# prerelease gems are included, otherwise the user can never
# request them.
found = Gem::SpecFetcher.fetcher.fetch dep, false, false, true
end
dep.prerelease = options[:prerelease]
found, err = Gem::SpecFetcher.fetcher.spec_for_dependency dep

specs.push(*found.map { |spec,| spec })
end
Expand Down
8 changes: 8 additions & 0 deletions lib/rubygems/dependency.rb
Expand Up @@ -80,6 +80,14 @@ def prerelease?
@prerelease || requirement.prerelease?
end

##
# Is this dependency simply asking for the latest version
# of a gem?

def latest_version?
@requirement.none?
end

def pretty_print q # :nodoc:
q.group 1, 'Gem::Dependency.new(', ')' do
q.pp name
Expand Down
45 changes: 24 additions & 21 deletions lib/rubygems/dependency_installer.rb
Expand Up @@ -91,6 +91,22 @@ def initialize(options = {})
@errors = nil
end

##
# Indicated, based on the requested domain, if local
# gems should be considered.

def consider_local?
@domain == :both or @domain == :local
end

##
# Indicated, based on the requested domain, if remote
# gems should be considered.

def consider_remote?
@domain == :both or @domain == :remote
end

##
# Returns a list of pairs of gemspecs and source_uris that match
# Gem::Dependency +dep+ from both local (Dir.pwd) and remote (Gem.sources)
Expand All @@ -104,7 +120,7 @@ def find_gems_with_sources(dep)
@errors = nil
gems_and_sources = []

if @domain == :both or @domain == :local then
if consider_local?
# REFACTOR rather than hardcoding using Dir.pwd, delegate to some config
# that allows knows the directory to look for local gems.
Dir[File.join(Dir.pwd, "#{dep.name}-[0-9]*.gem")].each do |gem_file|
Expand All @@ -113,21 +129,9 @@ def find_gems_with_sources(dep)
end
end

if @domain == :both or @domain == :remote then
if consider_remote?
begin
# REFACTOR: all = dep.requirement.needs_all?
requirements = dep.requirement.requirements.map do |req, ver|
req
end

# REFACTOR the API for fetch_with_errors sucks thats why +all+ exists.
all = !dep.prerelease? &&
# we only need latest if there's one requirement and it is
# guaranteed to match the newest specs
(requirements.length > 1 or
(requirements.first != ">=" and requirements.first != ">"))

found, @errors = Gem::SpecFetcher.fetcher.fetch_with_errors dep, all, true, dep.prerelease?
found, @errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep

gems_and_sources.push(*found)

Expand Down Expand Up @@ -254,7 +258,7 @@ def find_spec_by_name_and_version(gem_name,

spec_and_source = nil

if @domain != :remote
if consider_local?
glob = if File::ALT_SEPARATOR then
gem_name.gsub File::ALT_SEPARATOR, File::SEPARATOR
else
Expand All @@ -280,7 +284,7 @@ def find_spec_by_name_and_version(gem_name,
# HACK Dependency objects should be immutable
dep.prerelease = true if prerelease

spec_and_sources = find_gems_with_sources(dep).reverse
spec_and_sources = find_gems_with_sources(dep)
spec_and_source = spec_and_sources.find { |spec, source|
Gem::Platform.match spec.platform
}
Expand All @@ -292,7 +296,6 @@ def find_spec_by_name_and_version(gem_name,
gem_name, version, @errors)
end

# REFACTOR just return spec_and_source
@specs_and_sources = [spec_and_source]
end

Expand All @@ -312,11 +315,11 @@ def find_spec_by_name_and_version(gem_name,

def install dep_or_name, version = Gem::Requirement.default
if String === dep_or_name then
# REFACTOR use return value to set @specs_and_source
find_spec_by_name_and_version dep_or_name, version, @prerelease
else
dep_or_name.prerelease = @prerelease
@specs_and_sources = [find_gems_with_sources(dep_or_name).last]
dep = dep_or_name.dup
dep.prerelease = @prerelease
@specs_and_sources = [find_gems_with_sources(dep).first]
end

@installed_gems = []
Expand Down
3 changes: 1 addition & 2 deletions lib/rubygems/remote_fetcher.rb
Expand Up @@ -87,8 +87,7 @@ def initialize(proxy = nil)
# larger, more emcompassing effort. -erikh

def download_to_cache dependency
found = Gem::SpecFetcher.fetcher.fetch dependency, true, true,
dependency.prerelease?
found, err = Gem::SpecFetcher.fetcher.spec_for_dependency dependency

return if found.empty?

Expand Down

0 comments on commit e5769be

Please sign in to comment.