Permalink
Browse files

Add Gem::Source, the source abstraction

  • Loading branch information...
1 parent 38c8ba8 commit d922a0f616432cb37e81fb287f378abc22efc29a @evanphx evanphx committed Mar 1, 2012
View
@@ -105,6 +105,7 @@ module Gem
require 'rubygems/deprecate'
require 'rubygems/compatibility'
require 'rubygems/errors'
+require 'rubygems/source_list'
module Gem
RUBYGEMS_DIR = File.dirname File.expand_path(__FILE__)
@@ -921,7 +922,7 @@ def self.rubygems_version
# default_sources if it is not installed.
def self.sources
- @sources ||= default_sources
+ @sources ||= Gem::SourceList.from(default_sources)
end
##
@@ -932,7 +933,11 @@ def self.sources
# more of a code comment about the implementation.
def self.sources= new_sources
- @sources = new_sources
+ if !new_sources
+ @sources = nil
+ else
+ @sources = Gem::SourceList.from(new_sources)
+ end
end
##
@@ -76,7 +76,7 @@ def execute
when /^gempath/, /^path/, /^GEM_PATH/ then
out << Gem.path.join(File::PATH_SEPARATOR)
when /^remotesources/ then
- out << Gem.sources.join("\n")
+ out << Gem.sources.to_a.join("\n")
when /^platform/ then
out << Gem.platforms.join(File::PATH_SEPARATOR)
when nil then
@@ -48,14 +48,14 @@ def execute
specs_and_sources = filtered unless filtered.empty?
end
- spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.first
+ spec, source = specs_and_sources.sort_by { |s,| s.version }.first
if spec.nil? then
show_lookup_failure gem_name, version, errors, options[:domain]
next
end
- Gem::RemoteFetcher.fetcher.download spec, source_uri, Dir.pwd
+ source.download spec
say "Downloaded #{spec.full_name}"
end
@@ -150,8 +150,8 @@ def output_query_results(spec_tuples)
output = []
versions = Hash.new { |h,name| h[name] = [] }
- spec_tuples.each do |spec_tuple, source_uri|
- versions[spec_tuple.name] << [spec_tuple, source_uri]
+ spec_tuples.each do |spec_tuple, source|
+ versions[spec_tuple.name] << [spec_tuple, source]
end
versions = versions.sort_by do |(n,_),_|
@@ -204,8 +204,7 @@ def output_query_results(spec_tuples)
spec = detail_tuple.last
unless spec.kind_of? Gem::Specification
- uri = URI.parse spec
- spec = Gem::SpecFetcher.fetcher.fetch_spec detail_tuple.first, uri
+ spec = spec.fetch_spec detail_tuple.first
end
entry << "\n"
@@ -48,7 +48,7 @@ def execute
options[:update])
if options[:clear_all] then
- path = Gem::SpecFetcher.fetcher.dir
+ path = File.join Gem.user_home, '.gem', 'specs'
FileUtils.rm_rf path
unless File.exist? path then
@@ -64,13 +64,12 @@ def execute
end
end
- if options[:add] then
- source_uri = options[:add]
- uri = URI.parse source_uri
+ if source_uri = options[:add] then
+ source = Gem::Source.new source_uri
begin
- Gem::SpecFetcher.fetcher.load_specs uri, 'specs'
- Gem.sources << source_uri
+ source.load_specs :released
+ Gem.sources << source
Gem.configuration.write
say "#{source_uri} added to sources"
@@ -99,10 +98,9 @@ def execute
if options[:update] then
fetcher = Gem::SpecFetcher.fetcher
- Gem.sources.each do |update_uri|
- update_uri = URI.parse update_uri
- fetcher.load_specs update_uri, 'specs'
- fetcher.load_specs update_uri, 'latest_specs'
+ Gem.sources.each_source do |source|
+ source.load_specs :released
+ source.load_specs :latest
end
say "source cache successfully updated"
@@ -346,7 +346,7 @@ def to_yaml # :nodoc:
DEFAULT_BULK_THRESHOLD
end
- yaml_hash[:sources] = Gem.sources
+ yaml_hash[:sources] = Gem.sources.to_a
yaml_hash[:update_sources] = if @hash.key?(:update_sources)
@hash[:update_sources]
@@ -4,6 +4,8 @@
require 'rubygems/installer'
require 'rubygems/spec_fetcher'
require 'rubygems/user_interaction'
+require 'rubygems/source_local'
+require 'rubygems/source_specific_file'
##
# Installs a gem along with all its dependencies from local and remote gems.
@@ -121,11 +123,10 @@ def find_gems_with_sources(dep)
gems_and_sources = []
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|
- spec = Gem::Package.new(gem_file).spec
- gems_and_sources << [spec, gem_file] if spec.name == dep.name
+ sl = Gem::Source::Local.new
+
+ if spec = sl.find_gem(dep.name)
+ gems_and_sources << [spec, sl]
end
end
@@ -147,11 +148,8 @@ def find_gems_with_sources(dep)
end
end
- # REFACTOR 2 of 3 users of this method call reverse on the results, perhaps
- # we're sorting them wrong. The other calls last, so perhaps it shuold use
- # a different API.
gems_and_sources.sort_by do |gem, source|
- [gem, source =~ /^http:\/\// ? 0 : 1] # local gems win
+ [gem, source] # local gems win
end
end
@@ -224,7 +222,7 @@ def add_found_dependencies to_do, dependency_list
end
end
- results = find_gems_with_sources(dep).reverse
+ results = find_gems_with_sources(dep)
results.reject! do |dep_spec,|
to_do.push dep_spec
@@ -259,22 +257,14 @@ def find_spec_by_name_and_version(gem_name,
spec_and_source = nil
if consider_local?
- glob = if File::ALT_SEPARATOR then
- gem_name.gsub File::ALT_SEPARATOR, File::SEPARATOR
- else
- gem_name
- end
-
- # REFACTOR Don't assume local gems are in the current directory
- local_gems = Dir["#{glob}*"].sort.reverse
-
- local_gems.each do |gem_file|
- next unless gem_file =~ /gem$/
- begin
- spec = Gem::Package.new(gem_file).spec
- spec_and_source = [spec, gem_file]
- break
- rescue SystemCallError, Gem::Package::FormatError
+ if File.exists? gem_name
+ source = Gem::Source::SpecificFile.new(gem_name)
+ spec_and_source = [source.spec, source]
+ else
+ local = Gem::Source::Local.new
+
+ if spec = local.find_gem(gem_name, version)
+ spec_and_source = [spec, local]
end
end
end
@@ -337,11 +327,10 @@ def install dep_or_name, version = Gem::Requirement.default
# TODO: make this sorta_verbose so other users can benefit from it
say "Installing gem #{spec.full_name}" if Gem.configuration.really_verbose
- _, source_uri = @specs_and_sources.assoc spec
+ _, source = @specs_and_sources.assoc spec
begin
# REFACTOR make the fetcher to use configurable
- local_gem_path = Gem::RemoteFetcher.fetcher.download(spec, source_uri,
- @cache_dir)
+ local_gem_path = source.download spec, @cache_dir
rescue Gem::RemoteFetcher::FetchError
# TODO I doubt all fetch errors are recoverable, we should at least
# report the errors probably.
@@ -219,9 +219,9 @@ def prefetch(gems)
# Called from IndexSpecification to get a true Specification
# object.
#
- def load_spec(name, ver, uri)
+ def load_spec(name, ver, source)
key = "#{name}-#{ver}"
- @specs[key] ||= @f.fetch_spec(Gem::NameTuple.new(name, ver), uri)
+ @specs[key] ||= source.fetch_spec(Gem::NameTuple.new(name, ver))
end
end
@@ -380,12 +380,12 @@ def full_spec
def download(path)
if @spec.respond_to? :source
- source = @spec.source.to_s
+ source = @spec.source
else
source = Gem.sources.first
end
- Gem::RemoteFetcher.fetcher.download full_spec, source, path
+ source.download full_spec, path
end
def ==(other)
View
@@ -74,6 +74,10 @@ def to_a
[@name, @version, @platform]
end
+ def to_s
+ "#<Gem::NameTuple #{@name}, #{@version}, #{@platform}>"
+ end
+
def <=> other
to_a <=> other.to_a
end
@@ -97,4 +101,10 @@ def == other
end
end
+ alias_method :eql?, :==
+
+ def hash
+ to_a.hash
+ end
+
end
@@ -91,9 +91,9 @@ def download_to_cache dependency
return if found.empty?
- spec, source_uri = found.sort_by { |(s,_)| s.version }.last
+ spec, source = found.sort_by { |(s,_)| s.version }.last
- download spec, source_uri
+ download spec, source.uri.to_s
end
##
Oops, something went wrong.

0 comments on commit d922a0f

Please sign in to comment.