diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-11-19 00:34:13 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-11-19 00:34:13 +0000 |
commit | a7fa4d5d9aab150ad4b0c3f3217fe444df69f527 () | |
tree | 88ab96d22f7228b556337aa7c34042d4fd279394 /lib | |
parent | e7ec3dad907f2c77f17faddb40a98b2ef4523222 (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.rb | 49 | ||||
-rw-r--r-- | lib/rubygems/LICENSE.txt | 75 | ||||
-rw-r--r-- | lib/rubygems/available_set.rb | 4 | ||||
-rw-r--r-- | lib/rubygems/basic_specification.rb | 8 | ||||
-rw-r--r-- | lib/rubygems/commands/install_command.rb | 23 | ||||
-rw-r--r-- | lib/rubygems/commands/which_command.rb | 5 | ||||
-rw-r--r-- | lib/rubygems/dependency_installer.rb | 32 | ||||
-rw-r--r-- | lib/rubygems/doctor.rb | 20 | ||||
-rw-r--r-- | lib/rubygems/errors.rb | 17 | ||||
-rw-r--r-- | lib/rubygems/exceptions.rb | 10 | ||||
-rw-r--r-- | lib/rubygems/ext/builder.rb | 3 | ||||
-rw-r--r-- | lib/rubygems/ext/cmake_builder.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/ext/configure_builder.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/ext/ext_conf_builder.rb | 8 | ||||
-rw-r--r-- | lib/rubygems/ext/rake_builder.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/remote_fetcher.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/request_set.rb | 19 | ||||
-rw-r--r-- | lib/rubygems/request_set/gem_dependency_api.rb | 149 | ||||
-rw-r--r-- | lib/rubygems/request_set/lockfile.rb | 27 | ||||
-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.rb | 81 | ||||
-rw-r--r-- | lib/rubygems/resolver/git_specification.rb | 16 | ||||
-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.rb | 40 | ||||
-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.rb | 25 | ||||
-rw-r--r-- | lib/rubygems/source/git.rb | 189 | ||||
-rw-r--r-- | lib/rubygems/source/installed.rb | 7 | ||||
-rw-r--r-- | lib/rubygems/source/local.rb | 17 | ||||
-rw-r--r-- | lib/rubygems/source/specific_file.rb | 17 | ||||
-rw-r--r-- | lib/rubygems/source/vendor.rb | 18 | ||||
-rw-r--r-- | lib/rubygems/source_list.rb | 15 | ||||
-rw-r--r-- | lib/rubygems/spec_fetcher.rb | 26 | ||||
-rw-r--r-- | lib/rubygems/specification.rb | 5 | ||||
-rw-r--r-- | lib/rubygems/test_case.rb | 70 | ||||
-rw-r--r-- | lib/rubygems/util.rb | 65 | ||||
-rw-r--r-- | lib/rubygems/util/stringio.rb | 34 |
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 @@ |