diff options
author | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-11-21 23:27:30 +0000 |
---|---|---|
committer | drbrain <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-11-21 23:27:30 +0000 |
commit | 5307d803f5cce7b14a6afd1d51f6d53ec85ca87d () | |
tree | aac2997a9ff000fbf2f1f9f27077bb7b2403f2c9 /lib | |
parent | b1529a30e08040b717adef8ac1fa8be1c060e7e1 (diff) |
* lib/rubygems: Update to RubyGems master 50a8210. Important changes
in this commit: RubyGems now automatically checks for gem.deps.rb or Gemfile when running ruby executables. This behavior is similar to `bundle exec rake`. This change may be reverted before Ruby 2.1.0 if too many bugs are found. * test/rubygems: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43767 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | lib/rubygems.rb | 99 | ||||
-rw-r--r-- | lib/rubygems/doctor.rb | 7 | ||||
-rw-r--r-- | lib/rubygems/exceptions.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/request_set.rb | 15 | ||||
-rw-r--r-- | lib/rubygems/request_set/gem_dependency_api.rb | 17 | ||||
-rw-r--r-- | lib/rubygems/resolver.rb | 51 | ||||
-rw-r--r-- | lib/rubygems/resolver/api_set.rb | 49 | ||||
-rw-r--r-- | lib/rubygems/resolver/api_specification.rb | 37 | ||||
-rw-r--r-- | lib/rubygems/resolver/composed_set.rb | 19 | ||||
-rw-r--r-- | lib/rubygems/resolver/conflict.rb | 41 | ||||
-rw-r--r-- | lib/rubygems/resolver/git_set.rb | 33 | ||||
-rw-r--r-- | lib/rubygems/resolver/requirement_list.rb | 4 | ||||
-rw-r--r-- | lib/rubygems/source.rb | 44 | ||||
-rw-r--r-- | lib/rubygems/source/git.rb | 55 | ||||
-rw-r--r-- | lib/rubygems/specification.rb | 14 | ||||
-rw-r--r-- | lib/rubygems/test_case.rb | 6 | ||||
-rw-r--r-- | lib/rubygems/util.rb | 29 |
17 files changed, 356 insertions, 166 deletions
@@ -215,50 +215,6 @@ module Gem end end - def self.detect_gemdeps - if path = ENV['RUBYGEMS_GEMDEPS'] - path = path.dup.untaint - - if path == "-" - here = Dir.pwd.untaint - start = here - - begin - while true - path = GEM_DEP_FILES.find { |f| File.file?(f) } - - if path - path = File.join here, path - break - end - - Dir.chdir ".." - - # If we're at a toplevel, stop. - return if Dir.pwd == here - - here = Dir.pwd - end - ensure - Dir.chdir start - end - end - - path.untaint - - return unless File.file? path - - rs = Gem::RequestSet.new - rs.load_gemdeps path - - rs.resolve_current.map do |s| - sp = s.full_spec - sp.activate - sp - end - end - end - ## # Find the full path to the executable for gem +name+. If the +exec_name+ # is not given, the gem's default_executable is chosen, otherwise the @@ -1035,6 +991,61 @@ module Gem load_plugin_files files end # FIX: Almost everywhere else we use the `def self.` way of defining class # methods, and then we switch over to `class << self` here. Pick one or the # other. @@ -27,10 +27,13 @@ class Gem::Doctor ['gems', ''], ] - raise 'Update REPOSITORY_EXTENSION_MAP' unless - Gem::REPOSITORY_SUBDIRECTORIES.sort == REPOSITORY_EXTENSION_MAP.map { |(k,_)| k }.sort ## # Creates a new Gem::Doctor that will clean up +gem_repository+. Only one # gem repository may be cleaned at a time. @@ -223,7 +223,7 @@ class Gem::UnsatisfiableDependencyError < Gem::Exception attr_reader :dependency ## - # Creates a new UnsatisfiableDepedencyError for the unsatisfiable # Gem::Resolver::DependencyRequest +dep+ def initialize dep, platform_mismatch=nil @@ -2,6 +2,7 @@ require 'rubygems' require 'rubygems/dependency' require 'rubygems/dependency_list' require 'rubygems/installer' require 'tsort' ## @@ -146,7 +147,15 @@ class Gem::RequestSet resolve - install options, &block end def install_into dir, force = true, options = {} @@ -201,7 +210,7 @@ class Gem::RequestSet # Resolve the requested dependencies and return an Array of Specification # objects to be activated. - def resolve set = Gem::Resolver::IndexSet.new @sets << set @sets << @git_set @sets << @vendor_set @@ -253,7 +262,7 @@ class Gem::RequestSet end else unless @soft_missing - raise Gem::DependencyError, "Unresolved depedency found during sorting - #{dep}" end end end @@ -115,7 +115,7 @@ class Gem::RequestSet::GemDependencyAPI ## # A Hash containing gem names and files to require from those gems. - attr_reader :requires ## # A set of gems that are loaded via the +:path+ option to #gem @@ -125,7 +125,7 @@ class Gem::RequestSet::GemDependencyAPI ## # The groups of gems to exclude from installation - attr_accessor :without_groups ## # Creates a new GemDependencyAPI that will add dependencies to the @@ -282,6 +282,8 @@ class Gem::RequestSet::GemDependencyAPI true end ## # Handles the :group and :groups +options+ for the gem with the given # +name+. @@ -361,7 +363,7 @@ class Gem::RequestSet::GemDependencyAPI def gem_requires name, options # :nodoc: if options.include? :require then if requires = options.delete(:require) then - @requires[name].concat requires end else @requires[name] << name @@ -370,6 +372,11 @@ class Gem::RequestSet::GemDependencyAPI private :gem_requires def git repository @current_repository = repository @@ -424,6 +431,8 @@ class Gem::RequestSet::GemDependencyAPI ## # :category: Gem Dependencies DSL def platform what @current_platform = what @@ -436,6 +445,8 @@ class Gem::RequestSet::GemDependencyAPI ## # :category: Gem Dependencies DSL alias :platforms :platform @@ -29,9 +29,23 @@ class Gem::Resolver attr_accessor :soft_missing def self.compose_sets *sets sets.compact! case sets.length when 0 then raise ArgumentError, 'one set in the composition must be non-nil' @@ -77,6 +91,15 @@ class Gem::Resolver end end ## # Creates an ActivationRequest for the given +dep+ and the last +possible+ # specification. @@ -134,8 +157,6 @@ class Gem::Resolver # If no good candidate is found, the first state is tried. def find_conflict_state conflict, states # :nodoc: - rejected = [] - until states.empty? do state = states.pop @@ -145,14 +166,9 @@ class Gem::Resolver state.conflicts << [state.spec, conflict] return state end - - rejected << state end - return rejected.shift - ensure - rejected = rejected.concat states - states.replace rejected end ## @@ -172,14 +188,23 @@ class Gem::Resolver # If the existing activation indicates that there are other possibles for # it, then issue the conflict on the dependency for the activation itself. - # Otherwise, issue it on the requester's request itself. - if existing.others_possible? or existing.request.requester.nil? then conflict = Gem::Resolver::Conflict.new dep, existing - else depreq = dep.requester.request conflict = Gem::Resolver::Conflict.new depreq, existing, dep end @conflicts << conflict unless @conflicts.include? conflict @@ -234,6 +259,8 @@ class Gem::Resolver while !needed.empty? dep = needed.remove explain :try, [dep, dep.requester ? dep.requester.request : :toplevel] # If there is already a spec activated for the requested name... if specs && existing = specs.find { |s| dep.name == s.name } @@ -284,7 +311,7 @@ class Gem::Resolver # Retry resolution with this spec and add it's dependencies spec, act = activation_request state.dep, state.possibles - needed = requests spec, act, state.needed specs = Gem::List.prepend state.specs, act return needed, specs @@ -10,13 +10,28 @@ class Gem::Resolver::APISet < Gem::Resolver::Set attr_reader :dep_uri # :nodoc: ## # Creates a new APISet that will retrieve gems from +uri+ using the RubyGems - # API described at http://guides.rubygems.org/rubygems-org-api - def initialize uri = 'https://rubygems.org/api/v1/dependencies' - uri = URI uri unless URI === uri # for ruby 1.8 - @data = Hash.new { |h,k| h[k] = [] } - @dep_uri = uri end ## @@ -41,15 +56,35 @@ class Gem::Resolver::APISet < Gem::Resolver::Set def prefetch reqs names = reqs.map { |r| r.dependency.name } - needed = names.find_all { |d| [email protected]?(d) } return if needed.empty? uri = @dep_uri + "?gems=#{needed.sort.join ','}" str = Gem::RemoteFetcher.fetcher.fetch_path uri Marshal.load(str).each do |ver| - @data[ver[:name]] << ver end end @@ -34,5 +34,42 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification @dependencies == other.dependencies end end @@ -1,17 +1,36 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set attr_reader :sets # :nodoc: def initialize *sets @sets = sets end def find_all req res = [] @sets.each { |s| res += s.find_all(req) } res end def prefetch reqs @sets.each { |s| s.prefetch(reqs) } end @@ -4,25 +4,38 @@ class Gem::Resolver::Conflict attr_reader :activated attr_reader :dependency attr_reader :failed_dep # :nodoc: def initialize(dependency, activated, failed_dep=dependency) @dependency = dependency @activated = activated @failed_dep = failed_dep end - def == other self.class === other and @dependency == other.dependency and @activated == other.activated and @failed_dep == other.failed_dep end def explain "<Conflict wanted: #{@failed_dep}, had: #{activated.spec.full_name}>" end @@ -41,11 +54,15 @@ class Gem::Resolver::Conflict activated = @activated.spec.full_name requirement = @failed_dep.dependency.requirement - " Activated %s instead of (%s) via:\n %s\n" % [ - activated, requirement, request_path.join(', ') ] end def for_spec?(spec) @dependency.name == spec.name end @@ -72,16 +89,17 @@ class Gem::Resolver::Conflict end ## - # Path of specifications that requested this dependency - def request_path - current = requester - path = [] while current do - path << current.spec.full_name - current = current.request.requester end path = ['user request (gem command or Gemfile)'] if path.empty? @@ -98,5 +116,8 @@ class Gem::Resolver::Conflict end -Gem::Resolver::DependencyConflict = Gem::Resolver::Conflict @@ -42,38 +42,27 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set # Finds all git gems matching +req+ def find_all req - @repositories.keys.select do |name| - name == req.name - end.map do |name| - @specs[name] || load_spec(name) - end.select do |spec| req.matches_spec? spec end end - def load_spec name - repository, reference = @repositories[name] - - source = Gem::Source::Git.new name, repository, reference - - spec = source.load_spec name - - git_spec = - Gem::Resolver::GitSpecification.new self, spec, source - - @specs[name] = git_spec - end - ## # Prefetches specifications from the git repositories in this set. def prefetch reqs - names = reqs.map { |req| req.name } - @repositories.each_key do |name| - next unless names.include? name - load_spec name end end @@ -37,4 +37,8 @@ class Gem::Resolver::RequirementList def remove @list.shift end end @@ -1,13 +1,30 @@ require 'uri' require 'fileutils' class Gem::Source - FILES = { :released => 'specs', :latest => 'latest_specs', :prerelease => 'prerelease_specs', } def initialize(uri) unless uri.kind_of? URI uri = URI.parse(uri.to_s) @@ -17,13 +34,17 @@ class Gem::Source @api_uri = nil end - attr_reader :uri - def api_uri require 'rubygems/remote_fetcher' @api_uri ||= Gem::RemoteFetcher.fetcher.api_endpoint uri end def <=>(other) case other when Gem::Source::Installed, @@ -46,13 +67,11 @@ class Gem::Source end end - include Comparable - - def ==(other) self.class === other and @uri == other.uri end - alias_method :eql?, :== ## # Returns a Set that can fetch specifications from this source. @@ -70,7 +89,7 @@ class Gem::Source end end - def hash @uri.hash end @@ -83,6 +102,9 @@ class Gem::Source File.join Gem.spec_cache_dir, "#{uri.host}%#{uri.port}", File.dirname(escaped_path) end def update_cache? @update_cache ||= begin @@ -166,6 +188,10 @@ class Gem::Source end end def download(spec, dir=Dir.pwd) fetcher = Gem::RemoteFetcher.fetcher fetcher.download spec, api_uri.to_s, dir @@ -176,7 +202,7 @@ class Gem::Source q.breakable q.text @uri.to_s if api = api_uri - g.text api end end end @@ -36,9 +36,11 @@ class Gem::Source::Git < Gem::Source attr_reader :need_submodules ## - # Creates a new git gem source for a gem with the given +name+ that will be - # loaded from +reference+ in +repository+. If +submodules+ is true, - # submodules will be checked out when the gem is installed. def initialize name, repository, reference, submodules = false super(nil) @@ -126,34 +128,6 @@ class Gem::Source::Git < Gem::Source end ## - # Loads a Gem::Specification for +name+ from this git repository. - - def load_spec name - cache - - gemspec_reference = "#{@reference}:#{name}.gemspec" - - Dir.chdir repo_cache_dir do - source = Gem::Util.popen @git, 'show', gemspec_reference - - source.force_encoding Encoding::UTF_8 if Object.const_defined? :Encoding - source.untaint - - begin - spec = eval source, binding, gemspec_reference - - return spec if Gem::Specification === spec - - warn "git gem specification for #{@repository} #{gemspec_reference} is not a Gem::Specification (#{spec.class} instead)." - rescue SignalException, SystemExit - raise - rescue SyntaxError, Exception - warn "invalid git gem specification for #{@repository} #{gemspec_reference}" - end - end - end - - ## # The directory where the git gem's repository will be cached. def repo_cache_dir # :nodoc: @@ -164,13 +138,30 @@ class Gem::Source::Git < Gem::Source # Converts the git reference for the repository into a commit hash. def rev_parse # :nodoc: - # HACK no safe equivalent of ` exists on 1.8.7 Dir.chdir repo_cache_dir do Gem::Util.popen(@git, 'rev-parse', @reference).strip end end ## # A hash for the git gem based on the git repository URI. def uri_hash # :nodoc: @@ -27,6 +27,7 @@ class Date; end # Gem::Specification.new do |s| # s.name = 'example' # s.version = '0.1.0' # s.summary = "This is an example!" # s.description = "Much longer explanation of the example!" # s.authors = ["Ruby Coder"] @@ -530,6 +531,7 @@ class Gem::Specification < Gem::BasicSpecification end ## # The license for this gem. # # The license must be a short name, no more than 64 characters. @@ -538,7 +540,12 @@ class Gem::Specification < Gem::BasicSpecification # text of the license should be inside of the gem when you build it. # # See http://opensource.org/licenses/alphabetical for a list of licenses and - # their abbreviations (or short names). # # You can set multiple licenses with #licenses= # @@ -550,6 +557,7 @@ class Gem::Specification < Gem::BasicSpecification end ## # The license(s) for the library. # # Each license must be a short name, no more than 64 characters. @@ -2526,8 +2534,8 @@ class Gem::Specification < Gem::BasicSpecification } warning <<-warning if licenses.empty? -licenses is empty. Use a license abbreviation from: - http://opensource.org/licenses/alphabetical warning validate_permissions @@ -1149,8 +1149,10 @@ Also, a list: def dependency_request dep, from_name, from_version, parent = nil remote = Gem::Source.new @uri - parent ||= Gem::Resolver::DependencyRequest.new \ - dep, nil spec = Gem::Resolver::IndexSpecification.new \ nil, from_name, from_version, remote, Gem::Platform::RUBY @@ -40,27 +40,24 @@ module Gem::Util # for a command. def self.popen *command - begin - r, = IO.popen command, &:read - rescue TypeError # ruby 1.8 only supports string command - r, w = IO.pipe - pid = fork do - STDIN.close - STDOUT.reopen w - exec(*command) - end - w.close - begin - return r.read - ensure - Process.wait pid - end end - end end |