* 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
This commit is contained in:
drbrain 2013-11-19 00:34:13 +00:00
parent e7ec3dad90
commit a7fa4d5d9a
88 changed files with 1799 additions and 430 deletions

View File

@ -1,3 +1,28 @@
Tue Nov 19 09:33:52 2013 Eric Hodel <drbrain@segment7.net>
* 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]
Tue Nov 19 07:21:56 2013 Tanaka Akira <akr@fsij.org> Tue Nov 19 07:21:56 2013 Tanaka Akira <akr@fsij.org>
* configure.in (LOCALTIME_OVERFLOW_PROBLEM): Define it for cross * configure.in (LOCALTIME_OVERFLOW_PROBLEM): Define it for cross

View File

@ -8,7 +8,7 @@
require 'rbconfig' require 'rbconfig'
module Gem module Gem
VERSION = '2.2.0' VERSION = '2.2.0.preview.2'
end end
# Must be first since it unloads the prelude from 1.9.2 # 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. # The path where gem executables are to be installed.
def self.bindir(install_dir=Gem.dir) def self.bindir(install_dir=Gem.dir)
# TODO: move to Gem::Dirs
return File.join install_dir, 'bin' unless return File.join install_dir, 'bin' unless
install_dir.to_s == Gem.default_dir.to_s install_dir.to_s == Gem.default_dir.to_s
Gem.default_bindir Gem.default_bindir
@ -362,16 +361,21 @@ module Gem
Zlib::Deflate.deflate data Zlib::Deflate.deflate data
end end
# DOC: needs doc'd or :nodoc'd # Retrieve the PathSupport object that RubyGems uses to
# lookup files.
def self.paths def self.paths
@paths ||= Gem::PathSupport.new @paths ||= Gem::PathSupport.new
end end
# DOC: needs doc'd or :nodoc'd # Initialize the filesystem paths to use from +env+.
# +env+ is a hash-like object (typically ENV) that
# is queried for 'GEM_HOME', 'GEM_PATH', and 'GEM_SPEC_CACHE'
def self.paths=(env) def self.paths=(env)
clear_paths clear_paths
@paths = Gem::PathSupport.new env @paths = Gem::PathSupport.new env
Gem::Specification.dirs = @paths.path # FIX: home is at end Gem::Specification.dirs = @paths.path
end end
## ##
@ -380,12 +384,10 @@ module Gem
# FIXME deprecate these once everything else has been done -ebh # FIXME deprecate these once everything else has been done -ebh
def self.dir def self.dir
# TODO: raise "no"
paths.home paths.home
end end
def self.path def self.path
# TODO: raise "no"
paths.path paths.path
end end
@ -552,42 +554,30 @@ module Gem
private_class_method :find_home private_class_method :find_home
# FIXME deprecate these in 3.0
## ##
# Zlib::GzipReader wrapper that unzips +data+. # Zlib::GzipReader wrapper that unzips +data+.
def self.gunzip(data) def self.gunzip(data)
# TODO: move to utils require 'rubygems/util'
require 'stringio' Gem::Util.gunzip data
require 'zlib'
data = StringIO.new data
unzipped = Zlib::GzipReader.new(data).read
unzipped.force_encoding Encoding::BINARY if Object.const_defined? :Encoding
unzipped
end end
## ##
# Zlib::GzipWriter wrapper that zips +data+. # Zlib::GzipWriter wrapper that zips +data+.
def self.gzip(data) def self.gzip(data)
# TODO: move to utils require 'rubygems/util'
require 'stringio' Gem::Util.gzip data
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 end
## ##
# A Zlib::Inflate#inflate wrapper # A Zlib::Inflate#inflate wrapper
def self.inflate(data) def self.inflate(data)
# TODO: move to utils require 'rubygems/util'
require 'zlib' Gem::Util.inflate data
Zlib::Inflate.inflate data
end end
## ##
@ -693,7 +683,6 @@ module Gem
file = $1 file = $1
lineno = $2.to_i lineno = $2.to_i
# TODO: it is ALWAYS joined! STUPID!
[file, lineno] [file, lineno]
end end
@ -974,7 +963,6 @@ module Gem
paths = nil if paths == [nil] paths = nil if paths == [nil]
paths = paths.first if Array === Array(paths).first paths = paths.first if Array === Array(paths).first
self.paths = { "GEM_HOME" => home, "GEM_PATH" => paths } self.paths = { "GEM_HOME" => home, "GEM_PATH" => paths }
# TODO: self.paths = home, paths
end end
## ##
@ -1169,7 +1157,8 @@ module Gem
autoload :ConfigFile, 'rubygems/config_file' autoload :ConfigFile, 'rubygems/config_file'
autoload :Dependency, 'rubygems/dependency' autoload :Dependency, 'rubygems/dependency'
autoload :DependencyList, 'rubygems/dependency_list' autoload :DependencyList, 'rubygems/dependency_list'
autoload :DependencyResolver, 'rubygems/dependency_resolver' autoload :Resolver, 'rubygems/resolver'
autoload :DependencyResolver, 'rubygems/resolver'
autoload :PathSupport, 'rubygems/path_support' autoload :PathSupport, 'rubygems/path_support'
autoload :Platform, 'rubygems/platform' autoload :Platform, 'rubygems/platform'
autoload :RequestSet, 'rubygems/request_set' autoload :RequestSet, 'rubygems/request_set'

View File

@ -1,7 +1,7 @@
RubyGems is copyrighted free software by Chad Fowler, Rich Kilmer, Jim RubyGems is copyrighted free software by Chad Fowler, Rich Kilmer, Jim
Weirich and others. You can redistribute it and/or modify it under 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 either the terms of the MIT license (see the file MIT.txt), or the
below: conditions below:
1. You may make and give away verbatim copies of the source form of the 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 software without restriction, provided that you duplicate all of the
@ -10,33 +10,33 @@ below:
2. You may modify your copy of the software in any way, provided that 2. You may modify your copy of the software in any way, provided that
you do at least ONE of the following: you do at least ONE of the following:
a) place your modifications in the Public Domain or otherwise a. place your modifications in the Public Domain or otherwise
make them Freely Available, such as by posting said make them Freely Available, such as by posting said
modifications to Usenet or an equivalent medium, or by allowing modifications to Usenet or an equivalent medium, or by allowing
the author to include your modifications in the software. the author to include your modifications in the software.
b) use the modified software only within your corporation or b. use the modified software only within your corporation or
organization. organization.
c) rename any non-standard executables so the names do not conflict c. give non-standard executables non-standard names, with
with standard executables, which must also be provided. instructions on where to get the original software distribution.
d) make other distribution arrangements with the author. d. make other distribution arrangements with the author.
3. You may distribute the software in object code or executable 3. You may distribute the software in object code or executable
form, provided that you do at least ONE of the following: form, provided that you do at least ONE of the following:
a) distribute the executables and library files of the software, a. distribute the executables and library files of the software,
together with instructions (in the manual page or equivalent) together with instructions (in the manual page or equivalent)
on where to get the original distribution. on where to get the original distribution.
b) accompany the distribution with the machine-readable source of b. accompany the distribution with the machine-readable source of
the software. the software.
c) give non-standard executables non-standard names, with c. give non-standard executables non-standard names, with
instructions on where to get the original software distribution. instructions on where to get the original software distribution.
d) make other distribution arrangements with the author. d. make other distribution arrangements with the author.
4. You may modify and include the part of the software into any other 4. You may modify and include the part of the software into any other
software (possibly commercial). software (possibly commercial).
@ -51,3 +51,4 @@ below:
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. PURPOSE.

View File

@ -116,7 +116,7 @@ class Gem::AvailableSet
## ##
# #
# Used by the DependencyResolver, the protocol to use a AvailableSet as a # Used by the Resolver, the protocol to use a AvailableSet as a
# search Set. # search Set.
def find_all(req) def find_all(req)
@ -127,7 +127,7 @@ class Gem::AvailableSet
end end
match.map do |t| match.map do |t|
Gem::DependencyResolver::InstalledSpecification.new(self, t.spec, t.source) Gem::Resolver::InstalledSpecification.new(self, t.spec, t.source)
end end
end end

View File

@ -107,7 +107,7 @@ class Gem::BasicSpecification
File.join full_gem_path, path File.join full_gem_path, path
end end
full_paths << extension_install_dir unless @extensions.empty? full_paths.unshift extension_install_dir unless @extensions.empty?
full_paths full_paths
end end
@ -155,6 +155,10 @@ class Gem::BasicSpecification
raise NotImplementedError raise NotImplementedError
end end
def raw_require_paths # :nodoc:
@require_paths
end
## ##
# Paths in the gem to add to <code>$LOAD_PATH</code> when this gem is # Paths in the gem to add to <code>$LOAD_PATH</code> when this gem is
# activated. # activated.
@ -179,7 +183,7 @@ class Gem::BasicSpecification
File.join '..', '..', 'extensions', Gem::Platform.local.to_s, File.join '..', '..', 'extensions', Gem::Platform.local.to_s,
Gem.extension_api_version, full_name Gem.extension_api_version, full_name
@require_paths + [relative_extension_install_dir] [relative_extension_install_dir].concat @require_paths
end end
## ##

View File

@ -56,6 +56,12 @@ class Gem::Commands::InstallCommand < Gem::Command
o[:install_as_default] = v o[:install_as_default] = v
end end
add_option(:"Install/Update", '--explain',
'Rather than install the gems, indicate which would',
'be installed') do |v,o|
o[:explain] = v
end
@installed_specs = nil @installed_specs = nil
end end
@ -185,8 +191,23 @@ to write the specification by hand. For example:
return if options[:conservative] and return if options[:conservative] and
not Gem::Dependency.new(name, version).matching_specs.empty? not Gem::Dependency.new(name, version).matching_specs.empty?
req = Gem::Requirement.create(version)
inst = Gem::DependencyInstaller.new options inst = Gem::DependencyInstaller.new options
inst.install name, Gem::Requirement.create(version)
if options[:explain]
request_set = inst.resolve_dependencies name, req
puts "Gems to install:"
request_set.specs.map { |s| s.full_name }.sort.each do |s|
puts " #{s}"
end
return
else
inst.install name, req
end
@installed_specs.push(*inst.installed_gems) @installed_specs.push(*inst.installed_gems)

View File

@ -35,7 +35,7 @@ requiring to see why it does not behave as you expect.
end end
def execute def execute
found = false found = true
options[:args].each do |arg| options[:args].each do |arg|
arg = arg.sub(/#{Regexp.union(*Gem.suffixes)}$/, '') 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 if paths.empty? then
alert_error "Can't find ruby library file or shared library #{arg}" alert_error "Can't find ruby library file or shared library #{arg}"
found &&= false
else else
say paths say paths
found = true
end end
end end

View File

@ -1,6 +1,5 @@
require 'rubygems' require 'rubygems'
require 'rubygems/dependency_list' require 'rubygems/dependency_list'
require 'rubygems/dependency_resolver'
require 'rubygems/package' require 'rubygems/package'
require 'rubygems/installer' require 'rubygems/installer'
require 'rubygems/spec_fetcher' require 'rubygems/spec_fetcher'
@ -196,7 +195,7 @@ class Gem::DependencyInstaller
# sources. Gems are sorted with newer gems preferred over older gems, and # sources. Gems are sorted with newer gems preferred over older gems, and
# local gems preferred over remote gems. # local gems preferred over remote gems.
def find_gems_with_sources dep # :nodoc: def find_gems_with_sources dep, best_only=false # :nodoc:
set = Gem::AvailableSet.new set = Gem::AvailableSet.new
if consider_local? if consider_local?
@ -211,7 +210,26 @@ class Gem::DependencyInstaller
if consider_remote? if consider_remote?
begin begin
found, errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep # TODO this is pulled from #spec_for_dependency to allow
# us to filter tuples before fetching specs.
#
tuples, errors = Gem::SpecFetcher.fetcher.search_for_dependency dep
if best_only && !tuples.empty?
tuples.sort! { |a,b| b[0].version <=> a[0].version }
tuples = [tuples.first]
end
specs = []
tuples.each do |tup, source|
begin
spec = source.fetch_spec(tup)
rescue Gem::RemoteFetcher::FetchError => e
errors << Gem::SourceFetchProblem.new(source, e)
else
specs << [spec, source]
end
end
if @errors if @errors
@errors += errors @errors += errors
@ -219,7 +237,7 @@ class Gem::DependencyInstaller
@errors = errors @errors = errors
end end
set << found set << specs
rescue Gem::RemoteFetcher::FetchError => e rescue Gem::RemoteFetcher::FetchError => e
# FIX if there is a problem talking to the network, we either need to always tell # 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 = Gem::Dependency.new gem_name, version
dep.prerelease = true if prerelease dep.prerelease = true if prerelease
set = find_gems_with_sources(dep) set = find_gems_with_sources(dep, true)
set.match_platform! set.match_platform!
end end
@ -402,7 +420,7 @@ class Gem::DependencyInstaller
request_set = as.to_request_set install_development_deps request_set = as.to_request_set install_development_deps
request_set.soft_missing = @force request_set.soft_missing = @force
installer_set = Gem::DependencyResolver::InstallerSet.new @domain installer_set = Gem::Resolver::InstallerSet.new @domain
installer_set.always_install.concat request_set.always_install installer_set.always_install.concat request_set.always_install
installer_set.ignore_installed = @only_install_dir installer_set.ignore_installed = @only_install_dir
@ -411,7 +429,7 @@ class Gem::DependencyInstaller
request_set.soft_missing = true request_set.soft_missing = true
end end
composed_set = Gem::DependencyResolver.compose_sets as, installer_set composed_set = Gem::Resolver.compose_sets as, installer_set
request_set.resolve composed_set request_set.resolve composed_set

View File

@ -1,6 +1,5 @@
require 'rubygems' require 'rubygems'
require 'rubygems/user_interaction' require 'rubygems/user_interaction'
require 'pathname'
## ##
# Cleans up after a partially-failed uninstall or for an invalid # 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. # If +dry_run+ is true no files or directories will be removed.
def initialize gem_repository, dry_run = false def initialize gem_repository, dry_run = false
@gem_repository = Pathname(gem_repository) @gem_repository = gem_repository
@dry_run = dry_run @dry_run = dry_run
@installed_specs = nil @installed_specs = nil
@ -97,26 +96,29 @@ class Gem::Doctor
# Removes files in +sub_directory+ with +extension+ # Removes files in +sub_directory+ with +extension+
def doctor_child sub_directory, extension # :nodoc: def doctor_child sub_directory, extension # :nodoc:
directory = @gem_repository + sub_directory directory = File.join(@gem_repository, sub_directory)
directory.children.sort.each do |child| Dir.entries(directory).sort.each do |ent|
next unless child.exist? next if ent == "." || ent == ".."
basename = child.basename(extension).to_s child = File.join(directory, ent)
next unless File.exists?(child)
basename = File.basename(child, extension)
next if installed_specs.include? basename next if installed_specs.include? basename
next if /^rubygems-\d/ =~ basename next if /^rubygems-\d/ =~ basename
next if 'specifications' == sub_directory and 'default' == basename next if 'specifications' == sub_directory and 'default' == basename
type = child.directory? ? 'directory' : 'file' type = File.directory?(child) ? 'directory' : 'file'
action = if @dry_run then action = if @dry_run then
'Extra' 'Extra'
else else
child.rmtree FileUtils.rm_r(child)
'Removed' 'Removed'
end end
say "#{action} #{type} #{sub_directory}/#{child.basename}" say "#{action} #{type} #{sub_directory}/#{File.basename(child)}"
end end
rescue Errno::ENOENT rescue Errno::ENOENT
# ignore # ignore

View File

@ -73,12 +73,27 @@ module Gem
# data from a source # data from a source
class SourceFetchProblem < ErrorReason class SourceFetchProblem < ErrorReason
##
# Creates a new SourceFetchProblem for the given +source+ and +error+.
def initialize(source, error) def initialize(source, error)
@source = source @source = source
@error = error @error = error
end end
attr_reader :source, :error ##
# The source that had the fetch problem.
attr_reader :source
##
# The fetch error which is an Exception subclass.
attr_reader :error
##
# An English description of the error.
def wordy def wordy
"Unable to download data from #{@source.uri} - #{@error.message}" "Unable to download data from #{@source.uri} - #{@error.message}"

View File

@ -23,7 +23,7 @@ class Gem::DependencyError < Gem::Exception; end
class Gem::DependencyRemovalException < Gem::Exception; end class Gem::DependencyRemovalException < Gem::Exception; end
## ##
# Raised by Gem::DependencyResolver when a Gem::DependencyConflict reaches the # Raised by Gem::Resolver when a Gem::Dependency::Conflict reaches the
# toplevel. Indicates which dependencies were incompatible through #conflict # toplevel. Indicates which dependencies were incompatible through #conflict
# and #conflicting_dependencies # and #conflicting_dependencies
@ -117,7 +117,7 @@ class Gem::SpecificGemNotFoundException < Gem::GemNotFoundException
end end
## ##
# Raised by Gem::DependencyResolver when dependencies conflict and create the # Raised by Gem::Resolver when dependencies conflict and create the
# inability to find a valid possible spec for a request. # inability to find a valid possible spec for a request.
class Gem::ImpossibleDependenciesError < Gem::Exception class Gem::ImpossibleDependenciesError < Gem::Exception
@ -211,20 +211,20 @@ class Gem::SystemExitException < SystemExit
end end
## ##
# Raised by DependencyResolver when a dependency requests a gem for which # Raised by Resolver when a dependency requests a gem for which
# there is no spec. # there is no spec.
class Gem::UnsatisfiableDependencyError < Gem::Exception class Gem::UnsatisfiableDependencyError < Gem::Exception
## ##
# The unsatisfiable dependency. This is a # The unsatisfiable dependency. This is a
# Gem::DependencyResolver::DependencyRequest, not a Gem::Dependency # Gem::Resolver::DependencyRequest, not a Gem::Dependency
attr_reader :dependency attr_reader :dependency
## ##
# Creates a new UnsatisfiableDepedencyError for the unsatisfiable # Creates a new UnsatisfiableDepedencyError for the unsatisfiable
# Gem::DependencyResolver::DependencyRequest +dep+ # Gem::Resolver::DependencyRequest +dep+
def initialize dep, platform_mismatch=nil def initialize dep, platform_mismatch=nil
if platform_mismatch and !platform_mismatch.empty? if platform_mismatch and !platform_mismatch.empty?

View File

@ -149,6 +149,7 @@ EOF
extension ||= '' # I wish I knew why this line existed extension ||= '' # I wish I knew why this line existed
extension_dir = extension_dir =
File.expand_path File.join @gem_dir, File.dirname(extension) File.expand_path File.join @gem_dir, File.dirname(extension)
lib_dir = File.join @spec.full_gem_path, @spec.raw_require_paths.first
builder = builder_for extension builder = builder_for extension
@ -158,7 +159,7 @@ EOF
CHDIR_MUTEX.synchronize do CHDIR_MUTEX.synchronize do
Dir.chdir extension_dir do Dir.chdir extension_dir do
results = builder.build(extension, @gem_dir, dest_path, results = builder.build(extension, @gem_dir, dest_path,
results, @build_args) results, @build_args, lib_dir)
say results.join("\n") if Gem.configuration.really_verbose say results.join("\n") if Gem.configuration.really_verbose
end end

View File

@ -1,7 +1,7 @@
require 'rubygems/command' require 'rubygems/command'
class Gem::Ext::CmakeBuilder < Gem::Ext::Builder class Gem::Ext::CmakeBuilder < Gem::Ext::Builder
def self.build(extension, directory, dest_path, results) def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
unless File.exist?('Makefile') then unless File.exist?('Makefile') then
cmd = "cmake . -DCMAKE_INSTALL_PREFIX=#{dest_path}" cmd = "cmake . -DCMAKE_INSTALL_PREFIX=#{dest_path}"
cmd << " #{Gem::Command.build_args.join ' '}" unless Gem::Command.build_args.empty? cmd << " #{Gem::Command.build_args.join ' '}" unless Gem::Command.build_args.empty?

View File

@ -6,7 +6,7 @@
class Gem::Ext::ConfigureBuilder < Gem::Ext::Builder class Gem::Ext::ConfigureBuilder < Gem::Ext::Builder
def self.build(extension, directory, dest_path, results, args=[]) def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
unless File.exist?('Makefile') then unless File.exist?('Makefile') then
cmd = "sh ./configure --prefix=#{dest_path}" cmd = "sh ./configure --prefix=#{dest_path}"
cmd << " #{args.join ' '}" unless args.empty? cmd << " #{args.join ' '}" unless args.empty?

View File

@ -10,7 +10,7 @@ require 'tempfile'
class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
FileEntry = FileUtils::Entry_ # :nodoc: FileEntry = FileUtils::Entry_ # :nodoc:
def self.build(extension, directory, dest_path, results, args=[]) def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
tmp_dest = Dir.mktmpdir(".gem.", ".") tmp_dest = Dir.mktmpdir(".gem.", ".")
t = nil t = nil
@ -44,6 +44,12 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
if tmp_dest if tmp_dest
FileEntry.new(tmp_dest).traverse do |ent| FileEntry.new(tmp_dest).traverse do |ent|
# TODO remove in RubyGems 3
if lib_dir then
libent = ent.class.new lib_dir, ent.rel
libent.exist? or ent.copy libent.path
end
destent = ent.class.new(dest_path, ent.rel) destent = ent.class.new(dest_path, ent.rel)
destent.exist? or File.rename(ent.path, destent.path) destent.exist? or File.rename(ent.path, destent.path)
end end

View File

@ -6,7 +6,7 @@
class Gem::Ext::RakeBuilder < Gem::Ext::Builder class Gem::Ext::RakeBuilder < Gem::Ext::Builder
def self.build(extension, directory, dest_path, results, args=[]) def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
if File.basename(extension) =~ /mkrf_conf/i then if File.basename(extension) =~ /mkrf_conf/i then
cmd = "#{Gem.ruby} #{File.basename extension}" cmd = "#{Gem.ruby} #{File.basename extension}"
cmd << " #{args.join " "}" unless args.empty? cmd << " #{args.join " "}" unless args.empty?

View File

@ -90,7 +90,7 @@ class Gem::RemoteFetcher
rescue Resolv::ResolvError rescue Resolv::ResolvError
uri uri
else else
URI.parse "#{res.target}#{uri.path}" URI.parse "#{uri.scheme}://#{res.target}#{uri.path}"
end end
end end

View File

@ -1,6 +1,5 @@
require 'rubygems' require 'rubygems'
require 'rubygems/dependency' require 'rubygems/dependency'
require 'rubygems/dependency_resolver'
require 'rubygems/dependency_list' require 'rubygems/dependency_list'
require 'rubygems/installer' require 'rubygems/installer'
require 'tsort' require 'tsort'
@ -31,6 +30,11 @@ class Gem::RequestSet
attr_accessor :development attr_accessor :development
##
# The set of git gems imported via load_gemdeps.
attr_reader :git_set # :nodoc:
## ##
# Sets used for resolution # Sets used for resolution
@ -61,6 +65,7 @@ class Gem::RequestSet
@always_install = [] @always_install = []
@dependency_names = {} @dependency_names = {}
@development = false @development = false
@git_set = nil
@requests = [] @requests = []
@sets = [] @sets = []
@soft_missing = false @soft_missing = false
@ -184,7 +189,8 @@ class Gem::RequestSet
# Load a dependency management file. # Load a dependency management file.
def load_gemdeps path, without_groups = [] def load_gemdeps path, without_groups = []
@vendor_set = Gem::DependencyResolver::VendorSet.new @git_set = Gem::Resolver::GitSet.new
@vendor_set = Gem::Resolver::VendorSet.new
gf = Gem::RequestSet::GemDependencyAPI.new self, path gf = Gem::RequestSet::GemDependencyAPI.new self, path
gf.without_groups = without_groups if without_groups 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 # Resolve the requested dependencies and return an Array of Specification
# objects to be activated. # objects to be activated.
def resolve set = Gem::DependencyResolver::IndexSet.new def resolve set = Gem::Resolver::IndexSet.new
@sets << set @sets << set
@sets << @git_set
@sets << @vendor_set @sets << @vendor_set
set = Gem::DependencyResolver.compose_sets(*@sets) set = Gem::Resolver.compose_sets(*@sets)
resolver = Gem::DependencyResolver.new @dependencies, set resolver = Gem::Resolver.new @dependencies, set
resolver.development = @development resolver.development = @development
resolver.soft_missing = @soft_missing resolver.soft_missing = @soft_missing
@ -213,7 +220,7 @@ class Gem::RequestSet
# and return an Array of Specification objects to be activated. # and return an Array of Specification objects to be activated.
def resolve_current def resolve_current
resolve Gem::DependencyResolver::CurrentSet.new resolve Gem::Resolver::CurrentSet.new
end end
def sorted_requests def sorted_requests

View File

@ -107,6 +107,11 @@ class Gem::RequestSet::GemDependencyAPI
:x64_mingw_21 => :only, :x64_mingw_21 => :only,
} }
##
# A set of gems that are loaded via the +:git+ option to #gem
attr_reader :git_set # :nodoc:
## ##
# A Hash containing gem names and files to require from those gems. # A Hash containing gem names and files to require from those gems.
@ -132,13 +137,55 @@ class Gem::RequestSet::GemDependencyAPI
@current_groups = nil @current_groups = nil
@current_platform = nil @current_platform = nil
@current_repository = nil
@default_sources = true @default_sources = true
@git_set = @set.git_set
@requires = Hash.new { |h, name| h[name] = [] } @requires = Hash.new { |h, name| h[name] = [] }
@vendor_set = @set.vendor_set @vendor_set = @set.vendor_set
@gem_sources = {} @gem_sources = {}
@without_groups = [] @without_groups = []
end end
##
# Adds +dependencies+ to the request set if any of the +groups+ are allowed.
# This is used for gemspec dependencies.
def add_dependencies groups, dependencies # :nodoc:
return unless (groups & @without_groups).empty?
dependencies.each do |dep|
@set.gem dep.name, *dep.requirement
end
end
private :add_dependencies
##
# Finds a gemspec with the given +name+ that lives at +path+.
def find_gemspec name, path # :nodoc:
glob = File.join path, "#{name}.gemspec"
spec_files = Dir[glob]
case spec_files.length
when 1 then
spec_file = spec_files.first
spec = Gem::Specification.load spec_file
return spec if spec
raise ArgumentError, "invalid gemspec #{spec_file}"
when 0 then
raise ArgumentError, "no gemspecs found at #{Dir.pwd}"
else
raise ArgumentError,
"found multiple gemspecs at #{Dir.pwd}, " +
"use the name: option to specify the one you want"
end
end
## ##
# Loads the gem dependency file # Loads the gem dependency file
@ -160,7 +207,13 @@ class Gem::RequestSet::GemDependencyAPI
options = requirements.pop if requirements.last.kind_of?(Hash) options = requirements.pop if requirements.last.kind_of?(Hash)
options ||= {} options ||= {}
source_set = gem_path name, options options[:git] = @current_repository if @current_repository
source_set = false
source_set ||= gem_path name, options
source_set ||= gem_git name, options
source_set ||= gem_github name, options
return unless gem_platforms options return unless gem_platforms options
@ -181,6 +234,54 @@ class Gem::RequestSet::GemDependencyAPI
@set.gem name, *requirements @set.gem name, *requirements
end end
##
# Handles the git: option from +options+ for gem +name+.
#
# Returns +true+ if the path option was handled.
def gem_git name, options # :nodoc:
if gist = options.delete(:gist) then
options[:git] = "https://gist.github.com/#{gist}.git"
end
return unless repository = options.delete(:git)
raise ArgumentError,
"duplicate source git: #{repository} for gem #{name}" if
@gem_sources.include? name
reference = nil
reference ||= options.delete :ref
reference ||= options.delete :branch
reference ||= options.delete :tag
reference ||= 'master'
submodules = options.delete :submodules
@git_set.add_git_gem name, repository, reference, submodules
@gem_sources[name] = repository
true
end
private :gem_git
##
# Handles the github: option from +options+ for gem +name+.
#
# Returns +true+ if the path option was handled.
def gem_github name, options # :nodoc:
return unless path = options.delete(:github)
options[:git] = "git://github.com/#{path}.git"
gem_git name, options
true
end
## ##
# Handles the :group and :groups +options+ for the gem with the given # Handles the :group and :groups +options+ for the gem with the given
# +name+. # +name+.
@ -269,6 +370,15 @@ class Gem::RequestSet::GemDependencyAPI
private :gem_requires private :gem_requires
def git repository
@current_repository = repository
yield
ensure
@current_repository = nil
end
## ##
# Returns the basename of the file the dependencies were loaded from # Returns the basename of the file the dependencies were loaded from
@ -276,6 +386,29 @@ class Gem::RequestSet::GemDependencyAPI
File.basename @path File.basename @path
end end
##
# :category: Gem Dependencies DSL
#
# Loads dependencies from a gemspec file.
def gemspec options = {}
name = options.delete(:name) || '{,*}'
path = options.delete(:path) || '.'
development_group = options.delete(:development_group) || :development
spec = find_gemspec name, path
groups = gem_group spec.name, {}
add_dependencies groups, spec.runtime_dependencies
groups << development_group
add_dependencies groups, spec.development_dependencies
gem_requires spec.name, options
end
## ##
# :category: Gem Dependencies DSL # :category: Gem Dependencies DSL
# Block form for placing a dependency in the given +groups+. # Block form for placing a dependency in the given +groups+.

View File

@ -1,5 +1,3 @@
require 'pathname'
class Gem::RequestSet::Lockfile class Gem::RequestSet::Lockfile
## ##
@ -46,8 +44,8 @@ class Gem::RequestSet::Lockfile
def initialize request_set, gem_deps_file def initialize request_set, gem_deps_file
@set = request_set @set = request_set
@gem_deps_file = Pathname(gem_deps_file).expand_path @gem_deps_file = File.expand_path(gem_deps_file)
@gem_deps_dir = @gem_deps_file.dirname @gem_deps_dir = File.dirname(@gem_deps_file)
@current_token = nil @current_token = nil
@line = 0 @line = 0
@ -62,7 +60,7 @@ class Gem::RequestSet::Lockfile
@set.dependencies.sort.map do |dependency| @set.dependencies.sort.map do |dependency|
source = @requests.find do |req| source = @requests.find do |req|
req.name == dependency.name and req.name == dependency.name and
req.spec.class == Gem::DependencyResolver::VendorSpecification req.spec.class == Gem::Resolver::VendorSpecification
end end
source_dep = '!' if source source_dep = '!' if source
@ -102,15 +100,26 @@ class Gem::RequestSet::Lockfile
out << nil out << nil
end end
def relative_path_from(dest, base)
dest = File.expand_path(dest)
base = File.expand_path(base)
if dest.index(base) == 0
return dest[base.size+1..-1]
else
dest
end
end
def add_PATH out # :nodoc: def add_PATH out # :nodoc:
return unless path_requests = return unless path_requests =
@spec_groups.delete(Gem::DependencyResolver::VendorSpecification) @spec_groups.delete(Gem::Resolver::VendorSpecification)
out << "PATH" out << "PATH"
path_requests.each do |request| path_requests.each do |request|
directory = Pathname(request.spec.source.uri).expand_path directory = File.expand_path(request.spec.source.uri)
out << " remote: #{directory.relative_path_from @gem_deps_dir}" out << " remote: #{relative_path_from directory, @gem_deps_dir}"
out << " specs:" out << " specs:"
out << " #{request.name} (#{request.version})" out << " #{request.name} (#{request.version})"
end end
@ -208,7 +217,7 @@ class Gem::RequestSet::Lockfile
skip :newline skip :newline
set = Gem::DependencyResolver::LockSet.new source set = Gem::Resolver::LockSet.new source
while not @tokens.empty? and :text == peek.first do while not @tokens.empty? and :text == peek.first do
_, name, = get :text _, name, = get :text

View File

@ -12,7 +12,7 @@ require 'net/http'
# objects which indicate all the specs that should be activated to meet the # objects which indicate all the specs that should be activated to meet the
# all the requirements. # all the requirements.
class Gem::DependencyResolver class Gem::Resolver
## ##
# Contains all the conflicts encountered while doing resolution # Contains all the conflicts encountered while doing resolution
@ -38,20 +38,20 @@ class Gem::DependencyResolver
when 1 then when 1 then
sets.first sets.first
else else
Gem::DependencyResolver::ComposedSet.new(*sets) Gem::Resolver::ComposedSet.new(*sets)
end end
end end
## ##
# Provide a DependencyResolver that queries only against the already # Provide a Resolver that queries only against the already
# installed gems. # installed gems.
def self.for_current_gems needed def self.for_current_gems needed
new needed, Gem::DependencyResolver::CurrentSet.new new needed, Gem::Resolver::CurrentSet.new
end end
## ##
# Create DependencyResolver object which will resolve the tree starting # Create Resolver object which will resolve the tree starting
# with +needed+ Dependency objects. # with +needed+ Dependency objects.
# #
# +set+ is an object that provides where to look for specifications to # +set+ is an object that provides where to look for specifications to
@ -59,7 +59,7 @@ class Gem::DependencyResolver
# rubygems.org. # rubygems.org.
def initialize needed, set = nil def initialize needed, set = nil
@set = set || Gem::DependencyResolver::IndexSet.new @set = set || Gem::Resolver::IndexSet.new
@needed = needed @needed = needed
@conflicts = [] @conflicts = []
@ -68,6 +68,15 @@ class Gem::DependencyResolver
@soft_missing = false @soft_missing = false
end end
DEBUG_RESOLVER = !ENV['DEBUG_RESOLVER'].nil?
def explain(stage, *data)
if DEBUG_RESOLVER
d = data.map { |x| x.inspect }.join(", ")
STDOUT.printf "%20s %s\n", stage.to_s.upcase, d
end
end
## ##
# Creates an ActivationRequest for the given +dep+ and the last +possible+ # Creates an ActivationRequest for the given +dep+ and the last +possible+
# specification. # specification.
@ -77,8 +86,10 @@ class Gem::DependencyResolver
def activation_request dep, possible # :nodoc: def activation_request dep, possible # :nodoc:
spec = possible.pop spec = possible.pop
explain :activate, [spec.full_name, possible.size]
activation_request = activation_request =
Gem::DependencyResolver::ActivationRequest.new spec, dep, possible Gem::Resolver::ActivationRequest.new spec, dep, possible
return spec, activation_request return spec, activation_request
end end
@ -86,7 +97,7 @@ class Gem::DependencyResolver
def requests s, act, reqs=nil def requests s, act, reqs=nil
s.dependencies.reverse_each do |d| s.dependencies.reverse_each do |d|
next if d.type == :development and not @development next if d.type == :development and not @development
reqs = Gem::List.new Gem::DependencyResolver::DependencyRequest.new(d, act), reqs reqs.add Gem::Resolver::DependencyRequest.new(d, act)
end end
@set.prefetch reqs @set.prefetch reqs
@ -100,18 +111,18 @@ class Gem::DependencyResolver
def resolve def resolve
@conflicts = [] @conflicts = []
needed = nil needed = RequirementList.new
@needed.reverse_each do |n| @needed.reverse_each do |n|
request = Gem::DependencyResolver::DependencyRequest.new n, nil request = Gem::Resolver::DependencyRequest.new n, nil
needed = Gem::List.new request, needed needed.add request
end end
res = resolve_for needed, nil res = resolve_for needed, nil
raise Gem::DependencyResolutionError, res if raise Gem::DependencyResolutionError, res if
res.kind_of? Gem::DependencyResolver::DependencyConflict res.kind_of? Gem::Resolver::Conflict
res.to_a res.to_a
end end
@ -128,6 +139,8 @@ class Gem::DependencyResolver
until states.empty? do until states.empty? do
state = states.pop state = states.pop
explain :consider, state.dep, conflict.failed_dep
if conflict.for_spec? state.spec if conflict.for_spec? state.spec
state.conflicts << [state.spec, conflict] state.conflicts << [state.spec, conflict]
return state return state
@ -162,11 +175,11 @@ class Gem::DependencyResolver
# Otherwise, issue it on the requester's request itself. # Otherwise, issue it on the requester's request itself.
if existing.others_possible? or existing.request.requester.nil? then if existing.others_possible? or existing.request.requester.nil? then
conflict = conflict =
Gem::DependencyResolver::DependencyConflict.new dep, existing Gem::Resolver::Conflict.new dep, existing
else else
depreq = existing.request.requester.request depreq = dep.requester.request
conflict = conflict =
Gem::DependencyResolver::DependencyConflict.new depreq, existing, dep Gem::Resolver::Conflict.new depreq, existing, dep
end end
@conflicts << conflict unless @conflicts.include? conflict @conflicts << conflict unless @conflicts.include? conflict
@ -182,7 +195,7 @@ class Gem::DependencyResolver
# +spec+ is the Specification for this state. # +spec+ is the Specification for this state.
# +possible+ is List of DependencyRequest objects that can be tried to # +possible+ is List of DependencyRequest objects that can be tried to
# find a complete set. # find a complete set.
# +conflicts+ is a [DependencyRequest, DependencyConflict] hit tried to # +conflicts+ is a [DependencyRequest, Conflict] hit tried to
# activate the state. # activate the state.
# #
State = Struct.new(:needed, :specs, :dep, :spec, :possibles, :conflicts) do 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. # The State objects that are used to attempt the activation tree.
states = [] states = []
while needed while !needed.empty?
dep = needed.value dep = needed.remove
needed = needed.tail explain :try, [dep, dep.requester ? dep.requester.request : :toplevel]
# If there is already a spec activated for the requested name... # If there is already a spec activated for the requested name...
if specs && existing = specs.find { |s| dep.name == s.name } if specs && existing = specs.find { |s| dep.name == s.name }
@ -228,6 +241,7 @@ class Gem::DependencyResolver
next if dep.matches_spec? existing next if dep.matches_spec? existing
conflict = handle_conflict dep, existing conflict = handle_conflict dep, existing
explain :conflict, conflict.explain
state = find_conflict_state conflict, states 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 # 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 # to current +needed+ and +specs+ so we can try another. This is code is
# what makes conflict resolution possible. # what makes conflict resolution possible.
states << State.new(needed, specs, dep, spec, possible, []) states << State.new(needed.dup, specs, dep, spec, possible, [])
explain :states, states.map { |s| s.dep }
needed = requests spec, act, needed needed = requests spec, act, needed
specs = Gem::List.prepend specs, act specs = Gem::List.prepend specs, act
@ -341,24 +357,32 @@ class Gem::DependencyResolver
end end
require 'rubygems/dependency_resolver/activation_request' ##
require 'rubygems/dependency_resolver/dependency_conflict' # TODO remove in RubyGems 3
require 'rubygems/dependency_resolver/dependency_request'
require 'rubygems/dependency_resolver/set' Gem::DependencyResolver = Gem::Resolver # :nodoc:
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/resolver/activation_request'
require 'rubygems/dependency_resolver/spec_specification' require 'rubygems/resolver/conflict'
require 'rubygems/dependency_resolver/api_specification' require 'rubygems/resolver/dependency_request'
require 'rubygems/dependency_resolver/index_specification' require 'rubygems/resolver/requirement_list'
require 'rubygems/dependency_resolver/installed_specification'
require 'rubygems/dependency_resolver/vendor_specification' require 'rubygems/resolver/set'
require 'rubygems/resolver/api_set'
require 'rubygems/resolver/composed_set'
require 'rubygems/resolver/best_set'
require 'rubygems/resolver/current_set'
require 'rubygems/resolver/git_set'
require 'rubygems/resolver/index_set'
require 'rubygems/resolver/installer_set'
require 'rubygems/resolver/lock_set'
require 'rubygems/resolver/vendor_set'
require 'rubygems/resolver/specification'
require 'rubygems/resolver/spec_specification'
require 'rubygems/resolver/api_specification'
require 'rubygems/resolver/git_specification'
require 'rubygems/resolver/index_specification'
require 'rubygems/resolver/installed_specification'
require 'rubygems/resolver/vendor_specification'

View File

@ -3,7 +3,7 @@
# Also contains a dependency that was used to introduce this # Also contains a dependency that was used to introduce this
# activation. # activation.
class Gem::DependencyResolver::ActivationRequest class Gem::Resolver::ActivationRequest
attr_reader :request attr_reader :request
@ -19,7 +19,7 @@ class Gem::DependencyResolver::ActivationRequest
case other case other
when Gem::Specification when Gem::Specification
@spec == other @spec == other
when Gem::DependencyResolver::ActivationRequest when Gem::Resolver::ActivationRequest
@spec == other.spec && @request == other.request @spec == other.spec && @request == other.request
else else
false false
@ -70,7 +70,7 @@ class Gem::DependencyResolver::ActivationRequest
def installed? def installed?
case @spec case @spec
when Gem::DependencyResolver::VendorSpecification then when Gem::Resolver::VendorSpecification then
true true
else else
this_spec = full_spec this_spec = full_spec

View File

@ -2,7 +2,7 @@
# The global rubygems pool, available via the rubygems.org API. # The global rubygems pool, available via the rubygems.org API.
# Returns instances of APISpecification. # Returns instances of APISpecification.
class Gem::DependencyResolver::APISet < Gem::DependencyResolver::Set class Gem::Resolver::APISet < Gem::Resolver::Set
## ##
# The URI for the dependency API this APISet uses. # 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| versions(req.name).each do |ver|
if req.dependency.match? req.name, ver[:number] if req.dependency.match? req.name, ver[:number]
res << Gem::DependencyResolver::APISpecification.new(self, ver) res << Gem::Resolver::APISpecification.new(self, ver)
end end
end end

View File

@ -4,7 +4,7 @@
# This is used to avoid loading the full Specification object when all we need # This is used to avoid loading the full Specification object when all we need
# is the name, version, and dependencies. # is the name, version, and dependencies.
class Gem::DependencyResolver::APISpecification < Gem::DependencyResolver::Specification class Gem::Resolver::APISpecification < Gem::Resolver::Specification
## ##
# Creates an APISpecification for the given +set+ from the rubygems.org # Creates an APISpecification for the given +set+ from the rubygems.org

View File

@ -3,7 +3,7 @@
# #
# It combines IndexSet and APISet # It combines IndexSet and APISet
class Gem::DependencyResolver::BestSet < Gem::DependencyResolver::ComposedSet class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
## ##
# Creates a BestSet for the given +sources+ or Gem::sources if none are # Creates a BestSet for the given +sources+ or Gem::sources if none are

View File

@ -1,4 +1,4 @@
class Gem::DependencyResolver::ComposedSet < Gem::DependencyResolver::Set class Gem::Resolver::ComposedSet < Gem::Resolver::Set
attr_reader :sets # :nodoc: attr_reader :sets # :nodoc:

View File

@ -2,7 +2,7 @@
# Used internally to indicate that a dependency conflicted # Used internally to indicate that a dependency conflicted
# with a spec that would be activated. # with a spec that would be activated.
class Gem::DependencyResolver::DependencyConflict class Gem::Resolver::Conflict
attr_reader :activated attr_reader :activated
@ -23,6 +23,10 @@ class Gem::DependencyResolver::DependencyConflict
@failed_dep == other.failed_dep @failed_dep == other.failed_dep
end end
def explain
"<Conflict wanted: #{@failed_dep}, had: #{activated.spec.full_name}>"
end
## ##
# Return the 2 dependency objects that conflicted # Return the 2 dependency objects that conflicted
@ -94,3 +98,5 @@ class Gem::DependencyResolver::DependencyConflict
end end
Gem::Resolver::DependencyConflict = Gem::Resolver::Conflict

View File

@ -3,7 +3,7 @@
# all the normal settings that control where to look # all the normal settings that control where to look
# for installed gems. # for installed gems.
class Gem::DependencyResolver::CurrentSet < Gem::DependencyResolver::Set class Gem::Resolver::CurrentSet < Gem::Resolver::Set
def find_all req def find_all req
req.dependency.matching_specs req.dependency.matching_specs

View File

@ -2,7 +2,7 @@
# Used Internally. Wraps a Dependency object to also track which spec # Used Internally. Wraps a Dependency object to also track which spec
# contained the Dependency. # contained the Dependency.
class Gem::DependencyResolver::DependencyRequest class Gem::Resolver::DependencyRequest
attr_reader :dependency attr_reader :dependency
@ -17,7 +17,7 @@ class Gem::DependencyResolver::DependencyRequest
case other case other
when Gem::Dependency when Gem::Dependency
@dependency == other @dependency == other
when Gem::DependencyResolver::DependencyRequest when Gem::Resolver::DependencyRequest
@dependency == other.dependency && @requester == other.requester @dependency == other.dependency && @requester == other.requester
else else
false false

View File

@ -0,0 +1,81 @@
##
# A GitSet represents gems that are sourced from git repositories.
#
# This is used for gem dependency file support.
#
# Example:
#
# set = Gem::Resolver::GitSet.new
# set.add_git_gem 'rake', 'git://example/rake.git', tag: 'rake-10.1.0'
class Gem::Resolver::GitSet < Gem::Resolver::Set
##
# Contains repositories needing submodules
attr_reader :need_submodules # :nodoc:
##
# A Hash containing git gem names for keys and a Hash of repository and
# git commit reference as values.
attr_reader :repositories # :nodoc:
##
# A hash of gem names to Gem::Resolver::GitSpecifications
attr_reader :specs # :nodoc:
def initialize # :nodoc:
@git = ENV['git'] || 'git'
@need_submodules = {}
@repositories = {}
@specs = {}
end
def add_git_gem name, repository, reference, submodules # :nodoc:
@repositories[name] = [repository, reference]
@need_submodules[repository] = submodules
end
##
# 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
end

View File

@ -0,0 +1,16 @@
##
# A GitSpecification represents a gem that is sourced from a git repository
# and is being loaded through a gem dependencies file through the +git:+
# option.
class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification
def == other # :nodoc:
self.class === other and
@set == other.set and
@spec == other.spec and
@source == other.source
end
end

View File

@ -2,7 +2,7 @@
# The global rubygems pool represented via the traditional # The global rubygems pool represented via the traditional
# source index. # source index.
class Gem::DependencyResolver::IndexSet < Gem::DependencyResolver::Set class Gem::Resolver::IndexSet < Gem::Resolver::Set
def initialize source = nil # :nodoc: def initialize source = nil # :nodoc:
@f = @f =
@ -38,7 +38,7 @@ class Gem::DependencyResolver::IndexSet < Gem::DependencyResolver::Set
@all[name].each do |uri, n| @all[name].each do |uri, n|
if req.dependency.match? n then if req.dependency.match? n then
res << Gem::DependencyResolver::IndexSpecification.new( res << Gem::Resolver::IndexSpecification.new(
self, n.name, n.version, uri, n.platform) self, n.name, n.version, uri, n.platform)
end end
end end

View File

@ -3,7 +3,7 @@
# delay needed to download full Specification objects when only the +name+ # delay needed to download full Specification objects when only the +name+
# and +version+ are needed. # and +version+ are needed.
class Gem::DependencyResolver::IndexSpecification < Gem::DependencyResolver::Specification class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
## ##
# An IndexSpecification is created from the index format described in `gem # An IndexSpecification is created from the index format described in `gem

View File

@ -2,7 +2,7 @@
# An InstalledSpecification represents a gem that is already installed # An InstalledSpecification represents a gem that is already installed
# locally. # locally.
class Gem::DependencyResolver::InstalledSpecification < Gem::DependencyResolver::SpecSpecification class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
def == other # :nodoc: def == other # :nodoc:
self.class === other and self.class === other and

View File

@ -2,7 +2,7 @@
# A set of gems for installation sourced from remote sources and local .gem # A set of gems for installation sourced from remote sources and local .gem
# files # files
class Gem::DependencyResolver::InstallerSet < Gem::DependencyResolver::Set class Gem::Resolver::InstallerSet < Gem::Resolver::Set
## ##
# List of Gem::Specification objects that must always be installed. # 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| dep.matching_specs.each do |gemspec|
next if @always_install.include? gemspec next if @always_install.include? gemspec
res << Gem::DependencyResolver::InstalledSpecification.new(self, gemspec) res << Gem::Resolver::InstalledSpecification.new(self, gemspec)
end unless @ignore_installed end unless @ignore_installed
if consider_local? then if consider_local? then
local_source = Gem::Source::Local.new local_source = Gem::Source::Local.new
if spec = local_source.find_gem(name, dep.requirement) then if spec = local_source.find_gem(name, dep.requirement) then
res << Gem::DependencyResolver::IndexSpecification.new( res << Gem::Resolver::IndexSpecification.new(
self, spec.name, spec.version, local_source, spec.platform) self, spec.name, spec.version, local_source, spec.platform)
end end
end end
@ -81,7 +81,7 @@ class Gem::DependencyResolver::InstallerSet < Gem::DependencyResolver::Set
@all[name].each do |remote_source, n| @all[name].each do |remote_source, n|
if dep.match? n then if dep.match? n then
res << Gem::DependencyResolver::IndexSpecification.new( res << Gem::Resolver::IndexSpecification.new(
self, n.name, n.version, remote_source, n.platform) self, n.name, n.version, remote_source, n.platform)
end end
end end

View File

@ -1,7 +1,7 @@
## ##
# A set of gems from a gem dependencies lockfile. # A set of gems from a gem dependencies lockfile.
class Gem::DependencyResolver::LockSet < Gem::DependencyResolver::Set class Gem::Resolver::LockSet < Gem::Resolver::Set
attr_reader :specs # :nodoc: attr_reader :specs # :nodoc:
@ -24,8 +24,8 @@ class Gem::DependencyResolver::LockSet < Gem::DependencyResolver::Set
version = Gem::Version.new version version = Gem::Version.new version
spec = spec =
Gem::DependencyResolver::IndexSpecification.new self, name, version, Gem::Resolver::IndexSpecification.new self, name, version, @source,
@source, platform platform
@specs << spec @specs << spec
end end

View File

@ -0,0 +1,40 @@
##
# Used internally to hold the requirements being considered
# while attempting to find a proper activation set.
class Gem::Resolver::RequirementList
include Enumerable
def initialize
@list = []
end
def initialize_copy(other)
@list = @list.dup
end
def add(req)
@list.push req
req
end
##
# Enumerates requirements in the list
def each # :nodoc:
return enum_for __method__ unless block_given?
@list.each do |requirement|
yield requirement
end
end
def empty?
@list.empty?
end
def remove
@list.shift
end
end

View File

@ -1,13 +1,12 @@
## ##
# DependencyResolver sets are used to look up specifications (and their # Resolver sets are used to look up specifications (and their
# dependencies) used in resolution. This set is abstract. # dependencies) used in resolution. This set is abstract.
class Gem::DependencyResolver::Set class Gem::Resolver::Set
## ##
# The find_all method must be implemented. It returns all # The find_all method must be implemented. It returns all Resolver
# DependencyResolver Specification objects matching the given # Specification objects matching the given DependencyRequest +req+.
# DependencyRequest +req+.
def find_all req def find_all req
raise NotImplementedError raise NotImplementedError

View File

@ -1,8 +1,8 @@
## ##
# The DependencyResolver::SpecSpecification contains common functionality for # The Resolver::SpecSpecification contains common functionality for
# DependencyResolver specifications that are backed by a Gem::Specification. # Resolver specifications that are backed by a Gem::Specification.
class Gem::DependencyResolver::SpecSpecification < Gem::DependencyResolver::Specification class Gem::Resolver::SpecSpecification < Gem::Resolver::Specification
attr_reader :spec # :nodoc: attr_reader :spec # :nodoc:

View File

@ -1,9 +1,9 @@
## ##
# A DependencyResolver::Specification contains a subset of the information # A Resolver::Specification contains a subset of the information
# contained in a Gem::Specification. Only the information necessary for # contained in a Gem::Specification. Only the information necessary for
# dependency resolution in the resolver is included. # dependency resolution in the resolver is included.
class Gem::DependencyResolver::Specification class Gem::Resolver::Specification
## ##
# The dependencies of the gem for this specification # The dependencies of the gem for this specification

View File

@ -6,14 +6,14 @@
# #
# Example: # Example:
# #
# set = Gem::DependencyResolver::VendorSet.new # set = Gem::Resolver::VendorSet.new
# #
# set.add_vendor_gem 'rake', 'vendor/rake' # set.add_vendor_gem 'rake', 'vendor/rake'
# #
# The directory vendor/rake must contain an unpacked rake gem along with a # The directory vendor/rake must contain an unpacked rake gem along with a
# rake.gemspec (watching the given name). # rake.gemspec (watching the given name).
class Gem::DependencyResolver::VendorSet < Gem::DependencyResolver::Set class Gem::Resolver::VendorSet < Gem::Resolver::Set
def initialize # :nodoc: def initialize # :nodoc:
@directories = {} @directories = {}
@ -47,7 +47,7 @@ class Gem::DependencyResolver::VendorSet < Gem::DependencyResolver::Set
req.matches_spec? spec req.matches_spec? spec
end.map do |spec| end.map do |spec|
source = Gem::Source::Vendor.new @directories[spec] source = Gem::Source::Vendor.new @directories[spec]
Gem::DependencyResolver::VendorSpecification.new self, spec, source Gem::Resolver::VendorSpecification.new self, spec, source
end end
end end

View File

@ -3,7 +3,7 @@
# and is being loaded through a gem dependencies file through the +path:+ # and is being loaded through a gem dependencies file through the +path:+
# option. # option.
class Gem::DependencyResolver::VendorSpecification < Gem::DependencyResolver::SpecSpecification class Gem::Resolver::VendorSpecification < Gem::Resolver::SpecSpecification
def == other # :nodoc: def == other # :nodoc:
self.class === other and self.class === other and

View File

@ -28,7 +28,9 @@ class Gem::Source
case other case other
when Gem::Source::Installed, when Gem::Source::Installed,
Gem::Source::Local, Gem::Source::Local,
Gem::Source::SpecificFile then Gem::Source::SpecificFile,
Gem::Source::Git,
Gem::Source::Vendor then
-1 -1
when Gem::Source then when Gem::Source then
if !@uri if !@uri
@ -62,9 +64,9 @@ class Gem::Source
fetcher = Gem::RemoteFetcher.fetcher fetcher = Gem::RemoteFetcher.fetcher
fetcher.fetch_path bundler_api_uri, nil, true fetcher.fetch_path bundler_api_uri, nil, true
rescue Gem::RemoteFetcher::FetchError rescue Gem::RemoteFetcher::FetchError
Gem::DependencyResolver::IndexSet.new self Gem::Resolver::IndexSet.new self
else else
Gem::DependencyResolver::APISet.new bundler_api_uri Gem::Resolver::APISet.new bundler_api_uri
end end
end end
@ -90,12 +92,15 @@ class Gem::Source
end end
end end
def fetch_spec(name) ##
# Fetches a specification for the given +name_tuple+.
def fetch_spec name_tuple
fetcher = Gem::RemoteFetcher.fetcher fetcher = Gem::RemoteFetcher.fetcher
spec_file_name = name.spec_name spec_file_name = name_tuple.spec_name
uri = @uri + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}" uri = api_uri + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}"
cache_dir = cache_dir uri cache_dir = cache_dir uri
@ -139,7 +144,7 @@ class Gem::Source
file = FILES[type] file = FILES[type]
fetcher = Gem::RemoteFetcher.fetcher fetcher = Gem::RemoteFetcher.fetcher
file_name = "#{file}.#{Gem.marshal_version}" file_name = "#{file}.#{Gem.marshal_version}"
spec_path = @uri + "#{file_name}.gz" spec_path = api_uri + "#{file_name}.gz"
cache_dir = cache_dir spec_path cache_dir = cache_dir spec_path
local_file = File.join(cache_dir, file_name) local_file = File.join(cache_dir, file_name)
retried = false retried = false
@ -163,18 +168,22 @@ class Gem::Source
def download(spec, dir=Dir.pwd) def download(spec, dir=Dir.pwd)
fetcher = Gem::RemoteFetcher.fetcher fetcher = Gem::RemoteFetcher.fetcher
fetcher.download spec, @uri.to_s, dir fetcher.download spec, api_uri.to_s, dir
end end
def pretty_print q # :nodoc: def pretty_print q # :nodoc:
q.group 2, '[Remote:', ']' do q.group 2, '[Remote:', ']' do
q.breakable q.breakable
q.text @uri.to_s q.text @uri.to_s
if api = api_uri
g.text api
end
end end
end end
end end
require 'rubygems/source/git'
require 'rubygems/source/installed' require 'rubygems/source/installed'
require 'rubygems/source/specific_file' require 'rubygems/source/specific_file'
require 'rubygems/source/local' require 'rubygems/source/local'

189
lib/rubygems/source/git.rb Normal file
View File

@ -0,0 +1,189 @@
require 'digest'
require 'rubygems/util'
##
# A git gem for use in a gem dependencies file.
#
# Example:
#
# source =
# Gem::Source::Git.new 'rake', 'git@example:rake.git', 'rake-10.1.0', false
#
# spec = source.load_spec 'rake'
#
# source.checkout
class Gem::Source::Git < Gem::Source
##
# The name of the gem created by this git gem.
attr_reader :name
##
# The commit reference used for checking out this git gem.
attr_reader :reference
##
# The git repository this gem is sourced from.
attr_reader :repository
##
# Does this repository need submodules checked out too?
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)
@name = name
@repository = repository
@reference = reference
@need_submodules = submodules
@git = ENV['git'] || 'git'
end
def <=> other
case other
when Gem::Source::Git then
0
when Gem::Source::Installed then
-1
when Gem::Source then
1
else
nil
end
end
def == other # :nodoc:
super and
@name == other.name and
@repository == other.repository and
@reference == other.reference and
@need_submodules == other.need_submodules
end
##
# Checks out the files for the repository into the install_dir.
def checkout # :nodoc:
cache
unless File.exist? install_dir then
system @git, 'clone', '--quiet', '--no-checkout',
repo_cache_dir, install_dir
end
Dir.chdir install_dir do
system @git, 'fetch', '--quiet', '--force', '--tags', install_dir
success = system @git, 'reset', '--quiet', '--hard', @reference
success &&=
system @git, 'submodule', 'update',
'--quiet', '--init', '--recursive' if @need_submodules
success
end
end
##
# Creates a local cache repository for the git gem.
def cache # :nodoc:
if File.exist? repo_cache_dir then
Dir.chdir repo_cache_dir do
system @git, 'fetch', '--quiet', '--force', '--tags',
@repository, 'refs/heads/*:refs/heads/*'
end
else
system @git, 'clone', '--quiet', '--bare', '--no-hardlinks',
@repository, repo_cache_dir
end
end
##
# A short reference for use in git gem directories
def dir_shortref # :nodoc:
rev_parse[0..11]
end
##
# The directory where the git gem will be installed.
def install_dir # :nodoc:
File.join Gem.dir, 'bundler', 'gems', "#{@name}-#{dir_shortref}"
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:
File.join Gem.dir, 'cache', 'bundler', 'git', "#{@name}-#{uri_hash}"
end
##
# 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:
normalized =
if @repository =~ %r%^\w+://(\w+@)?% then
uri = URI(@repository).normalize.to_s.sub %r%/$%,''
uri.sub(/\A(\w+)/) { $1.downcase }
else
@repository
end
Digest::SHA1.hexdigest normalized
end
end

View File

@ -1,6 +1,9 @@
##
# Represents an installed gem. This is used for dependency resolution.
class Gem::Source::Installed < Gem::Source class Gem::Source::Installed < Gem::Source
def initialize def initialize # :nodoc:
@uri = nil @uri = nil
end end
@ -9,6 +12,8 @@ class Gem::Source::Installed < Gem::Source
def <=> other def <=> other
case other case other
when Gem::Source::Vendor then
-1
when Gem::Source::Installed then when Gem::Source::Installed then
0 0
when Gem::Source then when Gem::Source then

View File

@ -1,5 +1,10 @@
##
# The local source finds gems in the current directory for fulfilling
# dependencies.
class Gem::Source::Local < Gem::Source class Gem::Source::Local < Gem::Source
def initialize
def initialize # :nodoc:
@specs = nil @specs = nil
@api_uri = nil @api_uri = nil
@uri = nil @uri = nil
@ -26,7 +31,7 @@ class Gem::Source::Local < Gem::Source
"#<%s specs: %p>" % [self.class, keys] "#<%s specs: %p>" % [self.class, keys]
end end
def load_specs(type) def load_specs type # :nodoc:
names = [] names = []
@specs = {} @specs = {}
@ -68,8 +73,8 @@ class Gem::Source::Local < Gem::Source
names names
end end
def find_gem(gem_name, version=Gem::Requirement.default, def find_gem gem_name, version = Gem::Requirement.default, # :nodoc:
prerelease=false) prerelease = false
load_specs :complete load_specs :complete
found = [] found = []
@ -91,7 +96,7 @@ class Gem::Source::Local < Gem::Source
found.max_by { |s| s.version } found.max_by { |s| s.version }
end end
def fetch_spec(name) def fetch_spec name # :nodoc:
load_specs :complete load_specs :complete
if data = @specs[name] if data = @specs[name]
@ -101,7 +106,7 @@ class Gem::Source::Local < Gem::Source
end end
end end
def download(spec, cache_dir=nil) def download spec, cache_dir = nil # :nodoc:
load_specs :complete load_specs :complete
@specs.each do |name, data| @specs.each do |name, data|

View File

@ -1,4 +1,12 @@
##
# A source representing a single .gem file. This is used for installation of
# local gems.
class Gem::Source::SpecificFile < Gem::Source class Gem::Source::SpecificFile < Gem::Source
##
# Creates a new SpecificFile for the gem in +file+
def initialize(file) def initialize(file)
@uri = nil @uri = nil
@path = ::File.expand_path(file) @path = ::File.expand_path(file)
@ -8,19 +16,22 @@ class Gem::Source::SpecificFile < Gem::Source
@name = @spec.name_tuple @name = @spec.name_tuple
end end
##
# The Gem::Specification extracted from this .gem.
attr_reader :spec attr_reader :spec
def load_specs(*a) def load_specs *a # :nodoc:
[@name] [@name]
end end
def fetch_spec(name) def fetch_spec name # :nodoc:
return @spec if name == @name return @spec if name == @name
raise Gem::Exception, "Unable to find '#{name}'" raise Gem::Exception, "Unable to find '#{name}'"
@spec @spec
end end
def download(spec, dir=nil) def download spec, dir = nil # :nodoc:
return @path if spec == @spec return @path if spec == @spec
raise Gem::Exception, "Unable to download '#{spec.full_name}'" raise Gem::Exception, "Unable to download '#{spec.full_name}'"
end end

View File

@ -3,8 +3,22 @@
class Gem::Source::Vendor < Gem::Source::Installed class Gem::Source::Vendor < Gem::Source::Installed
def initialize uri ##
@uri = uri # Creates a new Vendor source for a gem that was unpacked at +path+.
def initialize path
@uri = path
end
def <=> other
case other
when Gem::Source::Vendor then
0
when Gem::Source then
1
else
nil
end
end end
end end

View File

@ -1,5 +1,18 @@
require 'rubygems/source' require 'rubygems/source'
##
# The SourceList represents the sources rubygems has been configured to use.
# A source may be created from an array of sources:
#
# Gem::SourceList.from %w[https://rubygems.example https://internal.example]
#
# Or by adding them:
#
# sources = Gem::SourceList.new
# sources.add 'https://rubygems.example'
#
# The most common way to get a SourceList is Gem.sources.
class Gem::SourceList class Gem::SourceList
include Enumerable include Enumerable
@ -91,7 +104,7 @@ class Gem::SourceList
@sources.empty? @sources.empty?
end end
def ==(other) def == other # :nodoc:
to_a == other to_a == other
end end

View File

@ -34,6 +34,10 @@ class Gem::SpecFetcher
@fetcher = nil @fetcher = nil
##
# Default fetcher instance. Use this instead of ::new to reduce object
# allocation.
def self.fetcher def self.fetcher
@fetcher ||= new @fetcher ||= new
end end
@ -43,8 +47,8 @@ class Gem::SpecFetcher
end end
## ##
# Creates a new SpecFetcher. Ordinarily you want to use # Creates a new SpecFetcher. Ordinarily you want to use the default fetcher
# Gem::SpecFetcher::fetcher which uses the Gem.sources. # from Gem::SpecFetcher::fetcher which uses the Gem.sources.
# #
# If you need to retrieve specifications from a different +source+, you can # If you need to retrieve specifications from a different +source+, you can
# send it as an argument. # send it as an argument.
@ -84,7 +88,11 @@ class Gem::SpecFetcher
rejected_specs = {} rejected_specs = {}
if dependency.prerelease? if dependency.prerelease?
if dependency.specific?
type = :complete type = :complete
else
type = :abs_latest
end
elsif dependency.latest_version? elsif dependency.latest_version?
type = :latest type = :latest
else else
@ -223,6 +231,12 @@ class Gem::SpecFetcher
tuples_for(source, :prerelease, true) + tuples_for(source, :prerelease, true) +
tuples_for(source, :released) tuples_for(source, :released)
names.sort
when :abs_latest
names =
tuples_for(source, :prerelease, true) +
tuples_for(source, :latest)
names.sort names.sort
when :prerelease when :prerelease
tuples_for(source, :prerelease) tuples_for(source, :prerelease)
@ -239,7 +253,11 @@ class Gem::SpecFetcher
[list, errors] [list, errors]
end end
def tuples_for(source, type, gracefully_ignore=false) ##
# Retrieves NameTuples from +source+ of the given +type+ (:prerelease,
# etc.). If +gracefully_ignore+ is true, errors are ignored.
def tuples_for(source, type, gracefully_ignore=false) # :nodoc:
cache = @caches[type] cache = @caches[type]
tuples = tuples =

View File

@ -12,6 +12,7 @@ require 'rubygems/platform'
require 'rubygems/deprecate' require 'rubygems/deprecate'
require 'rubygems/basic_specification' require 'rubygems/basic_specification'
require 'rubygems/stub_specification' require 'rubygems/stub_specification'
require 'rubygems/util/stringio'
# :stopdoc: # :stopdoc:
# date.rb can't be loaded for `make install` due to miniruby # date.rb can't be loaded for `make install` due to miniruby
@ -2165,7 +2166,7 @@ class Gem::Specification < Gem::BasicSpecification
end end
## ##
# Used by Gem::DependencyResolver to order Gem::Specification objects # Used by Gem::Resolver to order Gem::Specification objects
def source # :nodoc: def source # :nodoc:
self self
@ -2363,7 +2364,7 @@ class Gem::Specification < Gem::BasicSpecification
builder << self builder << self
ast = builder.tree ast = builder.tree
io = StringIO.new io = Gem::StringSink.new
io.set_encoding Encoding::UTF_8 if Object.const_defined? :Encoding io.set_encoding Encoding::UTF_8 if Object.const_defined? :Encoding
Psych::Visitors::Emitter.new(io).accept(ast) Psych::Visitors::Emitter.new(io).accept(ast)

View File

@ -233,6 +233,8 @@ class Gem::TestCase < MiniTest::Unit::TestCase
ruby ruby
end end
@git = ENV['GIT'] || 'git'
Gem.ensure_gem_subdirectories @gemhome Gem.ensure_gem_subdirectories @gemhome
@orig_LOAD_PATH = $LOAD_PATH.dup @orig_LOAD_PATH = $LOAD_PATH.dup
@ -372,6 +374,64 @@ class Gem::TestCase < MiniTest::Unit::TestCase
Gem.pre_uninstall_hooks.clear Gem.pre_uninstall_hooks.clear
end end
##
# A git_gem is used with a gem dependencies file. The gem created here
# has no files, just a gem specification for the given +name+ and +version+.
#
# Yields the +specification+ to the block, if given
def git_gem name = 'a', version = 1
have_git?
directory = File.join 'git', name
directory = File.expand_path directory
git_spec = Gem::Specification.new name, version do |specification|
yield specification if block_given?
end
FileUtils.mkdir_p directory
gemspec = "#{name}.gemspec"
open File.join(directory, gemspec), 'w' do |io|
io.write git_spec.to_ruby
end
head = nil
Dir.chdir directory do
unless File.exist? '.git' then
system @git, 'init', '--quiet'
system @git, 'config', 'user.name', 'RubyGems Tests'
system @git, 'config', 'user.email', 'rubygems@example'
end
system @git, 'add', gemspec
system @git, 'commit', '-a', '-m', 'a non-empty commit message', '--quiet'
head = Gem::Util.popen('git', 'rev-parse', 'master').strip
end
return name, git_spec.version, directory, head
end
##
# Skips this test unless you have a git executable
def have_git?
return if in_path? @git
skip 'cannot find git executable, use GIT environment variable to set'
end
def in_path? executable # :nodoc:
return true if %r%\A([A-Z]:|/)% =~ executable and File.exist? executable
ENV['PATH'].split(File::PATH_SEPARATOR).any? do |directory|
File.exist? File.join directory, executable
end
end
## ##
# Builds and installs the Gem::Specification +spec+ # Builds and installs the Gem::Specification +spec+
@ -1082,21 +1142,21 @@ Also, a list:
end end
## ##
# Constructs a Gem::DependencyResolver::DependencyRequest from a # Constructs a Gem::Resolver::DependencyRequest from a
# Gem::Dependency +dep+, a +from_name+ and +from_version+ requesting the # Gem::Dependency +dep+, a +from_name+ and +from_version+ requesting the
# dependency and a +parent+ DependencyRequest # dependency and a +parent+ DependencyRequest
def dependency_request dep, from_name, from_version, parent = nil def dependency_request dep, from_name, from_version, parent = nil
remote = Gem::Source.new @uri remote = Gem::Source.new @uri
parent ||= Gem::DependencyResolver::DependencyRequest.new \ parent ||= Gem::Resolver::DependencyRequest.new \
dep, nil dep, nil
spec = Gem::DependencyResolver::IndexSpecification.new \ spec = Gem::Resolver::IndexSpecification.new \
nil, from_name, from_version, remote, Gem::Platform::RUBY nil, from_name, from_version, remote, Gem::Platform::RUBY
activation = Gem::DependencyResolver::ActivationRequest.new spec, parent activation = Gem::Resolver::ActivationRequest.new spec, parent
Gem::DependencyResolver::DependencyRequest.new dep, activation Gem::Resolver::DependencyRequest.new dep, activation
end end
## ##

65
lib/rubygems/util.rb Normal file
View File

@ -0,0 +1,65 @@
module Gem::Util
##
# Zlib::GzipReader wrapper that unzips +data+.
def self.gunzip(data)
require 'zlib'
require 'rubygems/util/stringio'
data = Gem::StringSource.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)
require 'zlib'
require 'rubygems/util/stringio'
zipped = Gem::StringSink.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)
require 'zlib'
Zlib::Inflate.inflate data
end
##
# This calls IO.popen where it accepts an array for a +command+ (Ruby 1.9+)
# and implements an IO.popen-like behavior where it does not accept an array
# for a command.
def self.popen *command
begin
r, = IO.popen command
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
Process.wait pid
r
end
r.read
end
end

View File

@ -0,0 +1,34 @@
class Gem::StringSink
def initialize
@string = ""
end
attr_reader :string
def write(s)
@string += s
s.size
end
def set_encoding(enc)
@string.force_encoding enc
end
end
class Gem::StringSource
def initialize(str)
@string = str.dup
end
def read(count=nil)
if count
@string.slice!(0,count)
else
s = @string
@string = ""
s
end
end
alias_method :readpartial, :read
end

View File

@ -1120,7 +1120,7 @@ class TestGem < Gem::TestCase
ENV['RUBYGEMS_GEMDEPS'] = "-" ENV['RUBYGEMS_GEMDEPS'] = "-"
assert_equal [a,b,c], Gem.detect_gemdeps assert_equal [a,b,c], Gem.detect_gemdeps.sort_by { |s| s.name }
end end
LIB_PATH = File.expand_path "../../../lib".untaint, __FILE__.untaint LIB_PATH = File.expand_path "../../../lib".untaint, __FILE__.untaint

View File

@ -44,8 +44,10 @@ class TestGemCommandsWhichCommand < Gem::TestCase
@cmd.handle_options %w[foo_bar missinglib] @cmd.handle_options %w[foo_bar missinglib]
use_ui @ui do use_ui @ui do
assert_raises Gem::MockGemUi::TermError do
@cmd.execute @cmd.execute
end end
end
assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
assert_match %r%Can.t find ruby library file or shared library missinglib\n%, assert_match %r%Can.t find ruby library file or shared library missinglib\n%,

View File

@ -5,7 +5,7 @@ class TestGemDependencyResolutionError < Gem::TestCase
def setup def setup
super super
@DR = Gem::DependencyResolver @DR = Gem::Resolver
@spec = util_spec 'a', 2 @spec = util_spec 'a', 2
@ -14,7 +14,7 @@ class TestGemDependencyResolutionError < Gem::TestCase
@activated = @DR::ActivationRequest.new @spec, @a2_req @activated = @DR::ActivationRequest.new @spec, @a2_req
@conflict = @DR::DependencyConflict.new @a1_req, @activated @conflict = @DR::Conflict.new @a1_req, @activated
@error = Gem::DependencyResolutionError.new @conflict @error = Gem::DependencyResolutionError.new @conflict
end end

View File

@ -1,72 +0,0 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverVendorSpecification < Gem::TestCase
def setup
super
@set = Gem::DependencyResolver::VendorSet.new
@spec = Gem::Specification.new 'a', 1
end
def test_equals2
v_spec_a = Gem::DependencyResolver::VendorSpecification.new @set, @spec
assert_equal v_spec_a, v_spec_a
spec_b = Gem::Specification.new 'b', 1
v_spec_b = Gem::DependencyResolver::VendorSpecification.new @set, spec_b
refute_equal v_spec_a, v_spec_b
v_set = Gem::DependencyResolver::VendorSet.new
v_spec_s = Gem::DependencyResolver::VendorSpecification.new v_set, @spec
refute_equal v_spec_a, v_spec_s
i_set = Gem::DependencyResolver::IndexSet.new
source = Gem::Source.new @gem_repo
i_spec = Gem::DependencyResolver::IndexSpecification.new(
i_set, 'a', v(1), source, Gem::Platform::RUBY)
refute_equal v_spec_a, i_spec
end
def test_dependencies
@spec.add_dependency 'b'
@spec.add_dependency 'c'
v_spec = Gem::DependencyResolver::VendorSpecification.new @set, @spec
assert_equal [dep('b'), dep('c')], v_spec.dependencies
end
def test_full_name
v_spec = Gem::DependencyResolver::VendorSpecification.new @set, @spec
assert_equal 'a-1', v_spec.full_name
end
def test_name
v_spec = Gem::DependencyResolver::VendorSpecification.new @set, @spec
assert_equal 'a', v_spec.name
end
def test_platform
v_spec = Gem::DependencyResolver::VendorSpecification.new @set, @spec
assert_equal Gem::Platform::RUBY, v_spec.platform
end
def test_version
spec = Gem::Specification.new 'a', 1
v_spec = Gem::DependencyResolver::VendorSpecification.new @set, spec
assert_equal v(1), v_spec.version
end
end

View File

@ -98,22 +98,26 @@ install:
end end
def test_build_extensions def test_build_extensions
@spec.extensions << 'extconf.rb' @spec.extensions << 'ext/extconf.rb'
FileUtils.mkdir_p @spec.gem_dir ext_dir = File.join @spec.gem_dir, 'ext'
extconf_rb = File.join @spec.gem_dir, 'extconf.rb' FileUtils.mkdir_p ext_dir
extconf_rb = File.join ext_dir, 'extconf.rb'
open extconf_rb, 'w' do |f| open extconf_rb, 'w' do |f|
f.write <<-'RUBY' f.write <<-'RUBY'
open 'Makefile', 'w' do |f| require 'mkmf'
f.puts "clean:\n\techo cleaned"
f.puts "default:\n\techo built" create_makefile 'a'
f.puts "install:\n\techo installed"
end
RUBY RUBY
end end
ext_lib_dir = File.join ext_dir, 'lib'
FileUtils.mkdir ext_lib_dir
FileUtils.touch File.join ext_lib_dir, 'a.rb'
use_ui @ui do use_ui @ui do
@builder.build_extensions @builder.build_extensions
end end
@ -121,6 +125,8 @@ install:
assert_path_exists @spec.extension_install_dir assert_path_exists @spec.extension_install_dir
assert_path_exists @spec.gem_build_complete_path assert_path_exists @spec.gem_build_complete_path
assert_path_exists File.join @spec.extension_install_dir, 'gem_make.out' assert_path_exists File.join @spec.extension_install_dir, 'gem_make.out'
assert_path_exists File.join @spec.extension_install_dir, 'a.rb'
assert_path_exists File.join @spec.gem_dir, 'lib', 'a.rb'
end end
def test_build_extensions_none def test_build_extensions_none

View File

@ -15,10 +15,10 @@ class TestGemImpossibleDependenciesError < Gem::TestCase
net_ssh_2_6_5 = net_ssh_2_6_5 =
dependency_request dep('net-ssh', '~> 2.2.2'), 'net-ssh', '2.6.5', request dependency_request dep('net-ssh', '~> 2.2.2'), 'net-ssh', '2.6.5', request
conflict1 = Gem::DependencyResolver::DependencyConflict.new \ conflict1 = Gem::Resolver::Conflict.new \
net_ssh_2_6_5, net_ssh_2_6_5.requester net_ssh_2_6_5, net_ssh_2_6_5.requester
conflict2 = Gem::DependencyResolver::DependencyConflict.new \ conflict2 = Gem::Resolver::Conflict.new \
net_ssh_2_2_2, net_ssh_2_2_2.requester net_ssh_2_2_2, net_ssh_2_2_2.requester
conflicts << [net_ssh_2_6_5.requester.spec, conflict1] conflicts << [net_ssh_2_6_5.requester.spec, conflict1]

View File

@ -1004,6 +1004,10 @@ gem 'other', version
skip '1.9.2 and earlier mkmf.rb does not create TOUCH' if skip '1.9.2 and earlier mkmf.rb does not create TOUCH' if
RUBY_VERSION < '1.9.3' RUBY_VERSION < '1.9.3'
if RUBY_VERSION == "1.9.3" and RUBY_PATCHLEVEL <= 194
skip "TOUCH was introduced into 1.9.3 after p194"
end
@spec.require_paths = ["."] @spec.require_paths = ["."]
@spec.extensions << "extconf.rb" @spec.extensions << "extconf.rb"
@ -1038,8 +1042,14 @@ gem 'other', version
puts '-' * 78 puts '-' * 78
puts File.read File.join(@gemhome, 'gems', 'a-2', 'Makefile') puts File.read File.join(@gemhome, 'gems', 'a-2', 'Makefile')
puts '-' * 78 puts '-' * 78
puts File.read File.join(@gemhome, 'gems', 'a-2', 'gem_make.out')
path = File.join(@gemhome, 'gems', 'a-2', 'gem_make.out')
if File.exists?(path)
puts File.read(path)
puts '-' * 78 puts '-' * 78
end
raise raise
end end

View File

@ -165,7 +165,7 @@ gems:
def test_api_endpoint def test_api_endpoint
uri = URI.parse "http://gems.example.com/foo" uri = URI.parse "http://gems.example.com/foo"
target = MiniTest::Mock.new target = MiniTest::Mock.new
target.expect :target, "http://blah.com" target.expect :target, "blah.com"
dns = MiniTest::Mock.new dns = MiniTest::Mock.new
dns.expect :getresource, target, [String, Object] dns.expect :getresource, target, [String, Object]

View File

@ -7,7 +7,7 @@ class TestGemRequestSet < Gem::TestCase
Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
@DR = Gem::DependencyResolver @DR = Gem::Resolver
end end
def test_gem def test_gem
@ -69,6 +69,7 @@ class TestGemRequestSet < Gem::TestCase
assert_equal [dep('a')], rs.dependencies assert_equal [dep('a')], rs.dependencies
assert rs.git_set
assert rs.vendor_set assert rs.vendor_set
end end
@ -100,6 +101,32 @@ class TestGemRequestSet < Gem::TestCase
assert_equal ["a-2", "b-2"], names assert_equal ["a-2", "b-2"], names
end end
def test_resolve_git
name, _, repository, = git_gem
rs = Gem::RequestSet.new
Tempfile.open 'gem.deps.rb' do |io|
io.puts <<-gems_deps_rb
gem "#{name}", :git => "#{repository}"
gems_deps_rb
io.flush
rs.load_gemdeps io.path
end
res = rs.resolve
assert_equal 1, res.size
names = res.map { |s| s.full_name }.sort
assert_equal %w[a-1], names
assert_equal [@DR::IndexSet, @DR::GitSet, @DR::VendorSet],
rs.sets.map { |set| set.class }
end
def test_resolve_incompatible def test_resolve_incompatible
a1 = util_spec 'a', 1 a1 = util_spec 'a', 1
a2 = util_spec 'a', 2 a2 = util_spec 'a', 2
@ -142,7 +169,7 @@ class TestGemRequestSet < Gem::TestCase
assert_equal ["a-1", "b-2"], names assert_equal ["a-1", "b-2"], names
assert_equal [@DR::IndexSet, @DR::VendorSet], assert_equal [@DR::IndexSet, @DR::GitSet, @DR::VendorSet],
rs.sets.map { |set| set.class } rs.sets.map { |set| set.class }
end end

View File

@ -10,9 +10,11 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
@set = Gem::RequestSet.new @set = Gem::RequestSet.new
@vendor_set = Gem::DependencyResolver::VendorSet.new @git_set = Gem::Resolver::GitSet.new
@vendor_set = Gem::Resolver::VendorSet.new
@gda = @GDA.new @set, 'gem.deps.rb' @gda = @GDA.new @set, 'gem.deps.rb'
@gda.instance_variable_set :@git_set, @git_set
@gda.instance_variable_set :@vendor_set, @vendor_set @gda.instance_variable_set :@vendor_set, @vendor_set
end end
@ -48,6 +50,18 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
Gem.instance_variables.include? :@ruby_version Gem.instance_variables.include? :@ruby_version
end end
def test_gemspec_without_group
@gda.send :add_dependencies, [:development], [dep('a', '= 1')]
assert_equal [dep('a', '= 1')], @set.dependencies
@gda.without_groups << :development
@gda.send :add_dependencies, [:development], [dep('b', '= 2')]
assert_equal [dep('a', '= 1')], @set.dependencies
end
def test_gem def test_gem
@gda.gem 'a' @gda.gem 'a'
@ -56,6 +70,65 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
assert_equal %w[a], @gda.requires['a'] assert_equal %w[a], @gda.requires['a']
end end
def test_gem_git
@gda.gem 'a', :git => 'git/a'
assert_equal [dep('a')], @set.dependencies
assert_equal %w[git/a master], @git_set.repositories['a']
end
def test_gem_git_branch
@gda.gem 'a', :git => 'git/a', :branch => 'other', :tag => 'v1'
assert_equal [dep('a')], @set.dependencies
assert_equal %w[git/a other], @git_set.repositories['a']
end
def test_gem_git_gist
@gda.gem 'a', :gist => 'a'
assert_equal [dep('a')], @set.dependencies
assert_equal %w[https://gist.github.com/a.git master],
@git_set.repositories['a']
end
def test_gem_git_ref
@gda.gem 'a', :git => 'git/a', :ref => 'abcd123', :branch => 'other'
assert_equal [dep('a')], @set.dependencies
assert_equal %w[git/a abcd123], @git_set.repositories['a']
end
def test_gem_git_submodules
@gda.gem 'a', :git => 'git/a', :submodules => true
assert_equal [dep('a')], @set.dependencies
assert_equal %w[git/a master], @git_set.repositories['a']
assert_equal %w[git/a], @git_set.need_submodules.keys
end
def test_gem_git_tag
@gda.gem 'a', :git => 'git/a', :tag => 'v1'
assert_equal [dep('a')], @set.dependencies
assert_equal %w[git/a v1], @git_set.repositories['a']
end
def test_gem_github
@gda.gem 'a', :github => 'example/repository'
assert_equal [dep('a')], @set.dependencies
assert_equal %w[git://github.com/example/repository.git master],
@git_set.repositories['a']
end
def test_gem_group def test_gem_group
@gda.gem 'a', :group => :test @gda.gem 'a', :group => :test
@ -284,6 +357,130 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
assert_equal [:a, :b, :c, :d], groups.sort_by { |group| group.to_s } assert_equal [:a, :b, :c, :d], groups.sort_by { |group| group.to_s }
end end
def test_gemspec
spec = util_spec 'a', 1, 'b' => 2
spec.add_development_dependency 'c', 3
open 'a.gemspec', 'w' do |io|
io.write spec.to_ruby_for_cache
end
@gda.gemspec
assert_equal [dep('b', '= 2'), dep('c', '=3')], @set.dependencies
assert_equal %w[a], @gda.requires['a']
end
def test_gemspec_bad
FileUtils.touch 'a.gemspec'
e = assert_raises ArgumentError do
capture_io do
@gda.gemspec
end
end
assert_equal 'invalid gemspec ./a.gemspec', e.message
end
def test_gemspec_development_group
spec = util_spec 'a', 1, 'b' => 2
spec.add_development_dependency 'c', 3
open 'a.gemspec', 'w' do |io|
io.write spec.to_ruby_for_cache
end
@gda.without_groups << :other
@gda.gemspec :development_group => :other
assert_equal [dep('b', '= 2')], @set.dependencies
assert_equal %w[a], @gda.requires['a']
end
def test_gemspec_multiple
open 'a.gemspec', 'w' do |io|
spec = util_spec 'a', 1, 'b' => 2
io.write spec.to_ruby_for_cache
end
open 'b.gemspec', 'w' do |io|
spec = util_spec 'b', 2, 'c' => 3
io.write spec.to_ruby_for_cache
end
e = assert_raises ArgumentError do
@gda.gemspec
end
assert_equal "found multiple gemspecs at #{@tempdir}, use the name: option to specify the one you want", e.message
end
def test_gemspec_name
open 'a.gemspec', 'w' do |io|
spec = util_spec 'a', 1, 'b' => 2
io.write spec.to_ruby_for_cache
end
open 'b.gemspec', 'w' do |io|
spec = util_spec 'b', 2, 'c' => 3
io.write spec.to_ruby_for_cache
end
@gda.gemspec :name => 'b'
assert_equal [dep('c', '= 3')], @set.dependencies
end
def test_gemspec_named
spec = util_spec 'a', 1, 'b' => 2
open 'other.gemspec', 'w' do |io|
io.write spec.to_ruby_for_cache
end
@gda.gemspec
assert_equal [dep('b', '= 2')], @set.dependencies
end
def test_gemspec_none
e = assert_raises ArgumentError do
@gda.gemspec
end
assert_equal "no gemspecs found at #{@tempdir}", e.message
end
def test_gemspec_path
spec = util_spec 'a', 1, 'b' => 2
FileUtils.mkdir 'other'
open 'other/a.gemspec', 'w' do |io|
io.write spec.to_ruby_for_cache
end
@gda.gemspec :path => 'other'
assert_equal [dep('b', '= 2')], @set.dependencies
end
def test_git
@gda.git 'git://example/repo.git' do
@gda.gem 'a'
@gda.gem 'b'
end
assert_equal [dep('a'), dep('b')], @set.dependencies
assert_equal %w[git://example/repo.git master], @git_set.repositories['a']
assert_equal %w[git://example/repo.git master], @git_set.repositories['b']
end
def test_group def test_group
@gda.group :test do @gda.group :test do
@gda.gem 'a' @gda.gem 'a'

View File

@ -13,7 +13,7 @@ class TestGemRequestSetLockfile < Gem::TestCase
@set = Gem::RequestSet.new @set = Gem::RequestSet.new
@vendor_set = Gem::DependencyResolver::VendorSet.new @vendor_set = Gem::Resolver::VendorSet.new
@set.instance_variable_set :@vendor_set, @vendor_set @set.instance_variable_set :@vendor_set, @vendor_set
@ -96,7 +96,7 @@ DEPENDENCIES
assert_equal [Gem::Platform::RUBY], @lockfile.platforms assert_equal [Gem::Platform::RUBY], @lockfile.platforms
lockfile_set = @set.sets.find do |set| lockfile_set = @set.sets.find do |set|
Gem::DependencyResolver::LockSet === set Gem::Resolver::LockSet === set
end end
assert lockfile_set, 'could not find a LockSet' assert lockfile_set, 'could not find a LockSet'

View File

@ -1,12 +1,11 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolver < Gem::TestCase class TestGemResolver < Gem::TestCase
def setup def setup
super super
@DR = Gem::DependencyResolver @DR = Gem::Resolver
end end
def make_dep(name, *req) def make_dep(name, *req)
@ -30,13 +29,17 @@ class TestGemDependencyResolver < Gem::TestCase
flunk e.message flunk e.message
end end
def test_self_compatibility
assert_same Gem::Resolver, Gem::DependencyResolver
end
def test_self_compose_sets_multiple def test_self_compose_sets_multiple
index_set = @DR::IndexSet.new index_set = @DR::IndexSet.new
vendor_set = @DR::VendorSet.new vendor_set = @DR::VendorSet.new
composed = @DR.compose_sets index_set, vendor_set composed = @DR.compose_sets index_set, vendor_set
assert_kind_of Gem::DependencyResolver::ComposedSet, composed assert_kind_of Gem::Resolver::ComposedSet, composed
assert_equal [index_set, vendor_set], composed.sets assert_equal [index_set, vendor_set], composed.sets
end end
@ -66,13 +69,13 @@ class TestGemDependencyResolver < Gem::TestCase
def test_handle_conflict def test_handle_conflict
a1 = util_spec 'a', 1 a1 = util_spec 'a', 1
r1 = Gem::DependencyResolver::DependencyRequest.new dep('a', '= 1'), nil r1 = Gem::Resolver::DependencyRequest.new dep('a', '= 1'), nil
r2 = Gem::DependencyResolver::DependencyRequest.new dep('a', '= 2'), nil r2 = Gem::Resolver::DependencyRequest.new dep('a', '= 2'), nil
r3 = Gem::DependencyResolver::DependencyRequest.new dep('a', '= 3'), nil r3 = Gem::Resolver::DependencyRequest.new dep('a', '= 3'), nil
existing = Gem::DependencyResolver::ActivationRequest.new a1, r1, false existing = Gem::Resolver::ActivationRequest.new a1, r1, false
res = Gem::DependencyResolver.new [a1] res = Gem::Resolver.new [a1]
res.handle_conflict r2, existing res.handle_conflict r2, existing
res.handle_conflict r2, existing res.handle_conflict r2, existing
@ -92,7 +95,7 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(a, b) s = set(a, b)
res = Gem::DependencyResolver.new(deps, s) res = Gem::Resolver.new(deps, s)
assert_resolves_to [a, b], res assert_resolves_to [a, b], res
end end
@ -109,7 +112,7 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(a, b, c) s = set(a, b, c)
res = Gem::DependencyResolver.new(deps, s) res = Gem::Resolver.new(deps, s)
assert_resolves_to [a, b, c], res assert_resolves_to [a, b, c], res
end end
@ -122,13 +125,13 @@ class TestGemDependencyResolver < Gem::TestCase
ad = make_dep "a" ad = make_dep "a"
res = Gem::DependencyResolver.new([ad], s) res = Gem::Resolver.new([ad], s)
assert_resolves_to [a2], res assert_resolves_to [a2], res
end end
def test_picks_best_platform def test_picks_best_platform
is = Gem::DependencyResolver::IndexSpecification is = Gem::Resolver::IndexSpecification
unknown = Gem::Platform.new 'unknown' unknown = Gem::Platform.new 'unknown'
a2_p1 = a3_p2 = nil a2_p1 = a3_p2 = nil
@ -153,7 +156,7 @@ class TestGemDependencyResolver < Gem::TestCase
ad = make_dep "a" ad = make_dep "a"
res = Gem::DependencyResolver.new([ad], s) res = Gem::Resolver.new([ad], s)
assert_resolves_to [a2_p1], res assert_resolves_to [a2_p1], res
end end
@ -169,7 +172,7 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(a1, b1, c1) s = set(a1, b1, c1)
res = Gem::DependencyResolver.new([ad, bd], s) res = Gem::Resolver.new([ad, bd], s)
assert_resolves_to [a1, b1, c1], res assert_resolves_to [a1, b1, c1], res
end end
@ -186,17 +189,9 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(a1, b1, c1, c2) s = set(a1, b1, c1, c2)
res = Gem::DependencyResolver.new([ad, bd], s) res = Gem::Resolver.new([ad, bd], s)
assert_resolves_to [a1, b1, c1], res assert_resolves_to [a1, b1, c1], res
cons = res.conflicts
assert_equal 1, cons.size
con = cons.first
assert_equal "c (= 1)", con.dependency.to_s
assert_equal "c-2", con.activated.full_name
end end
def test_conflict_resolution_only_effects_correct_spec def test_conflict_resolution_only_effects_correct_spec
@ -214,7 +209,7 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(a1, b1, d3, d4, c1, c2) s = set(a1, b1, d3, d4, c1, c2)
res = Gem::DependencyResolver.new([ad, bd], s) res = Gem::Resolver.new([ad, bd], s)
assert_resolves_to [a1, b1, c1, d4], res assert_resolves_to [a1, b1, c1, d4], res
@ -239,31 +234,31 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(a1, b1, c1, c2) s = set(a1, b1, c1, c2)
r = Gem::DependencyResolver.new([ad, bd], s) r = Gem::Resolver.new([ad, bd], s)
e = assert_raises Gem::DependencyResolutionError do e = assert_raises Gem::DependencyResolutionError do
r.resolve r.resolve
end end
deps = [make_dep("c", "= 2"), make_dep("c", "= 1")] deps = [make_dep("c", "= 1"), make_dep("c", "= 2")]
assert_equal deps, e.conflicting_dependencies assert_equal deps, e.conflicting_dependencies
con = e.conflict con = e.conflict
act = con.activated act = con.activated
assert_equal "c-1", act.spec.full_name assert_equal "c-2", act.spec.full_name
parent = act.parent parent = act.parent
assert_equal "a-1", parent.spec.full_name assert_equal "b-1", parent.spec.full_name
act = con.requester act = con.requester
assert_equal "b-1", act.spec.full_name assert_equal "a-1", act.spec.full_name
end end
def test_raises_when_a_gem_is_missing def test_raises_when_a_gem_is_missing
ad = make_dep "a" ad = make_dep "a"
r = Gem::DependencyResolver.new([ad], set) r = Gem::Resolver.new([ad], set)
e = assert_raises Gem::UnsatisfiableDepedencyError do e = assert_raises Gem::UnsatisfiableDepedencyError do
r.resolve r.resolve
@ -280,7 +275,7 @@ class TestGemDependencyResolver < Gem::TestCase
ad = make_dep "a", "= 3" ad = make_dep "a", "= 3"
r = Gem::DependencyResolver.new([ad], set(a1)) r = Gem::Resolver.new([ad], set(a1))
e = assert_raises Gem::UnsatisfiableDepedencyError do e = assert_raises Gem::UnsatisfiableDepedencyError do
r.resolve r.resolve
@ -293,7 +288,7 @@ class TestGemDependencyResolver < Gem::TestCase
a1 = util_spec "a", "1" a1 = util_spec "a", "1"
ad = make_dep "a", "= 3" ad = make_dep "a", "= 3"
r = Gem::DependencyResolver.new([ad], set(a1)) r = Gem::Resolver.new([ad], set(a1))
e = assert_raises Gem::UnsatisfiableDepedencyError do e = assert_raises Gem::UnsatisfiableDepedencyError do
r.resolve r.resolve
@ -310,7 +305,7 @@ class TestGemDependencyResolver < Gem::TestCase
ad = make_dep "a", "= 1" ad = make_dep "a", "= 1"
r = Gem::DependencyResolver.new([ad], set(a1)) r = Gem::Resolver.new([ad], set(a1))
e = assert_raises Gem::UnsatisfiableDepedencyError do e = assert_raises Gem::UnsatisfiableDepedencyError do
r.resolve r.resolve
@ -333,7 +328,7 @@ class TestGemDependencyResolver < Gem::TestCase
ad = make_dep "a" ad = make_dep "a"
bd = make_dep "b" bd = make_dep "b"
r = Gem::DependencyResolver.new([ad, bd], s) r = Gem::Resolver.new([ad, bd], s)
e = assert_raises Gem::DependencyResolutionError do e = assert_raises Gem::DependencyResolutionError do
r.resolve r.resolve
@ -345,11 +340,11 @@ class TestGemDependencyResolver < Gem::TestCase
assert_equal req('>= 0'), dependency.requirement assert_equal req('>= 0'), dependency.requirement
activated = e.conflict.activated activated = e.conflict.activated
assert_equal 'c-2', activated.full_name assert_equal 'c-1', activated.full_name
assert_equal dep('c', '>= 2'), activated.request.dependency assert_equal dep('c', '= 1'), activated.request.dependency
assert_equal [dep('c', '= 1'), dep('c', '>= 2')], assert_equal [dep('c', '>= 2'), dep('c', '= 1')],
e.conflict.conflicting_dependencies e.conflict.conflicting_dependencies
end end
@ -363,7 +358,7 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(a1, b1, c1) s = set(a1, b1, c1)
r = Gem::DependencyResolver.new([ad, bd], s) r = Gem::Resolver.new([ad, bd], s)
assert_resolves_to [a1, b1, c1], r assert_resolves_to [a1, b1, c1], r
end end
@ -382,13 +377,13 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(lib1, rails, ap, rack100, rack101) s = set(lib1, rails, ap, rack100, rack101)
r = Gem::DependencyResolver.new([d1, d2], s) r = Gem::Resolver.new([d1, d2], s)
assert_resolves_to [rails, ap, rack101, lib1], r assert_resolves_to [rails, ap, rack101, lib1], r
# check it with the deps reverse too # check it with the deps reverse too
r = Gem::DependencyResolver.new([d2, d1], s) r = Gem::Resolver.new([d2, d1], s)
assert_resolves_to [lib1, rack101, rails, ap], r assert_resolves_to [lib1, rack101, rails, ap], r
end end
@ -405,7 +400,7 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(a1, a2, a3, a4) s = set(a1, a2, a3, a4)
r = Gem::DependencyResolver.new([d1, d2, d3], s) r = Gem::Resolver.new([d1, d2, d3], s)
assert_raises Gem::DependencyResolutionError do assert_raises Gem::DependencyResolutionError do
r.resolve r.resolve
@ -423,7 +418,7 @@ class TestGemDependencyResolver < Gem::TestCase
a_dep = dep 'a', '~> 1.0' a_dep = dep 'a', '~> 1.0'
b_dep = dep 'b' b_dep = dep 'b'
r = Gem::DependencyResolver.new [a_dep, b_dep], s r = Gem::Resolver.new [a_dep, b_dep], s
assert_raises Gem::DependencyResolutionError do assert_raises Gem::DependencyResolutionError do
r.resolve r.resolve
@ -444,7 +439,7 @@ class TestGemDependencyResolver < Gem::TestCase
a_dep = dep 'a', '= 1' a_dep = dep 'a', '= 1'
r = Gem::DependencyResolver.new [a_dep], s r = Gem::Resolver.new [a_dep], s
assert_resolves_to [a1, b1, c1], r assert_resolves_to [a1, b1, c1], r
end end
@ -461,7 +456,7 @@ class TestGemDependencyResolver < Gem::TestCase
a_dep = dep 'a', '~> 1.0' a_dep = dep 'a', '~> 1.0'
b_dep = dep 'b' b_dep = dep 'b'
r = Gem::DependencyResolver.new [a_dep, b_dep], s r = Gem::Resolver.new [a_dep, b_dep], s
assert_resolves_to [a1, b1], r assert_resolves_to [a1, b1], r
end end
@ -484,7 +479,7 @@ class TestGemDependencyResolver < Gem::TestCase
d1 = make_dep "activemerchant" d1 = make_dep "activemerchant"
d2 = make_dep "actionmailer" d2 = make_dep "actionmailer"
r = Gem::DependencyResolver.new([d1, d2], s) r = Gem::Resolver.new([d1, d2], s)
assert_resolves_to [merch, mail, sup1], r assert_resolves_to [merch, mail, sup1], r
end end
@ -502,13 +497,13 @@ class TestGemDependencyResolver < Gem::TestCase
p1 = make_dep "b", "> 0" p1 = make_dep "b", "> 0"
p2 = make_dep "d", "> 0" p2 = make_dep "d", "> 0"
r = Gem::DependencyResolver.new([p1, p2], s) r = Gem::Resolver.new([p1, p2], s)
assert_resolves_to [b1, c1, d2], r assert_resolves_to [b1, c1, d2], r
end end
def test_select_local_platforms def test_select_local_platforms
r = Gem::DependencyResolver.new nil, nil r = Gem::Resolver.new nil, nil
a1 = util_spec 'a', 1 a1 = util_spec 'a', 1
a1_p1 = util_spec 'a', 1 do |s| s.platform = Gem::Platform.local end a1_p1 = util_spec 'a', 1 do |s| s.platform = Gem::Platform.local end
@ -526,7 +521,7 @@ class TestGemDependencyResolver < Gem::TestCase
ad = make_dep "a", "= 1" ad = make_dep "a", "= 1"
r = Gem::DependencyResolver.new([ad], set(a1)) r = Gem::Resolver.new([ad], set(a1))
e = assert_raises Gem::UnsatisfiableDepedencyError do e = assert_raises Gem::UnsatisfiableDepedencyError do
r.resolve r.resolve

View File

@ -1,11 +1,11 @@
require 'rubygems/test_case' require 'rubygems/test_case'
class TestGemDependencyResolverActivationRequest < Gem::TestCase class TestGemResolverActivationRequest < Gem::TestCase
def setup def setup
super super
@DR = Gem::DependencyResolver @DR = Gem::Resolver
@dep = @DR::DependencyRequest.new dep('a', '>= 0'), nil @dep = @DR::DependencyRequest.new dep('a', '>= 0'), nil
@ -36,7 +36,7 @@ class TestGemDependencyResolverActivationRequest < Gem::TestCase
end end
def test_installed_eh def test_installed_eh
v_spec = Gem::DependencyResolver::VendorSpecification.new nil, @a3 v_spec = Gem::Resolver::VendorSpecification.new nil, @a3
@req = @DR::ActivationRequest.new v_spec, @dep, [@a1, @a2] @req = @DR::ActivationRequest.new v_spec, @dep, [@a1, @a2]

View File

@ -1,12 +1,11 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverAPISet < Gem::TestCase class TestGemResolverAPISet < Gem::TestCase
def setup def setup
super super
@DR = Gem::DependencyResolver @DR = Gem::Resolver
end end
def test_initialize def test_initialize

View File

@ -1,10 +1,9 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverAPISpecification < Gem::TestCase class TestGemResolverAPISpecification < Gem::TestCase
def test_initialize def test_initialize
set = Gem::DependencyResolver::APISet.new set = Gem::Resolver::APISet.new
data = { data = {
:name => 'rails', :name => 'rails',
:number => '3.0.3', :number => '3.0.3',
@ -15,7 +14,7 @@ class TestGemDependencyResolverAPISpecification < Gem::TestCase
], ],
} }
spec = Gem::DependencyResolver::APISpecification.new set, data spec = Gem::Resolver::APISpecification.new set, data
assert_equal 'rails', spec.name assert_equal 'rails', spec.name
assert_equal Gem::Version.new('3.0.3'), spec.version assert_equal Gem::Version.new('3.0.3'), spec.version

View File

@ -1,12 +1,11 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverBestSet < Gem::TestCase class TestGemResolverBestSet < Gem::TestCase
def setup def setup
super super
@DR = Gem::DependencyResolver @DR = Gem::Resolver
end end
def test_find_all_index def test_find_all_index

View File

@ -1,7 +1,10 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverDependencyConflict < Gem::TestCase class TestGemResolverConflict < Gem::TestCase
def test_self_compatibility
assert_same Gem::Resolver::Conflict, Gem::Resolver::DependencyConflict
end
def test_explanation def test_explanation
root = root =
@ -10,7 +13,7 @@ class TestGemDependencyResolverDependencyConflict < Gem::TestCase
dependency_request dep('net-ssh', '>= 2.6.5'), 'net-ssh', '2.2.2', root dependency_request dep('net-ssh', '>= 2.6.5'), 'net-ssh', '2.2.2', root
conflict = conflict =
Gem::DependencyResolver::DependencyConflict.new child, child.requester Gem::Resolver::Conflict.new child, child.requester
expected = <<-EXPECTED expected = <<-EXPECTED
Activated net-ssh-2.2.2 instead of (>= 2.6.5) via: Activated net-ssh-2.2.2 instead of (>= 2.6.5) via:
@ -21,7 +24,7 @@ class TestGemDependencyResolverDependencyConflict < Gem::TestCase
end end
def test_explanation_user_request def test_explanation_user_request
@DR = Gem::DependencyResolver @DR = Gem::Resolver
spec = util_spec 'a', 2 spec = util_spec 'a', 2
@ -30,7 +33,7 @@ class TestGemDependencyResolverDependencyConflict < Gem::TestCase
activated = @DR::ActivationRequest.new spec, a2_req activated = @DR::ActivationRequest.new spec, a2_req
conflict = @DR::DependencyConflict.new a1_req, activated conflict = @DR::Conflict.new a1_req, activated
expected = <<-EXPECTED expected = <<-EXPECTED
Activated a-2 instead of (= 1) via: Activated a-2 instead of (= 1) via:
@ -47,7 +50,7 @@ class TestGemDependencyResolverDependencyConflict < Gem::TestCase
dependency_request dep('net-ssh', '>= 2.6.5'), 'net-ssh', '2.2.2', root dependency_request dep('net-ssh', '>= 2.6.5'), 'net-ssh', '2.2.2', root
conflict = conflict =
Gem::DependencyResolver::DependencyConflict.new child, nil Gem::Resolver::Conflict.new child, nil
assert_equal %w[net-ssh-2.2.2 rye-0.9.8], conflict.request_path assert_equal %w[net-ssh-2.2.2 rye-0.9.8], conflict.request_path
end end

View File

@ -1,11 +1,11 @@
require 'rubygems/test_case' require 'rubygems/test_case'
class TestGemDependencyResolverDependencyRequest < Gem::TestCase class TestGemResolverDependencyRequest < Gem::TestCase
def setup def setup
super super
@DR = Gem::DependencyResolver::DependencyRequest @DR = Gem::Resolver::DependencyRequest
end end
def test_requirement def test_requirement

View File

@ -0,0 +1,84 @@
require 'rubygems/test_case'
class TestGemResolverGitSet < Gem::TestCase
def setup
super
@set = Gem::Resolver::GitSet.new
@reqs = Gem::Resolver::RequirementList.new
end
def test_add_git_gem
name, version, repository, = git_gem
@set.add_git_gem name, repository, 'master', false
dependency = dep 'a'
specs = @set.find_all dependency
assert_equal "#{name}-#{version}", specs.first.full_name
refute @set.need_submodules[repository]
end
def test_add_git_gem_submodules
name, _, repository, = git_gem
@set.add_git_gem name, repository, 'master', true
dependency = dep 'a'
refute_empty @set.find_all dependency
assert @set.need_submodules[repository]
end
def test_find_all
name, _, repository, = git_gem
@set.add_git_gem name, repository, 'master', false
dependency = dep 'a', '~> 1.0'
req = Gem::Resolver::ActivationRequest.new dependency, nil
@reqs.add req
@set.prefetch @reqs
found = @set.find_all dependency
assert_equal [@set.specs['a']], found
end
def test_prefetch
name, _, repository, = git_gem
@set.add_git_gem name, repository, 'master', false
dependency = dep name
req = Gem::Resolver::ActivationRequest.new dependency, nil
@reqs.add req
@set.prefetch @reqs
refute_empty @set.specs
end
def test_prefetch_filter
name, _, repository, = git_gem
@set.add_git_gem name, repository, 'master', false
dependency = dep 'b'
req = Gem::Resolver::ActivationRequest.new dependency, nil
@reqs.add req
@set.prefetch @reqs
assert_empty @set.specs
end
end

View File

@ -0,0 +1,36 @@
require 'rubygems/test_case'
class TestGemResolverGitSpecification < Gem::TestCase
def setup
super
@set = Gem::Resolver::GitSet.new
@spec = Gem::Specification.new 'a', 1
end
def test_equals2
g_spec_a = Gem::Resolver::GitSpecification.new @set, @spec
assert_equal g_spec_a, g_spec_a
spec_b = Gem::Specification.new 'b', 1
g_spec_b = Gem::Resolver::GitSpecification.new @set, spec_b
refute_equal g_spec_a, g_spec_b
g_set = Gem::Resolver::GitSet.new
g_spec_s = Gem::Resolver::GitSpecification.new g_set, @spec
refute_equal g_spec_a, g_spec_s
i_set = Gem::Resolver::IndexSet.new
source = Gem::Source.new @gem_repo
i_spec = Gem::Resolver::IndexSpecification.new(
i_set, 'a', v(1), source, Gem::Platform::RUBY)
refute_equal g_spec_a, i_spec
end
end

View File

@ -1,12 +1,11 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverIndexSet < Gem::TestCase class TestGemResolverIndexSet < Gem::TestCase
def setup def setup
super super
@DR = Gem::DependencyResolver @DR = Gem::Resolver
end end
def test_initialize def test_initialize

View File

@ -1,15 +1,14 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
require 'rubygems/available_set' require 'rubygems/available_set'
class TestGemDependencyResolverIndexSpecification < Gem::TestCase class TestGemResolverIndexSpecification < Gem::TestCase
def test_initialize def test_initialize
set = Gem::DependencyResolver::IndexSet.new set = Gem::Resolver::IndexSet.new
source = Gem::Source.new @gem_repo source = Gem::Source.new @gem_repo
version = Gem::Version.new '3.0.3' version = Gem::Version.new '3.0.3'
spec = Gem::DependencyResolver::IndexSpecification.new( spec = Gem::Resolver::IndexSpecification.new(
set, 'rails', version, source, Gem::Platform::RUBY) set, 'rails', version, source, Gem::Platform::RUBY)
assert_equal 'rails', spec.name assert_equal 'rails', spec.name
@ -20,11 +19,11 @@ class TestGemDependencyResolverIndexSpecification < Gem::TestCase
end end
def test_initialize_platform def test_initialize_platform
set = Gem::DependencyResolver::IndexSet.new set = Gem::Resolver::IndexSet.new
source = Gem::Source::Local.new source = Gem::Source::Local.new
version = Gem::Version.new '3.0.3' version = Gem::Version.new '3.0.3'
spec = Gem::DependencyResolver::IndexSpecification.new( spec = Gem::Resolver::IndexSpecification.new(
set, 'rails', version, source, Gem::Platform.local) set, 'rails', version, source, Gem::Platform.local)
assert_equal Gem::Platform.local.to_s, spec.platform assert_equal Gem::Platform.local.to_s, spec.platform
@ -39,8 +38,8 @@ class TestGemDependencyResolverIndexSpecification < Gem::TestCase
source = Gem::Source.new @gem_repo source = Gem::Source.new @gem_repo
version = v 2 version = v 2
set = Gem::DependencyResolver::IndexSet.new set = Gem::Resolver::IndexSet.new
i_spec = Gem::DependencyResolver::IndexSpecification.new \ i_spec = Gem::Resolver::IndexSpecification.new \
set, 'a', version, source, Gem::Platform.local set, 'a', version, source, Gem::Platform.local
spec = i_spec.spec spec = i_spec.spec
@ -53,10 +52,10 @@ class TestGemDependencyResolverIndexSpecification < Gem::TestCase
Gem::Package.build a_2_p Gem::Package.build a_2_p
source = Gem::Source::Local.new source = Gem::Source::Local.new
set = Gem::DependencyResolver::InstallerSet.new :local set = Gem::Resolver::InstallerSet.new :local
set.always_install << a_2_p set.always_install << a_2_p
i_spec = Gem::DependencyResolver::IndexSpecification.new \ i_spec = Gem::Resolver::IndexSpecification.new \
set, 'a', v(2), source, Gem::Platform.local set, 'a', v(2), source, Gem::Platform.local
spec = i_spec.spec spec = i_spec.spec

View File

@ -1,14 +1,13 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverInstalledSpecification < Gem::TestCase class TestGemResolverInstalledSpecification < Gem::TestCase
def test_initialize def test_initialize
set = Gem::DependencyResolver::CurrentSet.new set = Gem::Resolver::CurrentSet.new
source_spec = util_spec 'a' source_spec = util_spec 'a'
spec = Gem::DependencyResolver::InstalledSpecification.new set, source_spec spec = Gem::Resolver::InstalledSpecification.new set, source_spec
assert_equal 'a', spec.name assert_equal 'a', spec.name
assert_equal Gem::Version.new(2), spec.version assert_equal Gem::Version.new(2), spec.version

View File

@ -1,7 +1,6 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverInstallerSet < Gem::TestCase class TestGemResolverInstallerSet < Gem::TestCase
def test_load_spec def test_load_spec
specs = spec_fetcher do |fetcher| specs = spec_fetcher do |fetcher|
@ -12,7 +11,7 @@ class TestGemDependencyResolverInstallerSet < Gem::TestCase
source = Gem::Source.new @gem_repo source = Gem::Source.new @gem_repo
version = v 2 version = v 2
set = Gem::DependencyResolver::InstallerSet.new :remote set = Gem::Resolver::InstallerSet.new :remote
spec = set.load_spec 'a', version, Gem::Platform.local, source spec = set.load_spec 'a', version, Gem::Platform.local, source

View File

@ -1,14 +1,13 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverLockSet < Gem::TestCase class TestGemResolverLockSet < Gem::TestCase
def setup def setup
super super
@source = Gem::Source.new @gem_repo @source = Gem::Source.new @gem_repo
@set = Gem::DependencyResolver::LockSet.new @source @set = Gem::Resolver::LockSet.new @source
end end
def test_add def test_add

View File

@ -0,0 +1,19 @@
require 'rubygems/test_case'
class TestGemResolverRequirementList < Gem::TestCase
def setup
super
@list = Gem::Resolver::RequirementList.new
end
def test_each
@list.add 1
@list.add 2
assert_equal [1, 2], @list.each.to_a
end
end

View File

@ -1,12 +1,11 @@
require 'rubygems/test_case' require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverVendorSet < Gem::TestCase class TestGemResolverVendorSet < Gem::TestCase
def setup def setup
super super
@set = Gem::DependencyResolver::VendorSet.new @set = Gem::Resolver::VendorSet.new
end end
def test_add_vendor_gem def test_add_vendor_gem
@ -39,7 +38,7 @@ class TestGemDependencyResolverVendorSet < Gem::TestCase
dependency = dep 'a', '~> 1' dependency = dep 'a', '~> 1'
req = Gem::DependencyResolver::DependencyRequest.new dependency, nil req = Gem::Resolver::DependencyRequest.new dependency, nil
found = @set.find_all req found = @set.find_all req
@ -48,7 +47,7 @@ class TestGemDependencyResolverVendorSet < Gem::TestCase
source = Gem::Source::Vendor.new directory source = Gem::Source::Vendor.new directory
expected = [ expected = [
Gem::DependencyResolver::VendorSpecification.new(@set, spec, source) Gem::Resolver::VendorSpecification.new(@set, spec, source)
] ]
assert_equal expected, found assert_equal expected, found

View File

@ -0,0 +1,71 @@
require 'rubygems/test_case'
class TestGemResolverVendorSpecification < Gem::TestCase
def setup
super
@set = Gem::Resolver::VendorSet.new
@spec = Gem::Specification.new 'a', 1
end
def test_equals2
v_spec_a = Gem::Resolver::VendorSpecification.new @set, @spec
assert_equal v_spec_a, v_spec_a
spec_b = Gem::Specification.new 'b', 1
v_spec_b = Gem::Resolver::VendorSpecification.new @set, spec_b
refute_equal v_spec_a, v_spec_b
v_set = Gem::Resolver::VendorSet.new
v_spec_s = Gem::Resolver::VendorSpecification.new v_set, @spec
refute_equal v_spec_a, v_spec_s
i_set = Gem::Resolver::IndexSet.new
source = Gem::Source.new @gem_repo
i_spec = Gem::Resolver::IndexSpecification.new(
i_set, 'a', v(1), source, Gem::Platform::RUBY)
refute_equal v_spec_a, i_spec
end
def test_dependencies
@spec.add_dependency 'b'
@spec.add_dependency 'c'
v_spec = Gem::Resolver::VendorSpecification.new @set, @spec
assert_equal [dep('b'), dep('c')], v_spec.dependencies
end
def test_full_name
v_spec = Gem::Resolver::VendorSpecification.new @set, @spec
assert_equal 'a-1', v_spec.full_name
end
def test_name
v_spec = Gem::Resolver::VendorSpecification.new @set, @spec
assert_equal 'a', v_spec.name
end
def test_platform
v_spec = Gem::Resolver::VendorSpecification.new @set, @spec
assert_equal Gem::Platform::RUBY, v_spec.platform
end
def test_version
spec = Gem::Specification.new 'a', 1
v_spec = Gem::Resolver::VendorSpecification.new @set, spec
assert_equal v(1), v_spec.version
end
end

View File

@ -44,13 +44,13 @@ class TestGemSource < Gem::TestCase
set = @source.dependency_resolver_set set = @source.dependency_resolver_set
assert_kind_of Gem::DependencyResolver::APISet, set assert_kind_of Gem::Resolver::APISet, set
end end
def test_dependency_resolver_set_marshal_api def test_dependency_resolver_set_marshal_api
set = @source.dependency_resolver_set set = @source.dependency_resolver_set
assert_kind_of Gem::DependencyResolver::IndexSet, set assert_kind_of Gem::Resolver::IndexSet, set
end end
def test_fetch_spec def test_fetch_spec

View File

@ -0,0 +1,153 @@
require 'rubygems/test_case'
require 'rubygems/source'
class TestGemSourceGit < Gem::TestCase
def setup
super
@name, @version, @repository, @head = git_gem
@hash = Digest::SHA1.hexdigest @repository
@source = Gem::Source::Git.new @name, @repository, 'master', false
end
def test_checkout
@source.checkout
assert_path_exists File.join @source.install_dir, 'a.gemspec'
end
def test_checkout_submodules
source = Gem::Source::Git.new @name, @repository, 'master', true
git_gem 'b'
Dir.chdir 'git/a' do
system @git, 'submodule', '--quiet', 'add', File.expand_path('../b'), 'b'
system @git, 'commit', '--quiet', '-m', 'add submodule b'
end
source.checkout
assert_path_exists File.join source.install_dir, 'a.gemspec'
assert_path_exists File.join source.install_dir, 'b/b.gemspec'
end
def test_cache
assert @source.cache
assert_path_exists @source.repo_cache_dir
Dir.chdir @source.repo_cache_dir do
assert_equal @head, Gem::Util.popen(@git, 'rev-parse', 'master').strip
end
end
def test_dir_shortref
@source.cache
assert_equal @head[0..11], @source.dir_shortref
end
def test_equals2
assert_equal @source, @source
assert_equal @source, @source.dup
source =
Gem::Source::Git.new @source.name, @source.repository, 'other', false
refute_equal @source, source
source =
Gem::Source::Git.new @source.name, 'repo/other', @source.reference, false
refute_equal @source, source
source =
Gem::Source::Git.new 'b', @source.repository, @source.reference, false
refute_equal @source, source
source =
Gem::Source::Git.new @source.name, @source.repository, @source.reference,
true
refute_equal @source, source
end
def test_load_spec
spec = @source.load_spec @name
assert_equal "#{@name}-#{@version}", spec.full_name
end
def test_install_dir
@source.cache
expected = File.join Gem.dir, 'bundler', 'gems', "a-#{@head[0..11]}"
assert_equal expected, @source.install_dir
end
def test_repo_cache_dir
expected =
File.join Gem.dir, 'cache', 'bundler', 'git', "a-#{@hash}"
assert_equal expected, @source.repo_cache_dir
end
def test_rev_parse
@source.cache
assert_equal @head, @source.rev_parse
Dir.chdir @repository do
system @git, 'checkout', '--quiet', '-b', 'other'
end
master_head = @head
git_gem 'a', 2
source = Gem::Source::Git.new @name, @repository, 'other', false
source.cache
refute_equal master_head, source.rev_parse
end
def test_spaceship
git = Gem::Source::Git.new 'a', 'git/a', 'master', false
remote = Gem::Source.new @gem_repo
installed = Gem::Source::Installed.new
assert_equal( 0, git. <=>(git), 'git <=> git')
assert_equal( 1, git. <=>(remote), 'git <=> remote')
assert_equal(-1, remote. <=>(git), 'remote <=> git')
assert_equal( 1, installed.<=>(git), 'installed <=> git')
assert_equal(-1, git. <=>(installed), 'git <=> installed')
end
def test_uri_hash
assert_equal @hash, @source.uri_hash
source =
Gem::Source::Git.new 'a', 'http://git@example/repo.git', 'master', false
assert_equal '291c4caac7feba8bb64c297987028acb3dde6cfe',
source.uri_hash
source =
Gem::Source::Git.new 'a', 'HTTP://git@EXAMPLE/repo.git', 'master', false
assert_equal '291c4caac7feba8bb64c297987028acb3dde6cfe',
source.uri_hash
end
end

View File

@ -9,5 +9,19 @@ class TestGemSourceVendor < Gem::TestCase
assert_equal 'vendor/foo', source.uri assert_equal 'vendor/foo', source.uri
end end
def test_spaceship
vendor = Gem::Source::Vendor.new 'vendor/foo'
remote = Gem::Source.new @gem_repo
installed = Gem::Source::Installed.new
assert_equal( 0, vendor. <=>(vendor), 'vendor <=> vendor')
assert_equal( 1, vendor. <=>(remote), 'vendor <=> remote')
assert_equal(-1, remote. <=>(vendor), 'remote <=> vendor')
assert_equal( 1, vendor. <=>(installed), 'vendor <=> installed')
assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor')
end
end end

View File

@ -1733,7 +1733,7 @@ dependencies: []
full_gem_path = Pathname(@ext.full_gem_path) full_gem_path = Pathname(@ext.full_gem_path)
relative_install_dir = ext_install_dir.relative_path_from full_gem_path relative_install_dir = ext_install_dir.relative_path_from full_gem_path
assert_equal ['lib', relative_install_dir.to_s], @ext.require_paths assert_equal [relative_install_dir.to_s, 'lib'], @ext.require_paths
ensure ensure
RbConfig::CONFIG['ENABLE_SHARED'] = enable_shared RbConfig::CONFIG['ENABLE_SHARED'] = enable_shared
end end
@ -1744,8 +1744,8 @@ dependencies: []
@ext.require_path = 'lib' @ext.require_path = 'lib'
expected = [ expected = [
File.join(@gemhome, 'gems', @ext.original_name, 'lib'),
@ext.extension_install_dir, @ext.extension_install_dir,
File.join(@gemhome, 'gems', @ext.original_name, 'lib'),
] ]
assert_equal expected, @ext.full_require_paths assert_equal expected, @ext.full_require_paths

View File

@ -31,7 +31,7 @@ class TestStubSpecification < Gem::TestCase
assert_equal 'stub_e', stub.name assert_equal 'stub_e', stub.name
assert_equal v(2), stub.version assert_equal v(2), stub.version
assert_equal Gem::Platform::RUBY, stub.platform assert_equal Gem::Platform::RUBY, stub.platform
assert_equal ['lib', relative_install_dir], stub.require_paths assert_equal [relative_install_dir, 'lib'], stub.require_paths
assert_equal %w[ext/stub_e/extconf.rb], stub.extensions assert_equal %w[ext/stub_e/extconf.rb], stub.extensions
end end
@ -78,8 +78,8 @@ class TestStubSpecification < Gem::TestCase
stub = stub_with_extension stub = stub_with_extension
expected = [ expected = [
File.join(stub.full_gem_path, 'lib'),
stub.extension_install_dir, stub.extension_install_dir,
File.join(stub.full_gem_path, 'lib'),
] ]
assert_equal expected, stub.full_require_paths assert_equal expected, stub.full_require_paths

View File

@ -0,0 +1,11 @@
require 'rubygems/test_case'
require 'rubygems/util'
class TestGemUtil < Gem::TestCase
def test_class_popen
assert_equal "0\n", Gem::Util.popen(Gem.ruby, '-e', 'p 0')
end
end