summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authordrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-11-19 00:34:13 +0000
committerdrbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-11-19 00:34:13 +0000
commita7fa4d5d9aab150ad4b0c3f3217fe444df69f527 ()
tree88ab96d22f7228b556337aa7c34042d4fd279394 /lib
parente7ec3dad907f2c77f17faddb40a98b2ef4523222 (diff)
* lib/rubygems: Update to RubyGems master 6a3d9f9. Changes include:
Compatibly renamed Gem::DependencyResolver to Gem::Resolver. Added support for git gems in gem.deps.rb and Gemfile. Fixed resolver bugs. * test/rubygems: ditto. * lib/rubygems/LICENSE.txt: Updated to license from RubyGems trunk. [ruby-trunk - Bug #9086] * lib/rubygems/commands/which_command.rb: RubyGems now indicates failure when any file is missing. [ruby-trunk - Bug #9004] * lib/rubygems/ext/builder: Extensions are now installed into the extension install directory and the first directory in the require path from the gem. This allows backwards compatibility with msgpack and other gems that calculate full require paths. [ruby-trunk - Bug #9106] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43714 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--lib/rubygems.rb49
-rw-r--r--lib/rubygems/LICENSE.txt75
-rw-r--r--lib/rubygems/available_set.rb4
-rw-r--r--lib/rubygems/basic_specification.rb8
-rw-r--r--lib/rubygems/commands/install_command.rb23
-rw-r--r--lib/rubygems/commands/which_command.rb5
-rw-r--r--lib/rubygems/dependency_installer.rb32
-rw-r--r--lib/rubygems/doctor.rb20
-rw-r--r--lib/rubygems/errors.rb17
-rw-r--r--lib/rubygems/exceptions.rb10
-rw-r--r--lib/rubygems/ext/builder.rb3
-rw-r--r--lib/rubygems/ext/cmake_builder.rb2
-rw-r--r--lib/rubygems/ext/configure_builder.rb2
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb8
-rw-r--r--lib/rubygems/ext/rake_builder.rb2
-rw-r--r--lib/rubygems/remote_fetcher.rb2
-rw-r--r--lib/rubygems/request_set.rb19
-rw-r--r--lib/rubygems/request_set/gem_dependency_api.rb149
-rw-r--r--lib/rubygems/request_set/lockfile.rb27
-rw-r--r--lib/rubygems/resolver.rb (renamed from lib/rubygems/dependency_resolver.rb)104
-rw-r--r--lib/rubygems/resolver/activation_request.rb (renamed from lib/rubygems/dependency_resolver/activation_request.rb)6
-rw-r--r--lib/rubygems/resolver/api_set.rb (renamed from lib/rubygems/dependency_resolver/api_set.rb)4
-rw-r--r--lib/rubygems/resolver/api_specification.rb (renamed from lib/rubygems/dependency_resolver/api_specification.rb)2
-rw-r--r--lib/rubygems/resolver/best_set.rb (renamed from lib/rubygems/dependency_resolver/best_set.rb)2
-rw-r--r--lib/rubygems/resolver/composed_set.rb (renamed from lib/rubygems/dependency_resolver/composed_set.rb)2
-rw-r--r--lib/rubygems/resolver/conflict.rb (renamed from lib/rubygems/dependency_resolver/dependency_conflict.rb)8
-rw-r--r--lib/rubygems/resolver/current_set.rb (renamed from lib/rubygems/dependency_resolver/current_set.rb)2
-rw-r--r--lib/rubygems/resolver/dependency_request.rb (renamed from lib/rubygems/dependency_resolver/dependency_request.rb)4
-rw-r--r--lib/rubygems/resolver/git_set.rb81
-rw-r--r--lib/rubygems/resolver/git_specification.rb16
-rw-r--r--lib/rubygems/resolver/index_set.rb (renamed from lib/rubygems/dependency_resolver/index_set.rb)4
-rw-r--r--lib/rubygems/resolver/index_specification.rb (renamed from lib/rubygems/dependency_resolver/index_specification.rb)2
-rw-r--r--lib/rubygems/resolver/installed_specification.rb (renamed from lib/rubygems/dependency_resolver/installed_specification.rb)2
-rw-r--r--lib/rubygems/resolver/installer_set.rb (renamed from lib/rubygems/dependency_resolver/installer_set.rb)8
-rw-r--r--lib/rubygems/resolver/lock_set.rb (renamed from lib/rubygems/dependency_resolver/lock_set.rb)6
-rw-r--r--lib/rubygems/resolver/requirement_list.rb40
-rw-r--r--lib/rubygems/resolver/set.rb (renamed from lib/rubygems/dependency_resolver/set.rb)9
-rw-r--r--lib/rubygems/resolver/spec_specification.rb (renamed from lib/rubygems/dependency_resolver/spec_specification.rb)6
-rw-r--r--lib/rubygems/resolver/specification.rb (renamed from lib/rubygems/dependency_resolver/specification.rb)4
-rw-r--r--lib/rubygems/resolver/vendor_set.rb (renamed from lib/rubygems/dependency_resolver/vendor_set.rb)6
-rw-r--r--lib/rubygems/resolver/vendor_specification.rb (renamed from lib/rubygems/dependency_resolver/vendor_specification.rb)2
-rw-r--r--lib/rubygems/source.rb25
-rw-r--r--lib/rubygems/source/git.rb189
-rw-r--r--lib/rubygems/source/installed.rb7
-rw-r--r--lib/rubygems/source/local.rb17
-rw-r--r--lib/rubygems/source/specific_file.rb17
-rw-r--r--lib/rubygems/source/vendor.rb18
-rw-r--r--lib/rubygems/source_list.rb15
-rw-r--r--lib/rubygems/spec_fetcher.rb26
-rw-r--r--lib/rubygems/specification.rb5
-rw-r--r--lib/rubygems/test_case.rb70
-rw-r--r--lib/rubygems/util.rb65
-rw-r--r--lib/rubygems/util/stringio.rb34
53 files changed, 1031 insertions, 234 deletions
@@ -8,7 +8,7 @@
require 'rbconfig'
module Gem
- VERSION = '2.2.0'
end
# Must be first since it unloads the prelude from 1.9.2
@@ -302,7 +302,6 @@ module Gem
# The path where gem executables are to be installed.
def self.bindir(install_dir=Gem.dir)
- # TODO: move to Gem::Dirs
return File.join install_dir, 'bin' unless
install_dir.to_s == Gem.default_dir.to_s
Gem.default_bindir
@@ -362,16 +361,21 @@ module Gem
Zlib::Deflate.deflate data
end
- # DOC: needs doc'd or :nodoc'd
def self.paths
@paths ||= Gem::PathSupport.new
end
- # DOC: needs doc'd or :nodoc'd
def self.paths=(env)
clear_paths
@paths = Gem::PathSupport.new env
- Gem::Specification.dirs = @paths.path # FIX: home is at end
end
##
@@ -380,12 +384,10 @@ module Gem
# FIXME deprecate these once everything else has been done -ebh
def self.dir
- # TODO: raise "no"
paths.home
end
def self.path
- # TODO: raise "no"
paths.path
end
@@ -552,42 +554,30 @@ module Gem
private_class_method :find_home
##
# Zlib::GzipReader wrapper that unzips +data+.
def self.gunzip(data)
- # TODO: move to utils
- require 'stringio'
- require 'zlib'
- data = StringIO.new data
-
- unzipped = Zlib::GzipReader.new(data).read
- unzipped.force_encoding Encoding::BINARY if Object.const_defined? :Encoding
- unzipped
end
##
# Zlib::GzipWriter wrapper that zips +data+.
def self.gzip(data)
- # TODO: move to utils
- require 'stringio'
- require 'zlib'
- zipped = StringIO.new
- zipped.set_encoding Encoding::BINARY if Object.const_defined? :Encoding
-
- Zlib::GzipWriter.wrap zipped do |io| io.write data end
-
- zipped.string
end
##
# A Zlib::Inflate#inflate wrapper
def self.inflate(data)
- # TODO: move to utils
- require 'zlib'
- Zlib::Inflate.inflate data
end
##
@@ -693,7 +683,6 @@ module Gem
file = $1
lineno = $2.to_i
- # TODO: it is ALWAYS joined! STUPID!
[file, lineno]
end
@@ -974,7 +963,6 @@ module Gem
paths = nil if paths == [nil]
paths = paths.first if Array === Array(paths).first
self.paths = { "GEM_HOME" => home, "GEM_PATH" => paths }
- # TODO: self.paths = home, paths
end
##
@@ -1169,7 +1157,8 @@ module Gem
autoload :ConfigFile, 'rubygems/config_file'
autoload :Dependency, 'rubygems/dependency'
autoload :DependencyList, 'rubygems/dependency_list'
- autoload :DependencyResolver, 'rubygems/dependency_resolver'
autoload :PathSupport, 'rubygems/path_support'
autoload :Platform, 'rubygems/platform'
autoload :RequestSet, 'rubygems/request_set'
@@ -1,53 +1,54 @@
RubyGems is copyrighted free software by Chad Fowler, Rich Kilmer, Jim
Weirich and others. You can redistribute it and/or modify it under
-either the terms of the GPL (see the GPL.txt file), or the conditions
-below:
- 1. You may make and give away verbatim copies of the source form of the
- software without restriction, provided that you duplicate all of the
- original copyright notices and associated disclaimers.
- 2. You may modify your copy of the software in any way, provided that
- you do at least ONE of the following:
- a) place your modifications in the Public Domain or otherwise
- make them Freely Available, such as by posting said
- modifications to Usenet or an equivalent medium, or by allowing
- the author to include your modifications in the software.
- b) use the modified software only within your corporation or
- organization.
- c) rename any non-standard executables so the names do not conflict
- with standard executables, which must also be provided.
- d) make other distribution arrangements with the author.
- 3. You may distribute the software in object code or executable
- form, provided that you do at least ONE of the following:
- a) distribute the executables and library files of the software,
- together with instructions (in the manual page or equivalent)
- on where to get the original distribution.
- b) accompany the distribution with the machine-readable source of
- the software.
- c) give non-standard executables non-standard names, with
- instructions on where to get the original software distribution.
- d) make other distribution arrangements with the author.
- 4. You may modify and include the part of the software into any other
- software (possibly commercial).
- 5. The scripts and library files supplied as input to or produced as
- output from the software do not automatically fall under the
- copyright of the software, but belong to whomever generated them,
- and may be sold commercially, and may be aggregated with this
- software.
- 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE.
@@ -116,7 +116,7 @@ class Gem::AvailableSet
##
#
- # Used by the DependencyResolver, the protocol to use a AvailableSet as a
# search Set.
def find_all(req)
@@ -127,7 +127,7 @@ class Gem::AvailableSet
end
match.map do |t|
- Gem::DependencyResolver::InstalledSpecification.new(self, t.spec, t.source)
end
end
@@ -107,7 +107,7 @@ class Gem::BasicSpecification
File.join full_gem_path, path
end
- full_paths << extension_install_dir unless @extensions.empty?
full_paths
end
@@ -155,6 +155,10 @@ class Gem::BasicSpecification
raise NotImplementedError
end
##
# Paths in the gem to add to <code>$LOAD_PATH</code> when this gem is
# activated.
@@ -179,7 +183,7 @@ class Gem::BasicSpecification
File.join '..', '..', 'extensions', Gem::Platform.local.to_s,
Gem.extension_api_version, full_name
- @require_paths + [relative_extension_install_dir]
end
##
@@ -56,6 +56,12 @@ class Gem::Commands::InstallCommand < Gem::Command
o[:install_as_default] = v
end
@installed_specs = nil
end
@@ -185,8 +191,23 @@ to write the specification by hand. For example:
return if options[:conservative] and
not Gem::Dependency.new(name, version).matching_specs.empty?
inst = Gem::DependencyInstaller.new options
- inst.install name, Gem::Requirement.create(version)
@installed_specs.push(*inst.installed_gems)
@@ -35,7 +35,7 @@ requiring to see why it does not behave as you expect.
end
def execute
- found = false
options[:args].each do |arg|
arg = arg.sub(/#{Regexp.union(*Gem.suffixes)}$/, '')
@@ -56,9 +56,10 @@ requiring to see why it does not behave as you expect.
if paths.empty? then
alert_error "Can't find ruby library file or shared library #{arg}"
else
say paths
- found = true
end
end
@@ -1,6 +1,5 @@
require 'rubygems'
require 'rubygems/dependency_list'
-require 'rubygems/dependency_resolver'
require 'rubygems/package'
require 'rubygems/installer'
require 'rubygems/spec_fetcher'
@@ -196,7 +195,7 @@ class Gem::DependencyInstaller
# sources. Gems are sorted with newer gems preferred over older gems, and
# local gems preferred over remote gems.
- def find_gems_with_sources dep # :nodoc:
set = Gem::AvailableSet.new
if consider_local?
@@ -211,7 +210,26 @@ class Gem::DependencyInstaller
if consider_remote?
begin
- found, errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep
if @errors
@errors += errors
@@ -219,7 +237,7 @@ class Gem::DependencyInstaller
@errors = errors
end
- set << found
rescue Gem::RemoteFetcher::FetchError => e
# FIX if there is a problem talking to the network, we either need to always tell
@@ -271,7 +289,7 @@ class Gem::DependencyInstaller
dep = Gem::Dependency.new gem_name, version
dep.prerelease = true if prerelease
- set = find_gems_with_sources(dep)
set.match_platform!
end
@@ -402,7 +420,7 @@ class Gem::DependencyInstaller
request_set = as.to_request_set install_development_deps
request_set.soft_missing = @force
- installer_set = Gem::DependencyResolver::InstallerSet.new @domain
installer_set.always_install.concat request_set.always_install
installer_set.ignore_installed = @only_install_dir
@@ -411,7 +429,7 @@ class Gem::DependencyInstaller
request_set.soft_missing = true
end
- composed_set = Gem::DependencyResolver.compose_sets as, installer_set
request_set.resolve composed_set
@@ -1,6 +1,5 @@
require 'rubygems'
require 'rubygems/user_interaction'
-require 'pathname'
##
# Cleans up after a partially-failed uninstall or for an invalid
@@ -39,7 +38,7 @@ class Gem::Doctor
# If +dry_run+ is true no files or directories will be removed.
def initialize gem_repository, dry_run = false
- @gem_repository = Pathname(gem_repository)
@dry_run = dry_run
@installed_specs = nil
@@ -97,26 +96,29 @@ class Gem::Doctor
# Removes files in +sub_directory+ with +extension+
def doctor_child sub_directory, extension # :nodoc:
- directory = @gem_repository + sub_directory
- directory.children.sort.each do |child|
- next unless child.exist?
- basename = child.basename(extension).to_s
next if installed_specs.include? basename
next if /^rubygems-\d/ =~ basename
next if 'specifications' == sub_directory and 'default' == basename
- type = child.directory? ? 'directory' : 'file'
action = if @dry_run then
'Extra'
else
- child.rmtree
'Removed'
end
- say "#{action} #{type} #{sub_directory}/#{child.basename}"
end
rescue Errno::ENOENT
# ignore
@@ -73,12 +73,27 @@ module Gem
# data from a source
class SourceFetchProblem < ErrorReason
def initialize(source, error)
@source = source
@error = error
end
- attr_reader :source, :error
def wordy
"Unable to download data from #{@source.uri} - #{@error.message}"
@@ -23,7 +23,7 @@ class Gem::DependencyError < Gem::Exception; end
class Gem::DependencyRemovalException < Gem::Exception; end
##
-# Raised by Gem::DependencyResolver when a Gem::DependencyConflict reaches the
# toplevel. Indicates which dependencies were incompatible through #conflict
# and #conflicting_dependencies
@@ -117,7 +117,7 @@ class Gem::SpecificGemNotFoundException < Gem::GemNotFoundException
end
##
-# Raised by Gem::DependencyResolver when dependencies conflict and create the
# inability to find a valid possible spec for a request.
class Gem::ImpossibleDependenciesError < Gem::Exception
@@ -211,20 +211,20 @@ class Gem::SystemExitException < SystemExit
end
##
-# Raised by DependencyResolver when a dependency requests a gem for which
# there is no spec.
class Gem::UnsatisfiableDependencyError < Gem::Exception
##
# The unsatisfiable dependency. This is a
- # Gem::DependencyResolver::DependencyRequest, not a Gem::Dependency
attr_reader :dependency
##
# Creates a new UnsatisfiableDepedencyError for the unsatisfiable
- # Gem::DependencyResolver::DependencyRequest +dep+
def initialize dep, platform_mismatch=nil
if platform_mismatch and !platform_mismatch.empty?
@@ -149,6 +149,7 @@ EOF
extension ||= '' # I wish I knew why this line existed
extension_dir =
File.expand_path File.join @gem_dir, File.dirname(extension)
builder = builder_for extension
@@ -158,7 +159,7 @@ EOF
CHDIR_MUTEX.synchronize do
Dir.chdir extension_dir do
results = builder.build(extension, @gem_dir, dest_path,
- results, @build_args)
say results.join("\n") if Gem.configuration.really_verbose
end
@@ -1,7 +1,7 @@
require 'rubygems/command'
class Gem::Ext::CmakeBuilder < Gem::Ext::Builder
- def self.build(extension, directory, dest_path, results)
unless File.exist?('Makefile') then
cmd = "cmake . -DCMAKE_INSTALL_PREFIX=#{dest_path}"
cmd << " #{Gem::Command.build_args.join ' '}" unless Gem::Command.build_args.empty?
@@ -6,7 +6,7 @@
class Gem::Ext::ConfigureBuilder < Gem::Ext::Builder
- def self.build(extension, directory, dest_path, results, args=[])
unless File.exist?('Makefile') then
cmd = "sh ./configure --prefix=#{dest_path}"
cmd << " #{args.join ' '}" unless args.empty?
@@ -10,7 +10,7 @@ require 'tempfile'
class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
FileEntry = FileUtils::Entry_ # :nodoc:
- def self.build(extension, directory, dest_path, results, args=[])
tmp_dest = Dir.mktmpdir(".gem.", ".")
t = nil
@@ -44,6 +44,12 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
if tmp_dest
FileEntry.new(tmp_dest).traverse do |ent|
destent = ent.class.new(dest_path, ent.rel)
destent.exist? or File.rename(ent.path, destent.path)
end
@@ -6,7 +6,7 @@
class Gem::Ext::RakeBuilder < Gem::Ext::Builder
- def self.build(extension, directory, dest_path, results, args=[])
if File.basename(extension) =~ /mkrf_conf/i then
cmd = "#{Gem.ruby} #{File.basename extension}"
cmd << " #{args.join " "}" unless args.empty?
@@ -90,7 +90,7 @@ class Gem::RemoteFetcher
rescue Resolv::ResolvError
uri
else
- URI.parse "#{res.target}#{uri.path}"
end
end
@@ -1,6 +1,5 @@
require 'rubygems'
require 'rubygems/dependency'
-require 'rubygems/dependency_resolver'
require 'rubygems/dependency_list'
require 'rubygems/installer'
require 'tsort'
@@ -32,6 +31,11 @@ class Gem::RequestSet
attr_accessor :development
##
# Sets used for resolution
attr_reader :sets # :nodoc:
@@ -61,6 +65,7 @@ class Gem::RequestSet
@always_install = []
@dependency_names = {}
@development = false
@requests = []
@sets = []
@soft_missing = false
@@ -184,7 +189,8 @@ class Gem::RequestSet
# Load a dependency management file.
def load_gemdeps path, without_groups = []
- @vendor_set = Gem::DependencyResolver::VendorSet.new
gf = Gem::RequestSet::GemDependencyAPI.new self, path
gf.without_groups = without_groups if without_groups
@@ -195,13 +201,14 @@ class Gem::RequestSet
# Resolve the requested dependencies and return an Array of Specification
# objects to be activated.
- def resolve set = Gem::DependencyResolver::IndexSet.new
@sets << set
@sets << @vendor_set
- set = Gem::DependencyResolver.compose_sets(*@sets)
- resolver = Gem::DependencyResolver.new @dependencies, set
resolver.development = @development
resolver.soft_missing = @soft_missing
@@ -213,7 +220,7 @@ class Gem::RequestSet
# and return an Array of Specification objects to be activated.
def resolve_current
- resolve Gem::DependencyResolver::CurrentSet.new
end
def sorted_requests
@@ -108,6 +108,11 @@ class Gem::RequestSet::GemDependencyAPI
}
##
# A Hash containing gem names and files to require from those gems.
attr_reader :requires
@@ -130,13 +135,55 @@ class Gem::RequestSet::GemDependencyAPI
@set = set
@path = path
- @current_groups = nil
- @current_platform = nil
- @default_sources = true
- @requires = Hash.new { |h, name| h[name] = [] }
- @vendor_set = @set.vendor_set
- @gem_sources = {}
- @without_groups = []
end
##
@@ -160,7 +207,13 @@ class Gem::RequestSet::GemDependencyAPI
options = requirements.pop if requirements.last.kind_of?(Hash)
options ||= {}
- source_set = gem_path name, options
return unless gem_platforms options
@@ -182,6 +235,54 @@ class Gem::RequestSet::GemDependencyAPI
end
##
# Handles the :group and :groups +options+ for the gem with the given
# +name+.
@@ -269,6 +370,15 @@ class Gem::RequestSet::GemDependencyAPI
private :gem_requires
##
# Returns the basename of the file the dependencies were loaded from
@@ -278,6 +388,29 @@ class Gem::RequestSet::GemDependencyAPI
##
# :category: Gem Dependencies DSL
# Block form for placing a dependency in the given +groups+.
def group *groups
@@ -1,5 +1,3 @@
-require 'pathname'
-
class Gem::RequestSet::Lockfile
##
@@ -46,8 +44,8 @@ class Gem::RequestSet::Lockfile
def initialize request_set, gem_deps_file
@set = request_set
- @gem_deps_file = Pathname(gem_deps_file).expand_path
- @gem_deps_dir = @gem_deps_file.dirname
@current_token = nil
@line = 0
@@ -62,7 +60,7 @@ class Gem::RequestSet::Lockfile
@set.dependencies.sort.map do |dependency|
source = @requests.find do |req|
req.name == dependency.name and
- req.spec.class == Gem::DependencyResolver::VendorSpecification
end
source_dep = '!' if source
@@ -102,15 +100,26 @@ class Gem::RequestSet::Lockfile
out << nil
end
def add_PATH out # :nodoc:
return unless path_requests =
- @spec_groups.delete(Gem::DependencyResolver::VendorSpecification)
out << "PATH"
path_requests.each do |request|
- directory = Pathname(request.spec.source.uri).expand_path
- out << " remote: #{directory.relative_path_from @gem_deps_dir}"
out << " specs:"
out << " #{request.name} (#{request.version})"
end
@@ -208,7 +217,7 @@ class Gem::RequestSet::Lockfile
skip :newline
- set = Gem::DependencyResolver::LockSet.new source
while not @tokens.empty? and :text == peek.first do
_, name, = get :text
@@ -12,7 +12,7 @@ require 'net/http'
# objects which indicate all the specs that should be activated to meet the
# all the requirements.
-class Gem::DependencyResolver
##
# Contains all the conflicts encountered while doing resolution
@@ -38,20 +38,20 @@ class Gem::DependencyResolver
when 1 then
sets.first
else
- Gem::DependencyResolver::ComposedSet.new(*sets)
end
end
##
- # Provide a DependencyResolver that queries only against the already
# installed gems.
def self.for_current_gems needed
- new needed, Gem::DependencyResolver::CurrentSet.new
end
##
- # Create DependencyResolver object which will resolve the tree starting
# with +needed+ Dependency objects.
#
# +set+ is an object that provides where to look for specifications to
@@ -59,7 +59,7 @@ class Gem::DependencyResolver
# rubygems.org.
def initialize needed, set = nil
- @set = set || Gem::DependencyResolver::IndexSet.new
@needed = needed
@conflicts = []
@@ -68,6 +68,15 @@ class Gem::DependencyResolver
@soft_missing = false
end
##
# Creates an ActivationRequest for the given +dep+ and the last +possible+
# specification.
@@ -77,8 +86,10 @@ class Gem::DependencyResolver
def activation_request dep, possible # :nodoc:
spec = possible.pop
activation_request =
- Gem::DependencyResolver::ActivationRequest.new spec, dep, possible
return spec, activation_request
end
@@ -86,7 +97,7 @@ class Gem::DependencyResolver
def requests s, act, reqs=nil
s.dependencies.reverse_each do |d|
next if d.type == :development and not @development
- reqs = Gem::List.new Gem::DependencyResolver::DependencyRequest.new(d, act), reqs
end
@set.prefetch reqs
@@ -100,18 +111,18 @@ class Gem::DependencyResolver
def resolve
@conflicts = []
- needed = nil
@needed.reverse_each do |n|
- request = Gem::DependencyResolver::DependencyRequest.new n, nil
- needed = Gem::List.new request, needed
end
res = resolve_for needed, nil
raise Gem::DependencyResolutionError, res if
- res.kind_of? Gem::DependencyResolver::DependencyConflict
res.to_a
end
@@ -128,6 +139,8 @@ class Gem::DependencyResolver
until states.empty? do
state = states.pop
if conflict.for_spec? state.spec
state.conflicts << [state.spec, conflict]
return state
@@ -162,11 +175,11 @@ class Gem::DependencyResolver
# Otherwise, issue it on the requester's request itself.
if existing.others_possible? or existing.request.requester.nil? then
conflict =
- Gem::DependencyResolver::DependencyConflict.new dep, existing
else
- depreq = existing.request.requester.request
conflict =
- Gem::DependencyResolver::DependencyConflict.new depreq, existing, dep
end
@conflicts << conflict unless @conflicts.include? conflict
@@ -182,7 +195,7 @@ class Gem::DependencyResolver
# +spec+ is the Specification for this state.
# +possible+ is List of DependencyRequest objects that can be tried to
# find a complete set.
- # +conflicts+ is a [DependencyRequest, DependencyConflict] hit tried to
# activate the state.
#
State = Struct.new(:needed, :specs, :dep, :spec, :possibles, :conflicts) do
@@ -218,9 +231,9 @@ class Gem::DependencyResolver
# The State objects that are used to attempt the activation tree.
states = []
- while needed
- dep = needed.value
- needed = needed.tail
# If there is already a spec activated for the requested name...
if specs && existing = specs.find { |s| dep.name == s.name }
@@ -228,6 +241,7 @@ class Gem::DependencyResolver
next if dep.matches_spec? existing
conflict = handle_conflict dep, existing
state = find_conflict_state conflict, states
@@ -292,7 +306,9 @@ class Gem::DependencyResolver
# We may need to try all of +possible+, so we setup state to unwind back
# to current +needed+ and +specs+ so we can try another. This is code is
# what makes conflict resolution possible.
- states << State.new(needed, specs, dep, spec, possible, [])
needed = requests spec, act, needed
specs = Gem::List.prepend specs, act
@@ -341,24 +357,32 @@ class Gem::DependencyResolver
end
-require 'rubygems/dependency_resolver/activation_request'
-require 'rubygems/dependency_resolver/dependency_conflict'
-require 'rubygems/dependency_resolver/dependency_request'
-
-require 'rubygems/dependency_resolver/set'
-require 'rubygems/dependency_resolver/api_set'
-require 'rubygems/dependency_resolver/composed_set'
-require 'rubygems/dependency_resolver/best_set'
-require 'rubygems/dependency_resolver/current_set'
-require 'rubygems/dependency_resolver/index_set'
-require 'rubygems/dependency_resolver/installer_set'
-require 'rubygems/dependency_resolver/lock_set'
-require 'rubygems/dependency_resolver/vendor_set'
-
-require 'rubygems/dependency_resolver/specification'
-require 'rubygems/dependency_resolver/spec_specification'
-require 'rubygems/dependency_resolver/api_specification'
-require 'rubygems/dependency_resolver/index_specification'
-require 'rubygems/dependency_resolver/installed_specification'
-require 'rubygems/dependency_resolver/vendor_specification'
@@ -3,7 +3,7 @@
# Also contains a dependency that was used to introduce this
# activation.
-class Gem::DependencyResolver::ActivationRequest
attr_reader :request
@@ -19,7 +19,7 @@ class Gem::DependencyResolver::ActivationRequest
case other
when Gem::Specification
@spec == other
- when Gem::DependencyResolver::ActivationRequest
@spec == other.spec && @request == other.request
else
false
@@ -70,7 +70,7 @@ class Gem::DependencyResolver::ActivationRequest
def installed?
case @spec
- when Gem::DependencyResolver::VendorSpecification then
true
else
this_spec = full_spec
@@ -2,7 +2,7 @@
# The global rubygems pool, available via the rubygems.org API.
# Returns instances of APISpecification.
-class Gem::DependencyResolver::APISet < Gem::DependencyResolver::Set
##
# The URI for the dependency API this APISet uses.
@@ -28,7 +28,7 @@ class Gem::DependencyResolver::APISet < Gem::DependencyResolver::Set
versions(req.name).each do |ver|
if req.dependency.match? req.name, ver[:number]
- res << Gem::DependencyResolver::APISpecification.new(self, ver)
end
end
@@ -4,7 +4,7 @@
# This is used to avoid loading the full Specification object when all we need
# is the name, version, and dependencies.
-class Gem::DependencyResolver::APISpecification < Gem::DependencyResolver::Specification
##
# Creates an APISpecification for the given +set+ from the rubygems.org
@@ -3,7 +3,7 @@
#
# It combines IndexSet and APISet
-class Gem::DependencyResolver::BestSet < Gem::DependencyResolver::ComposedSet
##
# Creates a BestSet for the given +sources+ or Gem::sources if none are
@@ -1,4 +1,4 @@
-class Gem::DependencyResolver::ComposedSet < Gem::DependencyResolver::Set
attr_reader :sets # :nodoc:
@@ -2,7 +2,7 @@
# Used internally to indicate that a dependency conflicted
# with a spec that would be activated.
-class Gem::DependencyResolver::DependencyConflict
attr_reader :activated
@@ -23,6 +23,10 @@ class Gem::DependencyResolver::DependencyConflict
@failed_dep == other.failed_dep
end
##
# Return the 2 dependency objects that conflicted
@@ -94,3 +98,5 @@ class Gem::DependencyResolver::DependencyConflict
end
@@ -3,7 +3,7 @@
# all the normal settings that control where to look
# for installed gems.
-class Gem::DependencyResolver::CurrentSet < Gem::DependencyResolver::Set
def find_all req
req.dependency.matching_specs
@@ -2,7 +2,7 @@
# Used Internally. Wraps a Dependency object to also track which spec
# contained the Dependency.
-class Gem::DependencyResolver::DependencyRequest
attr_reader :dependency
@@ -17,7 +17,7 @@ class Gem::DependencyResolver::DependencyRequest
case other
when Gem::Dependency
@dependency == other
- when Gem::DependencyResolver::DependencyRequest
@dependency == other.dependency && @requester == other.requester
else
false
@@ -0,0 +1,81 @@
@@ -0,0 +1,16 @@
@@ -2,7 +2,7 @@
# The global rubygems pool represented via the traditional
# source index.
-class Gem::DependencyResolver::IndexSet < Gem::DependencyResolver::Set
def initialize source = nil # :nodoc:
@f =
@@ -38,7 +38,7 @@ class Gem::DependencyResolver::IndexSet < Gem::DependencyResolver::Set
@all[name].each do |uri, n|
if req.dependency.match? n then
- res << Gem::DependencyResolver::IndexSpecification.new(
self, n.name, n.version, uri, n.platform)
end
end
@@ -3,7 +3,7 @@
# delay needed to download full Specification objects when only the +name+
# and +version+ are needed.
-class Gem::DependencyResolver::IndexSpecification < Gem::DependencyResolver::Specification
##
# An IndexSpecification is created from the index format described in `gem
@@ -2,7 +2,7 @@
# An InstalledSpecification represents a gem that is already installed
# locally.
-class Gem::DependencyResolver::InstalledSpecification < Gem::DependencyResolver::SpecSpecification
def == other # :nodoc:
self.class === other and
@@ -2,7 +2,7 @@
# A set of gems for installation sourced from remote sources and local .gem
# files
-class Gem::DependencyResolver::InstallerSet < Gem::DependencyResolver::Set
##
# List of Gem::Specification objects that must always be installed.
@@ -64,14 +64,14 @@ class Gem::DependencyResolver::InstallerSet < Gem::DependencyResolver::Set
dep.matching_specs.each do |gemspec|
next if @always_install.include? gemspec
- res << Gem::DependencyResolver::InstalledSpecification.new(self, gemspec)
end unless @ignore_installed
if consider_local? then
local_source = Gem::Source::Local.new
if spec = local_source.find_gem(name, dep.requirement) then
- res << Gem::DependencyResolver::IndexSpecification.new(
self, spec.name, spec.version, local_source, spec.platform)
end
end
@@ -81,7 +81,7 @@ class Gem::DependencyResolver::InstallerSet < Gem::DependencyResolver::Set
@all[name].each do |remote_source, n|
if dep.match? n then
- res << Gem::DependencyResolver::IndexSpecification.new(
self, n.name, n.version, remote_source, n.platform)
end
end
@@ -1,7 +1,7 @@
##
# A set of gems from a gem dependencies lockfile.
-class Gem::DependencyResolver::LockSet < Gem::DependencyResolver::Set
attr_reader :specs # :nodoc:
@@ -24,8 +24,8 @@ class Gem::DependencyResolver::LockSet < Gem::DependencyResolver::Set
version = Gem::Version.new version
spec =
- Gem::DependencyResolver::IndexSpecification.new self, name, version,
- @source, platform
@specs << spec
end
@@ -0,0 +1,40 @@
@@ -1,13 +1,12 @@
##
-# DependencyResolver sets are used to look up specifications (and their
# dependencies) used in resolution. This set is abstract.
-class Gem::DependencyResolver::Set
##
- # The find_all method must be implemented. It returns all
- # DependencyResolver Specification objects matching the given
- # DependencyRequest +req+.
def find_all req
raise NotImplementedError
@@ -1,8 +1,8 @@
##
-# The DependencyResolver::SpecSpecification contains common functionality for
-# DependencyResolver specifications that are backed by a Gem::Specification.
-class Gem::DependencyResolver::SpecSpecification < Gem::DependencyResolver::Specification
attr_reader :spec # :nodoc:
@@ -1,9 +1,9 @@
##
-# A DependencyResolver::Specification contains a subset of the information
# contained in a Gem::Specification. Only the information necessary for
# dependency resolution in the resolver is included.
-class Gem::DependencyResolver::Specification
##
# The dependencies of the gem for this specification
@@ -6,14 +6,14 @@
#
# Example:
#
-# set = Gem::DependencyResolver::VendorSet.new
#
# set.add_vendor_gem 'rake', 'vendor/rake'
#
# The directory vendor/rake must contain an unpacked rake gem along with a
# rake.gemspec (watching the given name).
-class Gem::DependencyResolver::VendorSet < Gem::DependencyResolver::Set
def initialize # :nodoc:
@directories = {}
@@ -47,7 +47,7 @@ class Gem::DependencyResolver::VendorSet < Gem::DependencyResolver::Set
req.matches_spec? spec
end.map do |spec|
source = Gem::Source::Vendor.new @directories[spec]
- Gem::DependencyResolver::VendorSpecification.new self, spec, source
end
end
@@ -3,7 +3,7 @@
# and is being loaded through a gem dependencies file through the +path:+
# option.
-class Gem::DependencyResolver::VendorSpecification < Gem::DependencyResolver::SpecSpecification
def == other # :nodoc:
self.class === other and
@@ -28,7 +28,9 @@ class Gem::Source
case other
when Gem::Source::Installed,
Gem::Source::Local,
- Gem::Source::SpecificFile then
-1
when Gem::Source then
if !@uri
@@ -62,9 +64,9 @@ class Gem::Source
fetcher = Gem::RemoteFetcher.fetcher
fetcher.fetch_path bundler_api_uri, nil, true
rescue Gem::RemoteFetcher::FetchError
- Gem::DependencyResolver::IndexSet.new self
else
- Gem::DependencyResolver::APISet.new bundler_api_uri
end
end
@@ -90,12 +92,15 @@ class Gem::Source
end
end
- def fetch_spec(name)
fetcher = Gem::RemoteFetcher.fetcher
- spec_file_name = name.spec_name
- uri = @uri + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}"
cache_dir = cache_dir uri
@@ -139,7 +144,7 @@ class Gem::Source
file = FILES[type]
fetcher = Gem::RemoteFetcher.fetcher
file_name = "#{file}.#{Gem.marshal_version}"
- spec_path = @uri + "#{file_name}.gz"
cache_dir = cache_dir spec_path
local_file = File.join(cache_dir, file_name)
retried = false
@@ -163,18 +168,22 @@ class Gem::Source
def download(spec, dir=Dir.pwd)
fetcher = Gem::RemoteFetcher.fetcher
- fetcher.download spec, @uri.to_s, dir
end
def pretty_print q # :nodoc:
q.group 2, '[Remote:', ']' do
q.breakable
q.text @uri.to_s
end
end
end
require 'rubygems/source/installed'
require 'rubygems/source/specific_file'
require 'rubygems/source/local'
@@ -0,0 +1,189 @@
@@ -1,6 +1,9 @@
class Gem::Source::Installed < Gem::Source
- def initialize
@uri = nil
end
@@ -9,6 +12,8 @@ class Gem::Source::Installed < Gem::Source
def <=> other
case other
when Gem::Source::Installed then
0
when Gem::Source then
@@ -1,5 +1,10 @@
class Gem::Source::Local < Gem::Source
- def initialize
@specs = nil
@api_uri = nil
@uri = nil
@@ -26,7 +31,7 @@ class Gem::Source::Local < Gem::Source
"#<%s specs: %p>" % [self.class, keys]
end
- def load_specs(type)
names = []
@specs = {}
@@ -68,8 +73,8 @@ class Gem::Source::Local < Gem::Source
names
end
- def find_gem(gem_name, version=Gem::Requirement.default,
- prerelease=false)
load_specs :complete
found = []
@@ -91,7 +96,7 @@ class Gem::Source::Local < Gem::Source
found.max_by { |s| s.version }
end
- def fetch_spec(name)
load_specs :complete
if data = @specs[name]
@@ -101,7 +106,7 @@ class Gem::Source::Local < Gem::Source
end
end
- def download(spec, cache_dir=nil)
load_specs :complete
@specs.each do |name, data|
@@ -1,4 +1,12 @@
class Gem::Source::SpecificFile < Gem::Source
def initialize(file)
@uri = nil
@path = ::File.expand_path(file)
@@ -8,19 +16,22 @@ class Gem::Source::SpecificFile < Gem::Source
@name = @spec.name_tuple
end
attr_reader :spec
- def load_specs(*a)
[@name]
end
- def fetch_spec(name)
return @spec if name == @name
raise Gem::Exception, "Unable to find '#{name}'"
@spec
end
- def download(spec, dir=nil)
return @path if spec == @spec
raise Gem::Exception, "Unable to download '#{spec.full_name}'"
end
@@ -3,8 +3,22 @@
class Gem::Source::Vendor < Gem::Source::Installed
- def initialize uri
- @uri = uri
end
end
@@ -1,5 +1,18 @@
require 'rubygems/source'
class Gem::SourceList
include Enumerable
@@ -91,7 +104,7 @@ class Gem::SourceList
@sources.empty?
end
- def ==(other)
to_a == other
end
@@ -34,6 +34,10 @@ class Gem::SpecFetcher
@fetcher = nil
def self.fetcher
@fetcher ||= new
end
@@ -43,8 +47,8 @@ class Gem::SpecFetcher
end
##
- # Creates a new SpecFetcher. Ordinarily you want to use
- # Gem::SpecFetcher::fetcher which uses the Gem.sources.
#
# If you need to retrieve specifications from a different +source+, you can
# send it as an argument.
@@ -84,7 +88,11 @@ class Gem::SpecFetcher
rejected_specs = {}
if dependency.prerelease?
- type = :complete
elsif dependency.latest_version?
type = :latest
else
@@ -224,6 +232,12 @@ class Gem::SpecFetcher
tuples_for(source, :released)
names.sort
when :prerelease
tuples_for(source, :prerelease)
else
@@ -239,7 +253,11 @@ class Gem::SpecFetcher
[list, errors]
end
- def tuples_for(source, type, gracefully_ignore=false)
cache = @caches[type]
tuples =
@@ -12,6 +12,7 @@ require 'rubygems/platform'
require 'rubygems/deprecate'
require 'rubygems/basic_specification'
require 'rubygems/stub_specification'
# :stopdoc:
# date.rb can't be loaded for `make install` due to miniruby
@@ -2165,7 +2166,7 @@ class Gem::Specification < Gem::BasicSpecification
end
##
- # Used by Gem::DependencyResolver to order Gem::Specification objects
def source # :nodoc:
self
@@ -2363,7 +2364,7 @@ class Gem::Specification < Gem::BasicSpecification
builder << self
ast = builder.tree
- io = StringIO.new
io.set_encoding Encoding::UTF_8 if Object.const_defined? :Encoding
Psych::Visitors::Emitter.new(io).accept(ast)
@@ -233,6 +233,8 @@ class Gem::TestCase < MiniTest::Unit::TestCase
ruby
end
Gem.ensure_gem_subdirectories @gemhome
@orig_LOAD_PATH = $LOAD_PATH.dup
@@ -373,6 +375,64 @@ class Gem::TestCase < MiniTest::Unit::TestCase
end
##
# Builds and installs the Gem::Specification +spec+
def install_gem spec, options = {}
@@ -1082,21 +1142,21 @@ Also, a list:
end
##
- # Constructs a Gem::DependencyResolver::DependencyRequest from a
# Gem::Dependency +dep+, a +from_name+ and +from_version+ requesting the
# dependency and a +parent+ DependencyRequest
def dependency_request dep, from_name, from_version, parent = nil
remote = Gem::Source.new @uri
- parent ||= Gem::DependencyResolver::DependencyRequest.new \
dep, nil
- spec = Gem::DependencyResolver::IndexSpecification.new \
nil, from_name, from_version, remote, Gem::Platform::RUBY
- activation = Gem::DependencyResolver::ActivationRequest.new spec, parent
- Gem::DependencyResolver::DependencyRequest.new dep, activation
end
##
@@ -0,0 +1,65 @@
@@ -0,0 +1,34 @@