Skip to content

Commit

Permalink
Showing 25 changed files with 194 additions and 65 deletions.
10 changes: 8 additions & 2 deletions lib/ruby/stdlib/rubygems.rb
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
require 'thread'

module Gem
VERSION = '2.4.4'
VERSION = '2.4.5'
end

# Must be first since it unloads the prelude from 1.9.2
@@ -232,7 +232,13 @@ def self.bin_path(name, exec_name = nil, *requirements)
requirements = Gem::Requirement.default if
requirements.empty?

specs = Gem::Dependency.new(name, requirements).matching_specs(true)
dep = Gem::Dependency.new name, requirements

loaded = Gem.loaded_specs[name]

return loaded.bin_file exec_name if loaded && dep.matches_spec?(loaded)

specs = dep.matching_specs(true)

raise Gem::GemNotFoundException,
"can't find gem #{name} (#{requirements})" if specs.empty?
74 changes: 52 additions & 22 deletions lib/ruby/stdlib/rubygems/basic_specification.rb
Original file line number Diff line number Diff line change
@@ -58,23 +58,28 @@ def base_dir
# Return true if this spec can require +file+.

def contains_requirable_file? file
if instance_variable_defined?(:@ignored) or
instance_variable_defined?('@ignored') then
return false
elsif missing_extensions? then
@ignored = true

warn "Ignoring #{full_name} because its extensions are not built. " +
"Try: gem pristine #{full_name}"
return false
end

suffixes = Gem.suffixes

full_require_paths.any? do |dir|
base = "#{dir}/#{file}"
suffixes.any? { |suf| File.file? "#{base}#{suf}" }
end
@contains_requirable_file ||= {}
@contains_requirable_file[file] ||=
begin
if instance_variable_defined?(:@ignored) or
instance_variable_defined?('@ignored') then
return false
elsif missing_extensions? then
@ignored = true

warn "Ignoring #{full_name} because its extensions are not built. " +
"Try: gem pristine #{name} --version #{version}"
return false
end

suffixes = Gem.suffixes

full_require_paths.any? do |dir|
base = "#{dir}/#{file}"
suffixes.any? { |suf| File.file? "#{base}#{suf}" }
end
end ? :yes : :no
@contains_requirable_file[file] == :yes
end

def default_gem?
@@ -134,13 +139,38 @@ def full_name
# activated.

def full_require_paths
full_paths = raw_require_paths.map do |path|
File.join full_gem_path, path
end
@full_require_paths ||=
begin
full_paths = raw_require_paths.map do |path|
File.join full_gem_path, path
end

full_paths.unshift extension_dir unless @extensions.nil? || @extensions.empty?
full_paths.unshift extension_dir unless @extensions.nil? || @extensions.empty?

full_paths
full_paths
end
end

##
# Full path of the target library file.
# If the file is not in this gem, return nil.

def to_fullpath path
if activated? then
@paths_map ||= {}
@paths_map[path] ||=
begin
fullpath = nil
suffixes = Gem.suffixes
full_require_paths.find do |dir|
suffixes.find do |suf|
File.file?(fullpath = "#{dir}/#{path}#{suf}")
end
end ? fullpath : nil
end
else
nil
end
end

##
1 change: 0 additions & 1 deletion lib/ruby/stdlib/rubygems/commands/contents_command.rb
Original file line number Diff line number Diff line change
@@ -146,7 +146,6 @@ def gem_names # :nodoc:

def path_description spec_dirs # :nodoc:
if spec_dirs.empty? then
spec_dirs = Gem::Specification.dirs
"default gem paths"
else
"specified path"
16 changes: 15 additions & 1 deletion lib/ruby/stdlib/rubygems/commands/pristine_command.rb
Original file line number Diff line number Diff line change
@@ -109,6 +109,11 @@ def execute
next
end

if spec.bundled_gem_in_old_ruby?
say "Skipped #{spec.full_name}, it is bundled with old Ruby"
next
end

unless spec.extensions.empty? or options[:extensions] then
say "Skipped #{spec.full_name}, it needs to compile an extension"
next
@@ -120,8 +125,17 @@ def execute
require 'rubygems/remote_fetcher'

say "Cached gem for #{spec.full_name} not found, attempting to fetch..."

dep = Gem::Dependency.new spec.name, spec.version
Gem::RemoteFetcher.fetcher.download_to_cache dep
found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dep

if found.empty?
say "Skipped #{spec.full_name}, it was not found from cache and remote sources"
next
end

spec_candidate, source = found.first
Gem::RemoteFetcher.fetcher.download spec_candidate, source.uri.to_s, spec.base_dir
end

env_shebang =
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/commands/uninstall_command.rb
Original file line number Diff line number Diff line change
@@ -124,7 +124,7 @@ def execute
end

def uninstall_all
_, specs = Gem::Specification.partition { |spec| spec.default_gem? }
specs = Gem::Specification.reject { |spec| spec.default_gem? }

specs.each do |spec|
options[:version] = spec.version
2 changes: 0 additions & 2 deletions lib/ruby/stdlib/rubygems/commands/update_command.rb
Original file line number Diff line number Diff line change
@@ -84,8 +84,6 @@ def check_update_arguments # :nodoc:
end

def execute
hig = {}

if options[:system] then
update_rubygems
return
9 changes: 8 additions & 1 deletion lib/ruby/stdlib/rubygems/core_ext/kernel_gem.rb
Original file line number Diff line number Diff line change
@@ -55,7 +55,14 @@ def gem(gem_name, *requirements) # :doc:
gem_name = gem_name.name
end

spec = Gem::Dependency.new(gem_name, *requirements).to_spec
dep = Gem::Dependency.new(gem_name, *requirements)

loaded = Gem.loaded_specs[gem_name]

return false if loaded && dep.matches_spec?(loaded)

spec = dep.to_spec

Gem::LOADED_SPECS_MUTEX.synchronize {
spec.activate
} if spec
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/core_ext/kernel_require.rb
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ def require path

begin
RUBYGEMS_ACTIVATION_MONITOR.exit
return gem_original_require(path)
return gem_original_require(spec.to_fullpath(path) || path)
end if spec

# Attempt to find +path+ in any unresolved gems...
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/dependency.rb
Original file line number Diff line number Diff line change
@@ -281,7 +281,7 @@ def matching_specs platform_only = false
}
end

matches = matches.sort_by { |s| s.sort_obj } # HACK: shouldn't be needed
matches.sort_by { |s| s.sort_obj } # HACK: shouldn't be needed
end

##
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/ext/ext_conf_builder.rb
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
FileUtils.mkdir_p lib_dir
entries = Dir.entries(tmp_dest) - %w[. ..]
entries = entries.map { |entry| File.join tmp_dest, entry }
FileUtils.cp_r entries, lib_dir
FileUtils.cp_r entries, lib_dir, :remove_destination => true
end

FileEntry.new(tmp_dest).traverse do |ent|
4 changes: 2 additions & 2 deletions lib/ruby/stdlib/rubygems/installer.rb
Original file line number Diff line number Diff line change
@@ -421,8 +421,8 @@ def generate_bin # :nodoc:
next
end

mode = File.stat(bin_path).mode | 0111
FileUtils.chmod mode, bin_path
mode = File.stat(bin_path).mode
FileUtils.chmod mode | 0111, bin_path unless (mode | 0111) == mode

check_executable_overwrite filename

4 changes: 2 additions & 2 deletions lib/ruby/stdlib/rubygems/package/old.rb
Original file line number Diff line number Diff line change
@@ -153,10 +153,10 @@ def spec

begin
@spec = Gem::Specification.from_yaml yaml
rescue yaml_error => e
rescue yaml_error
raise Gem::Exception, "Failed to parse gem specification out of gem file"
end
rescue ArgumentError => e
rescue ArgumentError
raise Gem::Exception, "Failed to parse gem specification out of gem file"
end

6 changes: 5 additions & 1 deletion lib/ruby/stdlib/rubygems/remote_fetcher.rb
Original file line number Diff line number Diff line change
@@ -326,7 +326,7 @@ def fetch_size(uri) # TODO: phase this out

def correct_for_windows_path(path)
if path[0].chr == '/' && path[1].chr =~ /[a-z]/i && path[2].chr == ':'
path = path[1..-1]
path[1..-1]
else
path
end
@@ -352,6 +352,10 @@ def https?(uri)
uri.scheme.downcase == 'https'
end

def close_all
@pools.each_value {|pool| pool.close_all}
end

protected

# we have our own signing code here to avoid a dependency on the aws-sdk gem
6 changes: 5 additions & 1 deletion lib/ruby/stdlib/rubygems/request/connection_pools.rb
Original file line number Diff line number Diff line change
@@ -28,6 +28,10 @@ def pool_for uri
end
end

def close_all
@pools.each_value {|pool| pool.close_all}
end

private

##
@@ -69,7 +73,7 @@ def net_http_args uri, proxy_uri
Gem::UriFormatter.new(proxy_uri.password).unescape,
]
elsif no_proxy? uri.host, no_proxy then
net_http_args += [nil, nil]
net_http_args + [nil, nil]
else
net_http_args
end
9 changes: 9 additions & 0 deletions lib/ruby/stdlib/rubygems/request/http_pool.rb
Original file line number Diff line number Diff line change
@@ -23,6 +23,15 @@ def checkin connection
@queue.push connection
end

def close_all
until @queue.empty?
if connection = @queue.pop(true) and connection.started?
connection.finish
end
end
@queue.push(nil)
end

private

def make_connection
5 changes: 1 addition & 4 deletions lib/ruby/stdlib/rubygems/request_set.rb
Original file line number Diff line number Diff line change
@@ -403,10 +403,7 @@ def tsort_each_child node # :nodoc:
"Unresolved dependency found during sorting - #{dep} (requested by #{node.spec.full_name})"
end

begin
yield match
rescue TSort::Cyclic
end
yield match
end
end

29 changes: 21 additions & 8 deletions lib/ruby/stdlib/rubygems/request_set/lockfile.rb
Original file line number Diff line number Diff line change
@@ -200,6 +200,8 @@ def add_PLATFORMS out # :nodoc:

platforms = @requests.map { |request| request.spec.platform }.uniq

platforms = platforms.sort_by { |platform| platform.to_s }

platforms.sort.each do |platform|
out << " #{platform}"
end
@@ -277,14 +279,7 @@ def parse_DEPENDENCIES # :nodoc:
when :bang then
get :bang

spec = @set.sets.select { |set|
Gem::Resolver::GitSet === set or
Gem::Resolver::VendorSet === set
}.map { |set|
set.specs[name]
}.compact.first

requirements << spec.version
requirements << pinned_requirement(name)
when :l_paren then
get :l_paren

@@ -300,6 +295,13 @@ def parse_DEPENDENCIES # :nodoc:
end

get :r_paren

if peek[0] == :bang then
requirements.clear
requirements << pinned_requirement(name)

get :bang
end
end

@set.gem name, *requirements
@@ -507,6 +509,17 @@ def peek # :nodoc:
@tokens.first || [:EOF]
end

def pinned_requirement name # :nodoc:
spec = @set.sets.select { |set|
Gem::Resolver::GitSet === set or
Gem::Resolver::VendorSet === set
}.map { |set|
set.specs[name]
}.compact.first

spec.version
end

def skip type # :nodoc:
get while not @tokens.empty? and peek.first == type
end
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/resolver/api_set.rb
Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ def prefetch reqs
@to_fetch += needed
end

def prefetch_now
def prefetch_now # :nodoc:
needed, @to_fetch = @to_fetch, []

uri = @dep_uri + "?gems=#{needed.sort.join ','}"
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/resolver/installer_set.rb
Original file line number Diff line number Diff line change
@@ -154,7 +154,7 @@ def find_all req
end

def prefetch(reqs)
@remote_set.prefetch(reqs)
@remote_set.prefetch(reqs) if consider_remote?
end

def prerelease= allow_prerelease
8 changes: 6 additions & 2 deletions lib/ruby/stdlib/rubygems/source.rb
Original file line number Diff line number Diff line change
@@ -26,8 +26,12 @@ class Gem::Source
# Creates a new Source which will use the index located at +uri+.

def initialize(uri)
unless uri.kind_of? URI
uri = URI.parse(uri.to_s)
begin
unless uri.kind_of? URI
uri = URI.parse(uri.to_s)
end
rescue URI::InvalidURIError
raise if Gem::Source == self.class
end

@uri = uri
12 changes: 10 additions & 2 deletions lib/ruby/stdlib/rubygems/specification.rb
Original file line number Diff line number Diff line change
@@ -709,8 +709,6 @@ def self._all # :nodoc:
specs = {}
Gem.loaded_specs.each_value{|s| specs[s] = true}
@@all.each{|s| s.activated = true if specs[s]}

_resort!(@@all)
end
@@all
end
@@ -1478,6 +1476,16 @@ def build_info_file
File.join build_info_dir, "#{full_name}.info"
end

##
# Used to detect if the gem is bundled in older version of Ruby, but not
# detectable as default gem (see BasicSpecification#default_gem?).

def bundled_gem_in_old_ruby?
!default_gem? &&
RUBY_VERSION < "2.0.0" &&
summary == "This #{name} is bundled with Ruby"
end

##
# Returns the full path to the cache directory containing this
# spec's cached gem.
16 changes: 11 additions & 5 deletions lib/ruby/stdlib/rubygems/stub_specification.rb
Original file line number Diff line number Diff line change
@@ -42,15 +42,19 @@ def initialize(filename)
self.loaded_from = filename
@data = nil
@extensions = nil
@name = nil
@spec = nil
end

##
# True when this gem has been activated

def activated?
loaded = Gem.loaded_specs[name]
loaded && loaded.version == version
@activated ||=
begin
loaded = Gem.loaded_specs[name]
loaded && loaded.version == version
end
end

def build_extensions # :nodoc:
@@ -154,9 +158,11 @@ def require_paths
# The full Gem::Specification for this gem, loaded from evalling its gemspec

def to_spec
@spec ||= Gem.loaded_specs.values.find { |spec|
spec.name == @name and spec.version == @version
}
@spec ||= if @data then
Gem.loaded_specs.values.find { |spec|
spec.name == name and spec.version == version
}
end

@spec ||= Gem::Specification.load(loaded_from)
@spec.ignored = @ignored if instance_variable_defined? :@ignored
31 changes: 31 additions & 0 deletions lib/ruby/stdlib/rubygems/test_case.rb
Original file line number Diff line number Diff line change
@@ -1035,6 +1035,37 @@ def util_zip(data)
Zlib::Deflate.deflate data
end

def util_set_RUBY_VERSION(version, patchlevel = nil, revision = nil)
if Gem.instance_variables.include? :@ruby_version or
Gem.instance_variables.include? '@ruby_version' then
Gem.send :remove_instance_variable, :@ruby_version
end

@RUBY_VERSION = RUBY_VERSION
@RUBY_PATCHLEVEL = RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
@RUBY_REVISION = RUBY_REVISION if defined?(RUBY_REVISION)

Object.send :remove_const, :RUBY_VERSION
Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)

Object.const_set :RUBY_VERSION, version
Object.const_set :RUBY_PATCHLEVEL, patchlevel if patchlevel
Object.const_set :RUBY_REVISION, revision if revision
end

def util_restore_RUBY_VERSION
Object.send :remove_const, :RUBY_VERSION
Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)

Object.const_set :RUBY_VERSION, @RUBY_VERSION
Object.const_set :RUBY_PATCHLEVEL, @RUBY_PATCHLEVEL if
defined?(@RUBY_PATCHLEVEL)
Object.const_set :RUBY_REVISION, @RUBY_REVISION if
defined?(@RUBY_REVISION)
end

##
# Is this test being run on a Windows platform?

4 changes: 2 additions & 2 deletions lib/ruby/stdlib/rubygems/text.rb
Original file line number Diff line number Diff line change
@@ -27,9 +27,9 @@ def format_text(text, wrap, indent=0)
end

def min3 a, b, c # :nodoc:
if a < b && a < c
if a < b && a < c then
a
elsif b < a && b < c
elsif b < c then
b
else
c
1 change: 0 additions & 1 deletion lib/ruby/stdlib/rubygems/user_interaction.rb
Original file line number Diff line number Diff line change
@@ -318,7 +318,6 @@ def _gets_noecho
elsif Gem.win_platform?
def _gets_noecho
require "Win32API"
char = nil
password = ''

while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do

0 comments on commit 95ab70e

Please sign in to comment.