* 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>
* configure.in (LOCALTIME_OVERFLOW_PROBLEM): Define it for cross

View File

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

View File

@ -1,53 +1,54 @@
RubyGems is copyrighted free software by Chad Fowler, Rich Kilmer, Jim
Weirich and others. You can redistribute it and/or modify it under
either the terms of the GPL (see the GPL.txt file), or the conditions
below:
either the terms of the MIT license (see the file MIT.txt), or the
conditions below:
1. You may make and give away verbatim copies of the source form of the
software without restriction, provided that you duplicate all of the
original copyright notices and associated disclaimers.
1. You may make and give away verbatim copies of the source form of the
software without restriction, provided that you duplicate all of the
original copyright notices and associated disclaimers.
2. You may modify your copy of the software in any way, provided that
you do at least ONE of the following:
2. You may modify your copy of the software in any way, provided that
you do at least ONE of the following:
a) place your modifications in the Public Domain or otherwise
make them Freely Available, such as by posting said
modifications to Usenet or an equivalent medium, or by allowing
the author to include your modifications in the software.
a. place your modifications in the Public Domain or otherwise
make them Freely Available, such as by posting said
modifications to Usenet or an equivalent medium, or by allowing
the author to include your modifications in the software.
b) use the modified software only within your corporation or
organization.
b. use the modified software only within your corporation or
organization.
c) rename any non-standard executables so the names do not conflict
with standard executables, which must also be provided.
c. give non-standard executables non-standard names, with
instructions on where to get the original software distribution.
d) make other distribution arrangements with the author.
d. make other distribution arrangements with the author.
3. You may distribute the software in object code or executable
form, provided that you do at least ONE of the following:
3. You may distribute the software in object code or executable
form, provided that you do at least ONE of the following:
a) distribute the executables and library files of the software,
together with instructions (in the manual page or equivalent)
on where to get the original distribution.
a. distribute the executables and library files of the software,
together with instructions (in the manual page or equivalent)
on where to get the original distribution.
b) accompany the distribution with the machine-readable source of
the software.
b. accompany the distribution with the machine-readable source of
the software.
c) give non-standard executables non-standard names, with
instructions on where to get the original software distribution.
c. give non-standard executables non-standard names, with
instructions on where to get the original software distribution.
d) make other distribution arrangements with the author.
d. make other distribution arrangements with the author.
4. You may modify and include the part of the software into any other
software (possibly commercial).
4. You may modify and include the part of the software into any other
software (possibly commercial).
5. The scripts and library files supplied as input to or produced as
output from the software do not automatically fall under the
copyright of the software, but belong to whomever generated them,
and may be sold commercially, and may be aggregated with this
software.
5. The scripts and library files supplied as input to or produced as
output from the software do not automatically fall under the
copyright of the software, but belong to whomever generated them,
and may be sold commercially, and may be aggregated with this
software.
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.

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.
def find_all(req)
@ -127,7 +127,7 @@ class Gem::AvailableSet
end
match.map do |t|
Gem::DependencyResolver::InstalledSpecification.new(self, t.spec, t.source)
Gem::Resolver::InstalledSpecification.new(self, t.spec, t.source)
end
end

View File

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

View File

@ -56,6 +56,12 @@ class Gem::Commands::InstallCommand < Gem::Command
o[:install_as_default] = v
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
end
@ -185,8 +191,23 @@ to write the specification by hand. For example:
return if options[:conservative] and
not Gem::Dependency.new(name, version).matching_specs.empty?
req = Gem::Requirement.create(version)
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)

View File

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

View File

@ -1,6 +1,5 @@
require 'rubygems'
require 'rubygems/dependency_list'
require 'rubygems/dependency_resolver'
require 'rubygems/package'
require 'rubygems/installer'
require 'rubygems/spec_fetcher'
@ -196,7 +195,7 @@ class Gem::DependencyInstaller
# sources. Gems are sorted with newer gems preferred over older gems, and
# local gems preferred over remote gems.
def find_gems_with_sources dep # :nodoc:
def find_gems_with_sources dep, best_only=false # :nodoc:
set = Gem::AvailableSet.new
if consider_local?
@ -211,7 +210,26 @@ class Gem::DependencyInstaller
if consider_remote?
begin
found, errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep
# 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
@errors += errors
@ -219,7 +237,7 @@ class Gem::DependencyInstaller
@errors = errors
end
set << found
set << specs
rescue Gem::RemoteFetcher::FetchError => e
# FIX if there is a problem talking to the network, we either need to always tell
@ -271,7 +289,7 @@ class Gem::DependencyInstaller
dep = Gem::Dependency.new gem_name, version
dep.prerelease = true if prerelease
set = find_gems_with_sources(dep)
set = find_gems_with_sources(dep, true)
set.match_platform!
end
@ -402,7 +420,7 @@ class Gem::DependencyInstaller
request_set = as.to_request_set install_development_deps
request_set.soft_missing = @force
installer_set = Gem::DependencyResolver::InstallerSet.new @domain
installer_set = Gem::Resolver::InstallerSet.new @domain
installer_set.always_install.concat request_set.always_install
installer_set.ignore_installed = @only_install_dir
@ -411,7 +429,7 @@ class Gem::DependencyInstaller
request_set.soft_missing = true
end
composed_set = Gem::DependencyResolver.compose_sets as, installer_set
composed_set = Gem::Resolver.compose_sets as, installer_set
request_set.resolve composed_set

View File

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

View File

@ -73,12 +73,27 @@ module Gem
# data from a source
class SourceFetchProblem < ErrorReason
##
# Creates a new SourceFetchProblem for the given +source+ and +error+.
def initialize(source, error)
@source = source
@error = error
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
"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
##
# 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
# and #conflicting_dependencies
@ -117,7 +117,7 @@ class Gem::SpecificGemNotFoundException < Gem::GemNotFoundException
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.
class Gem::ImpossibleDependenciesError < Gem::Exception
@ -211,20 +211,20 @@ class Gem::SystemExitException < SystemExit
end
##
# Raised by DependencyResolver when a dependency requests a gem for which
# Raised by Resolver when a dependency requests a gem for which
# there is no spec.
class Gem::UnsatisfiableDependencyError < Gem::Exception
##
# The unsatisfiable dependency. This is a
# Gem::DependencyResolver::DependencyRequest, not a Gem::Dependency
# Gem::Resolver::DependencyRequest, not a Gem::Dependency
attr_reader :dependency
##
# Creates a new UnsatisfiableDepedencyError for the unsatisfiable
# Gem::DependencyResolver::DependencyRequest +dep+
# Gem::Resolver::DependencyRequest +dep+
def initialize dep, platform_mismatch=nil
if platform_mismatch and !platform_mismatch.empty?

View File

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

View File

@ -1,7 +1,7 @@
require 'rubygems/command'
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
cmd = "cmake . -DCMAKE_INSTALL_PREFIX=#{dest_path}"
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
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
cmd = "sh ./configure --prefix=#{dest_path}"
cmd << " #{args.join ' '}" unless args.empty?

View File

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

View File

@ -6,7 +6,7 @@
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
cmd = "#{Gem.ruby} #{File.basename extension}"
cmd << " #{args.join " "}" unless args.empty?

View File

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

View File

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

View File

@ -107,6 +107,11 @@ class Gem::RequestSet::GemDependencyAPI
: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.
@ -130,13 +135,55 @@ class Gem::RequestSet::GemDependencyAPI
@set = set
@path = path
@current_groups = nil
@current_platform = nil
@default_sources = true
@requires = Hash.new { |h, name| h[name] = [] }
@vendor_set = @set.vendor_set
@gem_sources = {}
@without_groups = []
@current_groups = nil
@current_platform = nil
@current_repository = nil
@default_sources = true
@git_set = @set.git_set
@requires = Hash.new { |h, name| h[name] = [] }
@vendor_set = @set.vendor_set
@gem_sources = {}
@without_groups = []
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
##
@ -160,7 +207,13 @@ class Gem::RequestSet::GemDependencyAPI
options = requirements.pop if requirements.last.kind_of?(Hash)
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
@ -181,6 +234,54 @@ class Gem::RequestSet::GemDependencyAPI
@set.gem name, *requirements
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
# +name+.
@ -269,6 +370,15 @@ class Gem::RequestSet::GemDependencyAPI
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
@ -276,6 +386,29 @@ class Gem::RequestSet::GemDependencyAPI
File.basename @path
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
# Block form for placing a dependency in the given +groups+.

View File

@ -1,5 +1,3 @@
require 'pathname'
class Gem::RequestSet::Lockfile
##
@ -46,8 +44,8 @@ class Gem::RequestSet::Lockfile
def initialize request_set, gem_deps_file
@set = request_set
@gem_deps_file = Pathname(gem_deps_file).expand_path
@gem_deps_dir = @gem_deps_file.dirname
@gem_deps_file = File.expand_path(gem_deps_file)
@gem_deps_dir = File.dirname(@gem_deps_file)
@current_token = nil
@line = 0
@ -62,7 +60,7 @@ class Gem::RequestSet::Lockfile
@set.dependencies.sort.map do |dependency|
source = @requests.find do |req|
req.name == dependency.name and
req.spec.class == Gem::DependencyResolver::VendorSpecification
req.spec.class == Gem::Resolver::VendorSpecification
end
source_dep = '!' if source
@ -102,15 +100,26 @@ class Gem::RequestSet::Lockfile
out << nil
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:
return unless path_requests =
@spec_groups.delete(Gem::DependencyResolver::VendorSpecification)
@spec_groups.delete(Gem::Resolver::VendorSpecification)
out << "PATH"
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 << " #{request.name} (#{request.version})"
end
@ -208,7 +217,7 @@ class Gem::RequestSet::Lockfile
skip :newline
set = Gem::DependencyResolver::LockSet.new source
set = Gem::Resolver::LockSet.new source
while not @tokens.empty? and :text == peek.first do
_, 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
# all the requirements.
class Gem::DependencyResolver
class Gem::Resolver
##
# Contains all the conflicts encountered while doing resolution
@ -38,20 +38,20 @@ class Gem::DependencyResolver
when 1 then
sets.first
else
Gem::DependencyResolver::ComposedSet.new(*sets)
Gem::Resolver::ComposedSet.new(*sets)
end
end
##
# Provide a DependencyResolver that queries only against the already
# Provide a Resolver that queries only against the already
# installed gems.
def self.for_current_gems needed
new needed, Gem::DependencyResolver::CurrentSet.new
new needed, Gem::Resolver::CurrentSet.new
end
##
# Create DependencyResolver object which will resolve the tree starting
# Create Resolver object which will resolve the tree starting
# with +needed+ Dependency objects.
#
# +set+ is an object that provides where to look for specifications to
@ -59,7 +59,7 @@ class Gem::DependencyResolver
# rubygems.org.
def initialize needed, set = nil
@set = set || Gem::DependencyResolver::IndexSet.new
@set = set || Gem::Resolver::IndexSet.new
@needed = needed
@conflicts = []
@ -68,6 +68,15 @@ class Gem::DependencyResolver
@soft_missing = false
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+
# specification.
@ -77,8 +86,10 @@ class Gem::DependencyResolver
def activation_request dep, possible # :nodoc:
spec = possible.pop
explain :activate, [spec.full_name, possible.size]
activation_request =
Gem::DependencyResolver::ActivationRequest.new spec, dep, possible
Gem::Resolver::ActivationRequest.new spec, dep, possible
return spec, activation_request
end
@ -86,7 +97,7 @@ class Gem::DependencyResolver
def requests s, act, reqs=nil
s.dependencies.reverse_each do |d|
next if d.type == :development and not @development
reqs = Gem::List.new Gem::DependencyResolver::DependencyRequest.new(d, act), reqs
reqs.add Gem::Resolver::DependencyRequest.new(d, act)
end
@set.prefetch reqs
@ -100,18 +111,18 @@ class Gem::DependencyResolver
def resolve
@conflicts = []
needed = nil
needed = RequirementList.new
@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
res = resolve_for needed, nil
raise Gem::DependencyResolutionError, res if
res.kind_of? Gem::DependencyResolver::DependencyConflict
res.kind_of? Gem::Resolver::Conflict
res.to_a
end
@ -128,6 +139,8 @@ class Gem::DependencyResolver
until states.empty? do
state = states.pop
explain :consider, state.dep, conflict.failed_dep
if conflict.for_spec? state.spec
state.conflicts << [state.spec, conflict]
return state
@ -162,11 +175,11 @@ class Gem::DependencyResolver
# Otherwise, issue it on the requester's request itself.
if existing.others_possible? or existing.request.requester.nil? then
conflict =
Gem::DependencyResolver::DependencyConflict.new dep, existing
Gem::Resolver::Conflict.new dep, existing
else
depreq = existing.request.requester.request
depreq = dep.requester.request
conflict =
Gem::DependencyResolver::DependencyConflict.new depreq, existing, dep
Gem::Resolver::Conflict.new depreq, existing, dep
end
@conflicts << conflict unless @conflicts.include? conflict
@ -182,7 +195,7 @@ class Gem::DependencyResolver
# +spec+ is the Specification for this state.
# +possible+ is List of DependencyRequest objects that can be tried to
# find a complete set.
# +conflicts+ is a [DependencyRequest, DependencyConflict] hit tried to
# +conflicts+ is a [DependencyRequest, Conflict] hit tried to
# activate the state.
#
State = Struct.new(:needed, :specs, :dep, :spec, :possibles, :conflicts) do
@ -218,9 +231,9 @@ class Gem::DependencyResolver
# The State objects that are used to attempt the activation tree.
states = []
while needed
dep = needed.value
needed = needed.tail
while !needed.empty?
dep = needed.remove
explain :try, [dep, dep.requester ? dep.requester.request : :toplevel]
# If there is already a spec activated for the requested name...
if specs && existing = specs.find { |s| dep.name == s.name }
@ -228,6 +241,7 @@ class Gem::DependencyResolver
next if dep.matches_spec? existing
conflict = handle_conflict dep, existing
explain :conflict, conflict.explain
state = find_conflict_state conflict, states
@ -292,7 +306,9 @@ class Gem::DependencyResolver
# We may need to try all of +possible+, so we setup state to unwind back
# to current +needed+ and +specs+ so we can try another. This is code is
# what makes conflict resolution possible.
states << State.new(needed, specs, dep, spec, possible, [])
states << State.new(needed.dup, specs, dep, spec, possible, [])
explain :states, states.map { |s| s.dep }
needed = requests spec, act, needed
specs = Gem::List.prepend specs, act
@ -341,24 +357,32 @@ class Gem::DependencyResolver
end
require 'rubygems/dependency_resolver/activation_request'
require 'rubygems/dependency_resolver/dependency_conflict'
require 'rubygems/dependency_resolver/dependency_request'
##
# TODO remove in RubyGems 3
require 'rubygems/dependency_resolver/set'
require 'rubygems/dependency_resolver/api_set'
require 'rubygems/dependency_resolver/composed_set'
require 'rubygems/dependency_resolver/best_set'
require 'rubygems/dependency_resolver/current_set'
require 'rubygems/dependency_resolver/index_set'
require 'rubygems/dependency_resolver/installer_set'
require 'rubygems/dependency_resolver/lock_set'
require 'rubygems/dependency_resolver/vendor_set'
Gem::DependencyResolver = Gem::Resolver # :nodoc:
require 'rubygems/dependency_resolver/specification'
require 'rubygems/dependency_resolver/spec_specification'
require 'rubygems/dependency_resolver/api_specification'
require 'rubygems/dependency_resolver/index_specification'
require 'rubygems/dependency_resolver/installed_specification'
require 'rubygems/dependency_resolver/vendor_specification'
require 'rubygems/resolver/activation_request'
require 'rubygems/resolver/conflict'
require 'rubygems/resolver/dependency_request'
require 'rubygems/resolver/requirement_list'
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
# activation.
class Gem::DependencyResolver::ActivationRequest
class Gem::Resolver::ActivationRequest
attr_reader :request
@ -19,7 +19,7 @@ class Gem::DependencyResolver::ActivationRequest
case other
when Gem::Specification
@spec == other
when Gem::DependencyResolver::ActivationRequest
when Gem::Resolver::ActivationRequest
@spec == other.spec && @request == other.request
else
false
@ -70,7 +70,7 @@ class Gem::DependencyResolver::ActivationRequest
def installed?
case @spec
when Gem::DependencyResolver::VendorSpecification then
when Gem::Resolver::VendorSpecification then
true
else
this_spec = full_spec

View File

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

View File

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

View File

@ -3,7 +3,7 @@
#
# 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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
# Used Internally. Wraps a Dependency object to also track which spec
# contained the Dependency.
class Gem::DependencyResolver::DependencyRequest
class Gem::Resolver::DependencyRequest
attr_reader :dependency
@ -17,7 +17,7 @@ class Gem::DependencyResolver::DependencyRequest
case other
when Gem::Dependency
@dependency == other
when Gem::DependencyResolver::DependencyRequest
when Gem::Resolver::DependencyRequest
@dependency == other.dependency && @requester == other.requester
else
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
# source index.
class Gem::DependencyResolver::IndexSet < Gem::DependencyResolver::Set
class Gem::Resolver::IndexSet < Gem::Resolver::Set
def initialize source = nil # :nodoc:
@f =
@ -38,7 +38,7 @@ class Gem::DependencyResolver::IndexSet < Gem::DependencyResolver::Set
@all[name].each do |uri, n|
if req.dependency.match? n then
res << Gem::DependencyResolver::IndexSpecification.new(
res << Gem::Resolver::IndexSpecification.new(
self, n.name, n.version, uri, n.platform)
end
end

View File

@ -3,7 +3,7 @@
# delay needed to download full Specification objects when only the +name+
# and +version+ are needed.
class Gem::DependencyResolver::IndexSpecification < Gem::DependencyResolver::Specification
class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
##
# 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
# locally.
class Gem::DependencyResolver::InstalledSpecification < Gem::DependencyResolver::SpecSpecification
class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification
def == other # :nodoc:
self.class === other and

View File

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

View File

@ -1,7 +1,7 @@
##
# 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:
@ -24,8 +24,8 @@ class Gem::DependencyResolver::LockSet < Gem::DependencyResolver::Set
version = Gem::Version.new version
spec =
Gem::DependencyResolver::IndexSpecification.new self, name, version,
@source, platform
Gem::Resolver::IndexSpecification.new self, name, version, @source,
platform
@specs << spec
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.
class Gem::DependencyResolver::Set
class Gem::Resolver::Set
##
# The find_all method must be implemented. It returns all
# DependencyResolver Specification objects matching the given
# DependencyRequest +req+.
# The find_all method must be implemented. It returns all Resolver
# Specification objects matching the given DependencyRequest +req+.
def find_all req
raise NotImplementedError

View File

@ -1,8 +1,8 @@
##
# The DependencyResolver::SpecSpecification contains common functionality for
# DependencyResolver specifications that are backed by a Gem::Specification.
# The Resolver::SpecSpecification contains common functionality for
# 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:

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
# dependency resolution in the resolver is included.
class Gem::DependencyResolver::Specification
class Gem::Resolver::Specification
##
# The dependencies of the gem for this specification

View File

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

View File

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

View File

@ -28,7 +28,9 @@ class Gem::Source
case other
when Gem::Source::Installed,
Gem::Source::Local,
Gem::Source::SpecificFile then
Gem::Source::SpecificFile,
Gem::Source::Git,
Gem::Source::Vendor then
-1
when Gem::Source then
if !@uri
@ -62,9 +64,9 @@ class Gem::Source
fetcher = Gem::RemoteFetcher.fetcher
fetcher.fetch_path bundler_api_uri, nil, true
rescue Gem::RemoteFetcher::FetchError
Gem::DependencyResolver::IndexSet.new self
Gem::Resolver::IndexSet.new self
else
Gem::DependencyResolver::APISet.new bundler_api_uri
Gem::Resolver::APISet.new bundler_api_uri
end
end
@ -90,12 +92,15 @@ class Gem::Source
end
end
def fetch_spec(name)
##
# Fetches a specification for the given +name_tuple+.
def fetch_spec name_tuple
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
@ -139,7 +144,7 @@ class Gem::Source
file = FILES[type]
fetcher = Gem::RemoteFetcher.fetcher
file_name = "#{file}.#{Gem.marshal_version}"
spec_path = @uri + "#{file_name}.gz"
spec_path = api_uri + "#{file_name}.gz"
cache_dir = cache_dir spec_path
local_file = File.join(cache_dir, file_name)
retried = false
@ -163,18 +168,22 @@ class Gem::Source
def download(spec, dir=Dir.pwd)
fetcher = Gem::RemoteFetcher.fetcher
fetcher.download spec, @uri.to_s, dir
fetcher.download spec, api_uri.to_s, dir
end
def pretty_print q # :nodoc:
q.group 2, '[Remote:', ']' do
q.breakable
q.text @uri.to_s
if api = api_uri
g.text api
end
end
end
end
require 'rubygems/source/git'
require 'rubygems/source/installed'
require 'rubygems/source/specific_file'
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
def initialize
def initialize # :nodoc:
@uri = nil
end
@ -9,6 +12,8 @@ class Gem::Source::Installed < Gem::Source
def <=> other
case other
when Gem::Source::Vendor then
-1
when Gem::Source::Installed then
0
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
def initialize
def initialize # :nodoc:
@specs = nil
@api_uri = nil
@uri = nil
@ -26,7 +31,7 @@ class Gem::Source::Local < Gem::Source
"#<%s specs: %p>" % [self.class, keys]
end
def load_specs(type)
def load_specs type # :nodoc:
names = []
@specs = {}
@ -68,8 +73,8 @@ class Gem::Source::Local < Gem::Source
names
end
def find_gem(gem_name, version=Gem::Requirement.default,
prerelease=false)
def find_gem gem_name, version = Gem::Requirement.default, # :nodoc:
prerelease = false
load_specs :complete
found = []
@ -91,7 +96,7 @@ class Gem::Source::Local < Gem::Source
found.max_by { |s| s.version }
end
def fetch_spec(name)
def fetch_spec name # :nodoc:
load_specs :complete
if data = @specs[name]
@ -101,7 +106,7 @@ class Gem::Source::Local < Gem::Source
end
end
def download(spec, cache_dir=nil)
def download spec, cache_dir = nil # :nodoc:
load_specs :complete
@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
##
# Creates a new SpecificFile for the gem in +file+
def initialize(file)
@uri = nil
@path = ::File.expand_path(file)
@ -8,19 +16,22 @@ class Gem::Source::SpecificFile < Gem::Source
@name = @spec.name_tuple
end
##
# The Gem::Specification extracted from this .gem.
attr_reader :spec
def load_specs(*a)
def load_specs *a # :nodoc:
[@name]
end
def fetch_spec(name)
def fetch_spec name # :nodoc:
return @spec if name == @name
raise Gem::Exception, "Unable to find '#{name}'"
@spec
end
def download(spec, dir=nil)
def download spec, dir = nil # :nodoc:
return @path if spec == @spec
raise Gem::Exception, "Unable to download '#{spec.full_name}'"
end

View File

@ -3,8 +3,22 @@
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

View File

@ -1,5 +1,18 @@
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
include Enumerable
@ -91,7 +104,7 @@ class Gem::SourceList
@sources.empty?
end
def ==(other)
def == other # :nodoc:
to_a == other
end

View File

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

View File

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

View File

@ -233,6 +233,8 @@ class Gem::TestCase < MiniTest::Unit::TestCase
ruby
end
@git = ENV['GIT'] || 'git'
Gem.ensure_gem_subdirectories @gemhome
@orig_LOAD_PATH = $LOAD_PATH.dup
@ -372,6 +374,64 @@ class Gem::TestCase < MiniTest::Unit::TestCase
Gem.pre_uninstall_hooks.clear
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+
@ -1082,21 +1142,21 @@ Also, a list:
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
# dependency and a +parent+ DependencyRequest
def dependency_request dep, from_name, from_version, parent = nil
remote = Gem::Source.new @uri
parent ||= Gem::DependencyResolver::DependencyRequest.new \
parent ||= Gem::Resolver::DependencyRequest.new \
dep, nil
spec = Gem::DependencyResolver::IndexSpecification.new \
spec = Gem::Resolver::IndexSpecification.new \
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
##

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'] = "-"
assert_equal [a,b,c], Gem.detect_gemdeps
assert_equal [a,b,c], Gem.detect_gemdeps.sort_by { |s| s.name }
end
LIB_PATH = File.expand_path "../../../lib".untaint, __FILE__.untaint

View File

@ -44,7 +44,9 @@ class TestGemCommandsWhichCommand < Gem::TestCase
@cmd.handle_options %w[foo_bar missinglib]
use_ui @ui do
@cmd.execute
assert_raises Gem::MockGemUi::TermError do
@cmd.execute
end
end
assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output

View File

@ -5,7 +5,7 @@ class TestGemDependencyResolutionError < Gem::TestCase
def setup
super
@DR = Gem::DependencyResolver
@DR = Gem::Resolver
@spec = util_spec 'a', 2
@ -14,7 +14,7 @@ class TestGemDependencyResolutionError < Gem::TestCase
@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
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
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|
f.write <<-'RUBY'
open 'Makefile', 'w' do |f|
f.puts "clean:\n\techo cleaned"
f.puts "default:\n\techo built"
f.puts "install:\n\techo installed"
end
require 'mkmf'
create_makefile 'a'
RUBY
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
@builder.build_extensions
end
@ -121,6 +125,8 @@ install:
assert_path_exists @spec.extension_install_dir
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, 'a.rb'
assert_path_exists File.join @spec.gem_dir, 'lib', 'a.rb'
end
def test_build_extensions_none

View File

@ -15,10 +15,10 @@ class TestGemImpossibleDependenciesError < Gem::TestCase
net_ssh_2_6_5 =
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
conflict2 = Gem::DependencyResolver::DependencyConflict.new \
conflict2 = Gem::Resolver::Conflict.new \
net_ssh_2_2_2, net_ssh_2_2_2.requester
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
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.extensions << "extconf.rb"
@ -1038,8 +1042,14 @@ gem 'other', version
puts '-' * 78
puts File.read File.join(@gemhome, 'gems', 'a-2', 'Makefile')
puts '-' * 78
puts File.read File.join(@gemhome, 'gems', 'a-2', 'gem_make.out')
puts '-' * 78
path = File.join(@gemhome, 'gems', 'a-2', 'gem_make.out')
if File.exists?(path)
puts File.read(path)
puts '-' * 78
end
raise
end

View File

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

View File

@ -7,7 +7,7 @@ class TestGemRequestSet < Gem::TestCase
Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
@DR = Gem::DependencyResolver
@DR = Gem::Resolver
end
def test_gem
@ -69,6 +69,7 @@ class TestGemRequestSet < Gem::TestCase
assert_equal [dep('a')], rs.dependencies
assert rs.git_set
assert rs.vendor_set
end
@ -100,6 +101,32 @@ class TestGemRequestSet < Gem::TestCase
assert_equal ["a-2", "b-2"], names
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
a1 = util_spec 'a', 1
a2 = util_spec 'a', 2
@ -142,7 +169,7 @@ class TestGemRequestSet < Gem::TestCase
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 }
end

View File

@ -10,9 +10,11 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
@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.instance_variable_set :@git_set, @git_set
@gda.instance_variable_set :@vendor_set, @vendor_set
end
@ -48,6 +50,18 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
Gem.instance_variables.include? :@ruby_version
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
@gda.gem 'a'
@ -56,6 +70,65 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase
assert_equal %w[a], @gda.requires['a']
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
@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 }
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
@gda.group :test do
@gda.gem 'a'

View File

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

View File

@ -1,12 +1,11 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolver < Gem::TestCase
class TestGemResolver < Gem::TestCase
def setup
super
@DR = Gem::DependencyResolver
@DR = Gem::Resolver
end
def make_dep(name, *req)
@ -30,13 +29,17 @@ class TestGemDependencyResolver < Gem::TestCase
flunk e.message
end
def test_self_compatibility
assert_same Gem::Resolver, Gem::DependencyResolver
end
def test_self_compose_sets_multiple
index_set = @DR::IndexSet.new
vendor_set = @DR::VendorSet.new
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
end
@ -66,13 +69,13 @@ class TestGemDependencyResolver < Gem::TestCase
def test_handle_conflict
a1 = util_spec 'a', 1
r1 = Gem::DependencyResolver::DependencyRequest.new dep('a', '= 1'), nil
r2 = Gem::DependencyResolver::DependencyRequest.new dep('a', '= 2'), nil
r3 = Gem::DependencyResolver::DependencyRequest.new dep('a', '= 3'), nil
r1 = Gem::Resolver::DependencyRequest.new dep('a', '= 1'), nil
r2 = Gem::Resolver::DependencyRequest.new dep('a', '= 2'), 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
@ -92,7 +95,7 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(a, b)
res = Gem::DependencyResolver.new(deps, s)
res = Gem::Resolver.new(deps, s)
assert_resolves_to [a, b], res
end
@ -109,7 +112,7 @@ class TestGemDependencyResolver < Gem::TestCase
s = set(a, b, c)
res = Gem::DependencyResolver.new(deps, s)
res = Gem::Resolver.new(deps, s)
assert_resolves_to [a, b, c], res
end
@ -122,13 +125,13 @@ class TestGemDependencyResolver < Gem::TestCase
ad = make_dep "a"
res = Gem::DependencyResolver.new([ad], s)
res = Gem::Resolver.new([ad], s)
assert_resolves_to [a2], res
end
def test_picks_best_platform
is = Gem::DependencyResolver::IndexSpecification
is = Gem::Resolver::IndexSpecification
unknown = Gem::Platform.new 'unknown'
a2_p1 = a3_p2 = nil
@ -153,7 +156,7 @@ class TestGemDependencyResolver < Gem::TestCase
ad = make_dep "a"
res = Gem::DependencyResolver.new([ad], s)
res = Gem::Resolver.new([ad], s)
assert_resolves_to [a2_p1], res
end
@ -169,7 +172,7 @@ class TestGemDependencyResolver < Gem::TestCase
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
end
@ -186,17 +189,9 @@ class TestGemDependencyResolver < Gem::TestCase
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
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
def test_conflict_resolution_only_effects_correct_spec
@ -214,7 +209,7 @@ class TestGemDependencyResolver < Gem::TestCase
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
@ -239,31 +234,31 @@ class TestGemDependencyResolver < Gem::TestCase
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
r.resolve
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
con = e.conflict
act = con.activated
assert_equal "c-1", act.spec.full_name
assert_equal "c-2", act.spec.full_name
parent = act.parent
assert_equal "a-1", parent.spec.full_name
assert_equal "b-1", parent.spec.full_name
act = con.requester
assert_equal "b-1", act.spec.full_name
assert_equal "a-1", act.spec.full_name
end
def test_raises_when_a_gem_is_missing
ad = make_dep "a"
r = Gem::DependencyResolver.new([ad], set)
r = Gem::Resolver.new([ad], set)
e = assert_raises Gem::UnsatisfiableDepedencyError do
r.resolve
@ -280,7 +275,7 @@ class TestGemDependencyResolver < Gem::TestCase
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
r.resolve
@ -293,7 +288,7 @@ class TestGemDependencyResolver < Gem::TestCase
a1 = util_spec "a", "1"
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
r.resolve
@ -310,7 +305,7 @@ class TestGemDependencyResolver < Gem::TestCase
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
r.resolve
@ -333,7 +328,7 @@ class TestGemDependencyResolver < Gem::TestCase
ad = make_dep "a"
bd = make_dep "b"
r = Gem::DependencyResolver.new([ad, bd], s)
r = Gem::Resolver.new([ad, bd], s)
e = assert_raises Gem::DependencyResolutionError do
r.resolve
@ -345,11 +340,11 @@ class TestGemDependencyResolver < Gem::TestCase
assert_equal req('>= 0'), dependency.requirement
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
end
@ -363,7 +358,7 @@ class TestGemDependencyResolver < Gem::TestCase
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
end
@ -382,13 +377,13 @@ class TestGemDependencyResolver < Gem::TestCase
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
# 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
end
@ -405,7 +400,7 @@ class TestGemDependencyResolver < Gem::TestCase
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
r.resolve
@ -423,7 +418,7 @@ class TestGemDependencyResolver < Gem::TestCase
a_dep = dep 'a', '~> 1.0'
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
r.resolve
@ -444,7 +439,7 @@ class TestGemDependencyResolver < Gem::TestCase
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
end
@ -461,7 +456,7 @@ class TestGemDependencyResolver < Gem::TestCase
a_dep = dep 'a', '~> 1.0'
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
end
@ -484,7 +479,7 @@ class TestGemDependencyResolver < Gem::TestCase
d1 = make_dep "activemerchant"
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
end
@ -502,13 +497,13 @@ class TestGemDependencyResolver < Gem::TestCase
p1 = make_dep "b", "> 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
end
def test_select_local_platforms
r = Gem::DependencyResolver.new nil, nil
r = Gem::Resolver.new nil, nil
a1 = util_spec 'a', 1
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"
r = Gem::DependencyResolver.new([ad], set(a1))
r = Gem::Resolver.new([ad], set(a1))
e = assert_raises Gem::UnsatisfiableDepedencyError do
r.resolve

View File

@ -1,11 +1,11 @@
require 'rubygems/test_case'
class TestGemDependencyResolverActivationRequest < Gem::TestCase
class TestGemResolverActivationRequest < Gem::TestCase
def setup
super
@DR = Gem::DependencyResolver
@DR = Gem::Resolver
@dep = @DR::DependencyRequest.new dep('a', '>= 0'), nil
@ -36,7 +36,7 @@ class TestGemDependencyResolverActivationRequest < Gem::TestCase
end
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]

View File

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

View File

@ -1,10 +1,9 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverAPISpecification < Gem::TestCase
class TestGemResolverAPISpecification < Gem::TestCase
def test_initialize
set = Gem::DependencyResolver::APISet.new
set = Gem::Resolver::APISet.new
data = {
:name => 'rails',
: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 Gem::Version.new('3.0.3'), spec.version

View File

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

View File

@ -1,7 +1,10 @@
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
root =
@ -10,7 +13,7 @@ class TestGemDependencyResolverDependencyConflict < Gem::TestCase
dependency_request dep('net-ssh', '>= 2.6.5'), 'net-ssh', '2.2.2', root
conflict =
Gem::DependencyResolver::DependencyConflict.new child, child.requester
Gem::Resolver::Conflict.new child, child.requester
expected = <<-EXPECTED
Activated net-ssh-2.2.2 instead of (>= 2.6.5) via:
@ -21,7 +24,7 @@ class TestGemDependencyResolverDependencyConflict < Gem::TestCase
end
def test_explanation_user_request
@DR = Gem::DependencyResolver
@DR = Gem::Resolver
spec = util_spec 'a', 2
@ -30,7 +33,7 @@ class TestGemDependencyResolverDependencyConflict < Gem::TestCase
activated = @DR::ActivationRequest.new spec, a2_req
conflict = @DR::DependencyConflict.new a1_req, activated
conflict = @DR::Conflict.new a1_req, activated
expected = <<-EXPECTED
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
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
end

View File

@ -1,11 +1,11 @@
require 'rubygems/test_case'
class TestGemDependencyResolverDependencyRequest < Gem::TestCase
class TestGemResolverDependencyRequest < Gem::TestCase
def setup
super
@DR = Gem::DependencyResolver::DependencyRequest
@DR = Gem::Resolver::DependencyRequest
end
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/dependency_resolver'
class TestGemDependencyResolverIndexSet < Gem::TestCase
class TestGemResolverIndexSet < Gem::TestCase
def setup
super
@DR = Gem::DependencyResolver
@DR = Gem::Resolver
end
def test_initialize

View File

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

View File

@ -1,14 +1,13 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverInstalledSpecification < Gem::TestCase
class TestGemResolverInstalledSpecification < Gem::TestCase
def test_initialize
set = Gem::DependencyResolver::CurrentSet.new
set = Gem::Resolver::CurrentSet.new
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 Gem::Version.new(2), spec.version

View File

@ -1,7 +1,6 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverInstallerSet < Gem::TestCase
class TestGemResolverInstallerSet < Gem::TestCase
def test_load_spec
specs = spec_fetcher do |fetcher|
@ -12,7 +11,7 @@ class TestGemDependencyResolverInstallerSet < Gem::TestCase
source = Gem::Source.new @gem_repo
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

View File

@ -1,14 +1,13 @@
require 'rubygems/test_case'
require 'rubygems/dependency_resolver'
class TestGemDependencyResolverLockSet < Gem::TestCase
class TestGemResolverLockSet < Gem::TestCase
def setup
super
@source = Gem::Source.new @gem_repo
@set = Gem::DependencyResolver::LockSet.new @source
@set = Gem::Resolver::LockSet.new @source
end
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/dependency_resolver'
class TestGemDependencyResolverVendorSet < Gem::TestCase
class TestGemResolverVendorSet < Gem::TestCase
def setup
super
@set = Gem::DependencyResolver::VendorSet.new
@set = Gem::Resolver::VendorSet.new
end
def test_add_vendor_gem
@ -39,7 +38,7 @@ class TestGemDependencyResolverVendorSet < Gem::TestCase
dependency = dep 'a', '~> 1'
req = Gem::DependencyResolver::DependencyRequest.new dependency, nil
req = Gem::Resolver::DependencyRequest.new dependency, nil
found = @set.find_all req
@ -48,7 +47,7 @@ class TestGemDependencyResolverVendorSet < Gem::TestCase
source = Gem::Source::Vendor.new directory
expected = [
Gem::DependencyResolver::VendorSpecification.new(@set, spec, source)
Gem::Resolver::VendorSpecification.new(@set, spec, source)
]
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
assert_kind_of Gem::DependencyResolver::APISet, set
assert_kind_of Gem::Resolver::APISet, set
end
def test_dependency_resolver_set_marshal_api
set = @source.dependency_resolver_set
assert_kind_of Gem::DependencyResolver::IndexSet, set
assert_kind_of Gem::Resolver::IndexSet, set
end
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
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

View File

@ -1733,7 +1733,7 @@ dependencies: []
full_gem_path = Pathname(@ext.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
RbConfig::CONFIG['ENABLE_SHARED'] = enable_shared
end
@ -1744,8 +1744,8 @@ dependencies: []
@ext.require_path = 'lib'
expected = [
File.join(@gemhome, 'gems', @ext.original_name, 'lib'),
@ext.extension_install_dir,
File.join(@gemhome, 'gems', @ext.original_name, 'lib'),
]
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 v(2), stub.version
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
end
@ -78,8 +78,8 @@ class TestStubSpecification < Gem::TestCase
stub = stub_with_extension
expected = [
File.join(stub.full_gem_path, 'lib'),
stub.extension_install_dir,
File.join(stub.full_gem_path, 'lib'),
]
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