Skip to content

Commit

Permalink
Showing 45 changed files with 485 additions and 370 deletions.
2 changes: 1 addition & 1 deletion bin/jgem
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ require 'rubygems/exceptions'
required_version = Gem::Requirement.new ">= 1.8.7"

unless required_version.satisfied_by? Gem.ruby_version then
abort "Expected Ruby Version #{required_version}, is #{Gem.ruby_version}"
abort "Expected Ruby version #{required_version}, is #{Gem.ruby_version}"
end

args = ARGV.clone
5 changes: 5 additions & 0 deletions bin/rake
Original file line number Diff line number Diff line change
@@ -19,4 +19,9 @@ if ARGV.first
end
end

if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('rake', 'rake', version)
else
gem "rake", version
load Gem.bin_path("rake", "rake", version)
end
78 changes: 57 additions & 21 deletions lib/ruby/stdlib/rubygems.rb
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
require 'thread'

module Gem
VERSION = "2.6.11"
VERSION = "2.6.13"
end

# Must be first since it unloads the prelude from 1.9.2
@@ -39,23 +39,24 @@ module Gem
# Further RubyGems documentation can be found at:
#
# * {RubyGems Guides}[http://guides.rubygems.org]
# * {RubyGems API}[http://rubygems.rubyforge.org/rdoc] (also available from
# * {RubyGems API}[http://www.rubydoc.info/github/rubygems/rubygems] (also available from
# <tt>gem server</tt>)
#
# == RubyGems Plugins
#
# As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or
# $LOAD_PATH. Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and
# placed at the root of your gem's #require_path. Plugins are discovered via
# Gem::find_files then loaded. Take care when implementing a plugin as your
# Gem::find_files and then loaded. Take care when implementing a plugin as your
# plugin file may be loaded multiple times if multiple versions of your gem
# are installed.
#
# For an example plugin, see the graph gem which adds a `gem graph` command.
# For an example plugin, see the {Graph gem}[https://github.com/seattlerb/graph]
# which adds a `gem graph` command.
#
# == RubyGems Defaults, Packaging
#
# RubyGems defaults are stored in rubygems/defaults.rb. If you're packaging
# RubyGems defaults are stored in lib/rubygems/defaults.rb. If you're packaging
# RubyGems or implementing Ruby you can change RubyGems' defaults.
#
# For RubyGems packagers, provide lib/rubygems/defaults/operating_system.rb
@@ -65,7 +66,7 @@ module Gem
# override any defaults from lib/rubygems/defaults.rb.
#
# If you need RubyGems to perform extra work on install or uninstall, your
# defaults override file can set pre and post install and uninstall hooks.
# defaults override file can set pre/post install and uninstall hooks.
# See Gem::pre_install, Gem::pre_uninstall, Gem::post_install,
# Gem::post_uninstall.
#
@@ -106,6 +107,8 @@ module Gem
#
# (If your name is missing, PLEASE let us know!)
#
# == License
#
# See {LICENSE.txt}[rdoc-ref:lib/rubygems/LICENSE.txt] for permissions.
#
# Thanks!
@@ -130,6 +133,7 @@ module Gem

GEM_DEP_FILES = %w[
gem.deps.rb
gems.rb
Gemfile
Isolate
]
@@ -174,6 +178,8 @@ module Gem
write_binary_errors
end.freeze

USE_BUNDLER_FOR_GEMDEPS = false # :nodoc:

@@win_platform = nil

@configuration = nil
@@ -234,6 +240,7 @@ def self.needs

def self.finish_resolve(request_set=Gem::RequestSet.new)
request_set.import Gem::Specification.unresolved_deps.values
request_set.import Gem.loaded_specs.values.map {|s| Gem::Dependency.new(s.name, s.version) }

request_set.resolve_current.each do |s|
s.full_spec.activate
@@ -265,17 +272,22 @@ def self.find_spec_for_exe name, exec_name, requirements

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

specs = dep.matching_specs(true)

raise Gem::GemNotFoundException,
"can't find gem #{dep}" if specs.empty?
find_specs = proc { dep.matching_specs(true) }
if dep.to_s == "bundler (>= 0.a)"
specs = Gem::BundlerVersionFinder.without_filtering(&find_specs)
else
specs = find_specs.call
end

specs = specs.find_all { |spec|
spec.executables.include? exec_name
} if exec_name

unless spec = specs.first
msg = "can't find gem #{name} (#{requirements}) with executable #{exec_name}"
msg = "can't find gem #{dep} with executable #{exec_name}"
if name == "bundler" && bundler_message = Gem::BundlerVersionFinder.missing_version_message
msg = bundler_message
end
raise Gem::GemNotFoundException, msg
end

@@ -718,9 +730,20 @@ def self.load_yaml

##
# The file name and line number of the caller of the caller of this method.
#
# +depth+ is how many layers up the call stack it should go.
#
# e.g.,
#
# def a; Gem.location_of_caller; end
# a #=> ["x.rb", 2] # (it'll vary depending on file name and line number)
#
# def b; c; end
# def c; Gem.location_of_caller(2); end
# b #=> ["x.rb", 6] # (it'll vary depending on file name and line number)

def self.location_of_caller
caller[1] =~ /(.*?):(\d+).*?$/i
def self.location_of_caller(depth = 1)
caller[depth] =~ /(.*?):(\d+).*?$/i
file = $1
lineno = $2.to_i

@@ -1169,14 +1192,26 @@ def self.use_gemdeps path = nil
raise ArgumentError, "Unable to find gem dependencies file at #{path}"
end

ENV["BUNDLE_GEMFILE"] ||= File.expand_path(path)
require 'rubygems/user_interaction'
Gem::DefaultUserInteraction.use_ui(ui) do
require "bundler/postit_trampoline" unless ENV["BUNDLE_TRAMPOLINE_DISABLE"]
require "bundler"
@gemdeps = Bundler.setup
Bundler.ui = nil
@gemdeps.requested_specs.map(&:to_spec).sort_by(&:name)
if USE_BUNDLER_FOR_GEMDEPS

ENV["BUNDLE_GEMFILE"] ||= File.expand_path(path)
require 'rubygems/user_interaction'
Gem::DefaultUserInteraction.use_ui(ui) do
require "bundler"
@gemdeps = Bundler.setup
Bundler.ui = nil
@gemdeps.requested_specs.map(&:to_spec).sort_by(&:name)
end

else

rs = Gem::RequestSet.new
@gemdeps = rs.load_gemdeps path

rs.resolve_current.map do |s|
s.full_spec.tap(&:activate)
end

end
rescue => e
case e
@@ -1320,6 +1355,7 @@ def clear_default_specs

MARSHAL_SPEC_DIR = "quick/Marshal.#{Gem.marshal_version}/"

autoload :BundlerVersionFinder, 'rubygems/bundler_version_finder'
autoload :ConfigFile, 'rubygems/config_file'
autoload :Dependency, 'rubygems/dependency'
autoload :DependencyList, 'rubygems/dependency_list'
112 changes: 112 additions & 0 deletions lib/ruby/stdlib/rubygems/bundler_version_finder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
module Gem::BundlerVersionFinder
@without_filtering = false

def self.without_filtering
without_filtering, @without_filtering = true, @without_filtering
yield
ensure
@without_filtering = without_filtering
end

def self.bundler_version
version, _ = bundler_version_with_reason

return unless version

Gem::Version.new(version)
end

def self.bundler_version_with_reason
return if @without_filtering

if v = ENV["BUNDLER_VERSION"]
return [v, "`$BUNDLER_VERSION`"]
end
if v = bundle_update_bundler_version
return if v == true
return [v, "`bundle update --bundler`"]
end
v, lockfile = lockfile_version
if v
return [v, "your #{lockfile}"]
end
end

def self.missing_version_message
return unless vr = bundler_version_with_reason
<<-EOS
Could not find 'bundler' (#{vr.first}) required by #{vr.last}.
To update to the lastest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:#{vr.first}`
EOS
end

def self.compatible?(spec)
return true unless spec.name == "bundler".freeze
return true unless bundler_version = self.bundler_version
if bundler_version.segments.first >= 2
spec.version == bundler_version
else # 1.x
spec.version.segments.first < 2
end
end

def self.filter!(specs)
return unless bundler_version = self.bundler_version
if bundler_version.segments.first >= 2
specs.reject! { |spec| spec.version != bundler_version }
else # 1.x
specs.reject! { |spec| spec.version.segments.first >= 2}
end
end

def self.bundle_update_bundler_version
return unless File.basename($0) == "bundle".freeze
return unless "update".start_with?(ARGV.first || " ")
bundler_version = nil
update_index = nil
ARGV.each_with_index do |a, i|
if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
bundler_version = a
end
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
bundler_version = $1 || true
update_index = i
end
bundler_version
end
private_class_method :bundle_update_bundler_version

def self.lockfile_version
return unless lockfile = lockfile_contents
lockfile, contents = lockfile
lockfile ||= "lockfile"
regexp = /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
return unless contents =~ regexp
[$1, lockfile]
end
private_class_method :lockfile_version

def self.lockfile_contents
gemfile = ENV["BUNDLE_GEMFILE"]
gemfile = nil if gemfile && gemfile.empty?
Gem::Util.traverse_parents Dir.pwd do |directory|
next unless gemfile = Gem::GEM_DEP_FILES.find { |f| File.file?(f.untaint) }

gemfile = File.join directory, gemfile
break
end unless gemfile

return unless gemfile

lockfile = case gemfile
when "gems.rb" then "gems.locked"
else "#{gemfile}.lock"
end.untaint

return unless File.file?(lockfile)

[lockfile, File.read(lockfile)]
end
private_class_method :lockfile_contents
end
2 changes: 2 additions & 0 deletions lib/ruby/stdlib/rubygems/command_manager.rb
Original file line number Diff line number Diff line change
@@ -58,6 +58,8 @@ class Gem::CommandManager
:rdoc,
:search,
:server,
:signin,
:signout,
:sources,
:specification,
:stale,
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/commands/open_command.rb
Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ def open_editor path
end

def spec_for name
spec = Gem::Specification.find_all_by_name(name, @version).last
spec = Gem::Specification.find_all_by_name(name, @version).first

return spec if spec

21 changes: 12 additions & 9 deletions lib/ruby/stdlib/rubygems/commands/pristine_command.rb
Original file line number Diff line number Diff line change
@@ -125,14 +125,14 @@ def execute
next
end

unless spec.extensions.empty? or options[:extensions] then
unless spec.extensions.empty? or options[:extensions] or options[:only_executables] then
say "Skipped #{spec.full_name}, it needs to compile an extension"
next
end

gem = spec.cache_file

unless File.exist? gem then
unless File.exist? gem or options[:only_executables] then
require 'rubygems/remote_fetcher'

say "Cached gem for #{spec.full_name} not found, attempting to fetch..."
@@ -157,16 +157,19 @@ def execute
install_defaults.to_s['--env-shebang']
end

installer = Gem::Installer.at(gem,
:wrappers => true,
:force => true,
:install_dir => spec.base_dir,
:env_shebang => env_shebang,
:build_args => spec.build_args)

installer_options = {
:wrappers => true,
:force => true,
:install_dir => spec.base_dir,
:env_shebang => env_shebang,
:build_args => spec.build_args,
}

if options[:only_executables] then
installer = Gem::Installer.for_spec(spec, installer_options)
installer.generate_bin
else
installer = Gem::Installer.at(gem, installer_options)
installer.install
end

7 changes: 4 additions & 3 deletions lib/ruby/stdlib/rubygems/commands/query_command.rb
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ def execute
name = Array(options[:name])
else
args = options[:args].to_a
name = options[:exact] ? args : args.map{|arg| /#{arg}/i }
name = options[:exact] ? args.map{|arg| /\A#{Regexp.escape(arg)}\Z/ } : args.map{|arg| /#{arg}/i }
end

prerelease = options[:prerelease]
@@ -226,7 +226,7 @@ def output_versions output, versions
end
end

output << make_entry(matching_tuples, platforms)
output << clean_text(make_entry(matching_tuples, platforms))
end
end

@@ -352,7 +352,8 @@ def spec_platforms entry, platforms
end

def spec_summary entry, spec
entry << "\n\n" << format_text(spec.summary, 68, 4)
summary = truncate_text(spec.summary, "the summary for #{spec.full_name}")
entry << "\n\n" << format_text(summary, 68, 4)
end

end
76 changes: 46 additions & 30 deletions lib/ruby/stdlib/rubygems/commands/setup_command.rb
Original file line number Diff line number Diff line change
@@ -15,7 +15,8 @@ def initialize
super 'setup', 'Install RubyGems',
:format_executable => true, :document => %w[ri],
:site_or_vendor => 'sitelibdir',
:destdir => '', :prefix => '', :previous_version => ''
:destdir => '', :prefix => '', :previous_version => '',
:regenerate_binstubs => true

add_option '--previous-version=VERSION',
'Previous version of RubyGems',
@@ -79,6 +80,15 @@ def initialize
options[:document].uniq!
end

add_option '--[no-]regenerate-binstubs',
'Regenerate gem binstubs' do |value, options|
if value then
options[:regenerate_binstubs] = true
else
options.delete(:regenerate_binstubs)
end
end

@verbose = nil
end

@@ -92,7 +102,7 @@ def check_ruby_version
end

def defaults_str # :nodoc:
"--format-executable --document ri"
"--format-executable --document ri --regenerate-binstubs"
end

def description # :nodoc:
@@ -146,6 +156,8 @@ def execute

say "RubyGems #{Gem::VERSION} installed"

regenerate_binstubs

uninstall_old_gemcutter

documentation_success = install_rdoc
@@ -208,10 +220,9 @@ def execute
def install_executables(bin_dir)
@bin_file_names = []

{
'gem' => 'bin',
'bundler' => 'bundler/exe',
}.each do |tool, path|
executables = { 'gem' => 'bin' }
executables['bundler'] = 'bundler/exe' if Gem::USE_BUNDLER_FOR_GEMDEPS
executables.each do |tool, path|
say "Installing #{tool} executable" if @verbose

Dir.chdir path do
@@ -277,10 +288,9 @@ def install_file file, dest_dir
end

def install_lib(lib_dir)
{
'RubyGems' => 'lib',
'Bundler' => 'bundler/lib'
}.each do |tool, path|
libs = { 'RubyGems' => 'lib' }
libs['Bundler'] = 'bundler/lib' if Gem::USE_BUNDLER_FOR_GEMDEPS
libs.each do |tool, path|
say "Installing #{tool}" if @verbose

lib_files = rb_files_in path
@@ -340,26 +350,26 @@ def fake_spec.full_gem_path
end

def install_default_bundler_gem
Dir.chdir("bundler") do
bundler_spec = Gem::Specification.load("bundler.gemspec")
bundler_spec.files = Dir["{*.md,{lib,exe,man}/**/*}"]
bundler_spec.executables -= %w[bundler bundle_ruby]
Dir.entries(Gem::Specification.default_specifications_dir).
select {|gs| gs.start_with?("bundler-") }.
each {|gs| File.delete(File.join(Gem::Specification.default_specifications_dir, gs)) }
return unless Gem::USE_BUNDLER_FOR_GEMDEPS

default_spec_path = File.join(Gem::Specification.default_specifications_dir, "#{bundler_spec.full_name}.gemspec")
Gem.write_binary(default_spec_path, bundler_spec.to_ruby)
bundler_spec = Gem::Specification.load("bundler/bundler.gemspec")
bundler_spec.files = Dir["bundler/{*.md,{lib,exe,man}/**/*}"]
bundler_spec.executables -= %w[bundler bundle_ruby]
Dir.entries(Gem::Specification.default_specifications_dir).
select {|gs| gs.start_with?("bundler-") }.
each {|gs| File.delete(File.join(Gem::Specification.default_specifications_dir, gs)) }

bundler_spec = Gem::Specification.load(default_spec_path)
default_spec_path = File.join(Gem::Specification.default_specifications_dir, "#{bundler_spec.full_name}.gemspec")
Gem.write_binary(default_spec_path, bundler_spec.to_ruby)

Dir.entries(bundler_spec.gems_dir).
select {|default_gem| default_gem.start_with?("bundler-") }.
each {|default_gem| rm_r File.join(bundler_spec.gems_dir, default_gem) }
bundler_spec = Gem::Specification.load(default_spec_path)

mkdir_p bundler_spec.bin_dir
bundler_spec.executables.each {|e| cp File.join(bundler_spec.bindir, e), File.join(bundler_spec.bin_dir, e) }
end
Dir.entries(bundler_spec.gems_dir).
select {|default_gem| default_gem.start_with?("bundler-") }.
each {|default_gem| rm_r File.join(bundler_spec.gems_dir, default_gem) }

mkdir_p bundler_spec.bin_dir
bundler_spec.executables.each {|e| cp File.join("bundler", bundler_spec.bindir, e), File.join(bundler_spec.bin_dir, e) }
end

def make_destination_dirs(install_destdir)
@@ -452,10 +462,9 @@ def remove_old_bin_files(bin_dir)
end

def remove_old_lib_files lib_dir
{
File.join(lib_dir, 'rubygems') => 'lib/rubygems',
File.join(lib_dir, 'bundler') => 'bundler/lib/bundler',
}.each do |old_lib_dir, new_lib_dir|
lib_dirs = { File.join(lib_dir, 'rubygems') => 'lib/rubygems' }
lib_dirs[File.join(lib_dir, 'bundler')] = 'bundler/lib/bundler' if Gem::USE_BUNDLER_FOR_GEMDEPS
lib_dirs.each do |old_lib_dir, new_lib_dir|
lib_files = rb_files_in(new_lib_dir)

old_lib_files = rb_files_in(old_lib_dir)
@@ -520,4 +529,11 @@ def uninstall_old_gemcutter
rescue Gem::InstallError
end

def regenerate_binstubs
require "rubygems/commands/pristine_command"
say "Regenerating binstubs"
command = Gem::Commands::PristineCommand.new
command.invoke(*%w[--all --only-executables --silent])
end

end
33 changes: 33 additions & 0 deletions lib/ruby/stdlib/rubygems/commands/signin_command.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/gemcutter_utilities'

class Gem::Commands::SigninCommand < Gem::Command
include Gem::GemcutterUtilities

def initialize
super 'signin', 'Sign in to any gemcutter-compatible host. '\
'It defaults to https://rubygems.org'

add_option('--host HOST', 'Push to another gemcutter-compatible host') do |value, options|
options[:host] = value
end

end

def description # :nodoc:
'The signin command executes host sign in for a push server (the default is'\
' https://rubygems.org). The host can be provided with the host flag or can'\
' be inferred from the provided gem. Host resolution matches the resolution'\
' strategy for the push command.'
end

def usage # :nodoc:
program_name
end

def execute
sign_in options[:host]
end

end
33 changes: 33 additions & 0 deletions lib/ruby/stdlib/rubygems/commands/signout_command.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true
require 'rubygems/command'

class Gem::Commands::SignoutCommand < Gem::Command

def initialize
super 'signout', 'Sign out from all the current sessions.'
end

def description # :nodoc:
'The `signout` command is used to sign out from all current sessions,'\
' allowing you to sign in using a different set of credentials.'
end

def usage # :nodoc:
program_name
end

def execute
credentials_path = Gem.configuration.credentials_path

if !File.exist?(credentials_path) then
alert_error 'You are not currently signed in.'
elsif !File.writable?(credentials_path) then
alert_error "File '#{Gem.configuration.credentials_path}' is read-only."\
' Please make sure it is writable.'
else
Gem.configuration.unset_api_key!
say 'You have successfully signed out from all sessions.'
end
end

end
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/commands/sources_command.rb
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ def add_source source_uri # :nodoc:
source = Gem::Source.new source_uri

begin
if Gem.sources.include? source_uri then
if Gem.sources.include? source then
say "source #{source_uri} already present in the cache"
else
source.load_specs :released
7 changes: 4 additions & 3 deletions lib/ruby/stdlib/rubygems/commands/uninstall_command.rb
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ def initialize
options[:ignore] = value
end

add_option('-D', '--[no-]-check-development',
add_option('-D', '--[no-]check-development',
'Check development dependencies while uninstalling',
'(default: false)') do |value, options|
options[:check_dev] = value
@@ -143,7 +143,9 @@ def uninstall_specific
deplist = Gem::DependencyList.new

get_all_gem_names.uniq.each do |name|
Gem::Specification.find_all_by_name(name).each do |spec|
gem_specs = Gem::Specification.find_all_by_name(name)
say("Gem '#{name}' is not installed") if gem_specs.empty?
gem_specs.each do |spec|
deplist.add spec
end
end
@@ -162,4 +164,3 @@ def uninstall_specific
end

end

2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/commands/update_command.rb
Original file line number Diff line number Diff line change
@@ -70,7 +70,7 @@ def usage # :nodoc:

def check_latest_rubygems version # :nodoc:
if Gem.rubygems_version == version then
say "Latest version currently installed. Aborting."
say "Latest version already installed. Done."
terminate_interaction
end

9 changes: 9 additions & 0 deletions lib/ruby/stdlib/rubygems/config_file.rb
Original file line number Diff line number Diff line change
@@ -336,6 +336,15 @@ def set_api_key host, api_key
load_api_keys # reload
end

##
# Remove the +~/.gem/credentials+ file to clear all the current sessions.

def unset_api_key!
return false unless File.exist?(credentials_path)

File.delete(credentials_path)
end

def load_file(filename)
Gem.load_yaml

7 changes: 6 additions & 1 deletion lib/ruby/stdlib/rubygems/core_ext/kernel_require.rb
Original file line number Diff line number Diff line change
@@ -43,7 +43,12 @@ def require path

if spec = Gem.find_unresolved_default_spec(path)
Gem.remove_unresolved_default_spec(spec)
Kernel.send(:gem, spec.name)
begin
Kernel.send(:gem, spec.name)
rescue Exception
RUBYGEMS_ACTIVATION_MONITOR.exit
raise
end
end

# If there are no unresolved deps, then we can use just try
2 changes: 2 additions & 0 deletions lib/ruby/stdlib/rubygems/dependency.rb
Original file line number Diff line number Diff line change
@@ -280,6 +280,8 @@ def matching_specs platform_only = false
requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
}.map(&:to_spec)

Gem::BundlerVersionFinder.filter!(matches) if name == "bundler".freeze

if platform_only
matches.reject! { |spec|
spec.nil? || !Gem::Platform.match(spec.platform)
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/dependency_list.rb
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ def find_name(full_name)
end

def inspect # :nodoc:
"#<%s:0x%x %p>" % [self.class, object_id, map { |s| s.full_name }]
"%s %p>" % [super[0..-2], map { |s| s.full_name }]
end

##
3 changes: 3 additions & 0 deletions lib/ruby/stdlib/rubygems/errors.rb
Original file line number Diff line number Diff line change
@@ -58,6 +58,9 @@ def initialize name, requirement, specs
private

def build_message
if name == "bundler" && message = Gem::BundlerVersionFinder.missing_version_message
return message
end
names = specs.map(&:full_name)
"Could not find '#{name}' (#{requirement}) - did find: [#{names.join ','}]\n"
end
6 changes: 2 additions & 4 deletions lib/ruby/stdlib/rubygems/ext/ext_conf_builder.rb
Original file line number Diff line number Diff line change
@@ -27,17 +27,15 @@ def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
# TODO: Make this unconditional when rubygems no longer supports Ruby 1.9.x.
tmp_dest = get_relative_path(tmp_dest) unless Gem.win_platform? && RUBY_VERSION <= '2.0'

t = nil
Tempfile.open %w"siteconf .rb", "." do |siteconf|
t = siteconf
siteconf.puts "require 'rbconfig'"
siteconf.puts "dest_path = #{tmp_dest.dump}"
%w[sitearchdir sitelibdir].each do |dir|
siteconf.puts "RbConfig::MAKEFILE_CONFIG['#{dir}'] = dest_path"
siteconf.puts "RbConfig::CONFIG['#{dir}'] = dest_path"
end

siteconf.flush
siteconf.close

destdir = ENV["DESTDIR"]

@@ -78,9 +76,9 @@ def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
end
ensure
ENV["DESTDIR"] = destdir
siteconf.close!
end
end
t.unlink if t and t.path

results
ensure
26 changes: 21 additions & 5 deletions lib/ruby/stdlib/rubygems/installer.rb
Original file line number Diff line number Diff line change
@@ -136,8 +136,9 @@ def self.for_spec spec, options = {}
end

##
# Constructs an Installer instance that will install the gem located at
# +gem+. +options+ is a Hash with the following keys:
# Constructs an Installer instance that will install the gem at +package+ which
# can either be a path or an instance of Gem::Package. +options+ is a Hash
# with the following keys:
#
# :bin_dir:: Where to put a bin wrapper if needed.
# :development:: Whether or not development dependencies should be installed.
@@ -157,6 +158,7 @@ def self.for_spec spec, options = {}
# :wrappers:: Install wrappers if true, symlinks if false.
# :build_args:: An Array of arguments to pass to the extension builder
# process. If not set, then Gem::Command.build_args is used
# :post_install_message:: Print gem post install message if true

def initialize(package, options={})
require 'fileutils'
@@ -214,7 +216,7 @@ def check_executable_overwrite filename # :nodoc:

ruby_executable = true
existing = io.read.slice(%r{
^(
^\s*(
gem \s |
load \s Gem\.bin_path\( |
load \s Gem\.activate_bin_path\(
@@ -471,7 +473,7 @@ def generate_bin # :nodoc:

unless File.exist? bin_path then
# TODO change this to a more useful warning
warn "#{bin_path} maybe `gem pristine #{spec.name}` will fix it?"
warn "`#{bin_path}` does not exist, maybe `gem pristine #{spec.name}` will fix it?"
next
end

@@ -700,10 +702,17 @@ def verify_gem_home(unpack = false) # :nodoc:
unpack or File.writable?(gem_home)
end

def verify_spec_name
return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN
raise Gem::InstallError, "#{spec} has an invalid name"
end

##
# Return the text for an application file.

def app_script_text(bin_file_name)
# note that the `load` lines cannot be indented, as old RG versions match
# against the beginning of the line
return <<-TEXT
#{shebang bin_file_name}
#
@@ -726,7 +735,12 @@ def app_script_text(bin_file_name)
end
end
if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('#{spec.name}', '#{bin_file_name}', version)
else
gem #{spec.name.dump}, version
load Gem.bin_path(#{spec.name.dump}, #{bin_file_name.dump}, version)
end
TEXT
end

@@ -812,13 +826,15 @@ def dir
#
# Version and dependency checks are skipped if this install is forced.
#
# The dependent check will be skipped this install is ignoring dependencies.
# The dependent check will be skipped if the install is ignoring dependencies.

def pre_install_checks
verify_gem_home options[:unpack]

ensure_loadable_spec

verify_spec_name

if options[:install_as_default]
Gem.ensure_default_gem_subdirectories gem_home
else
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/platform.rb
Original file line number Diff line number Diff line change
@@ -112,7 +112,7 @@ def initialize(arch)
end

def inspect
"#<%s:0x%x @cpu=%p, @os=%p, @version=%p>" % [self.class, object_id, *to_a]
"%s @cpu=%p, @os=%p, @version=%p>" % [super[0..-2], *to_a]
end

def to_a
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/remote_fetcher.rb
Original file line number Diff line number Diff line change
@@ -110,7 +110,7 @@ def api_endpoint(uri)
else
target = res.target.to_s.strip

if /\.#{Regexp.quote(host)}\z/ =~ target
if URI("http://" + target).host.end_with?(".#{host}")
return URI.parse "#{uri.scheme}://#{target}#{uri.path}"
end

14 changes: 7 additions & 7 deletions lib/ruby/stdlib/rubygems/resolver.rb
Original file line number Diff line number Diff line change
@@ -235,17 +235,16 @@ def search_for(dependency)

groups = Hash.new { |hash, key| hash[key] = [] }

possibles.each do |spec|
# create groups & sources in the same loop
sources = possibles.map { |spec|
source = spec.source

sources << source unless sources.include? source

groups[source] << spec
end
source
}.uniq.reverse

activation_requests = []

sources.sort.each do |source|
sources.each do |source|
groups[source].
sort_by { |spec| [spec.version, Gem::Platform.local =~ spec.platform ? 1 : 0] }.
map { |spec| ActivationRequest.new spec, dependency, [] }.
@@ -275,13 +274,14 @@ def allow_missing?(dependency)
end

def sort_dependencies(dependencies, activated, conflicts)
dependencies.sort_by do |dependency|
dependencies.sort_by.with_index do |dependency, i|
name = name_for(dependency)
[
activated.vertex_named(name).payload ? 0 : 1,
amount_constrained(dependency),
conflicts[name] ? 0 : 1,
activated.vertex_named(name).payload ? 0 : search_for(dependency).count,
i # for stable sort
]
end
end
10 changes: 4 additions & 6 deletions lib/ruby/stdlib/rubygems/resolver/installer_set.rb
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ def initialize domain
@ignore_dependencies = false
@ignore_installed = false
@local = {}
@local_source = Gem::Source::Local.new
@remote_set = Gem::Resolver::BestSet.new
@specs = {}
end
@@ -136,13 +137,11 @@ def find_all req

res.concat matching_local

local_source = Gem::Source::Local.new

begin
if local_spec = local_source.find_gem(name, dep.requirement) then
if local_spec = @local_source.find_gem(name, dep.requirement) then
res << Gem::Resolver::IndexSpecification.new(
self, local_spec.name, local_spec.version,
local_source, local_spec.platform)
@local_source, local_spec.platform)
end
rescue Gem::Package::FormatError
# ignore
@@ -194,7 +193,7 @@ def load_spec name, ver, platform, source # :nodoc:
# Has a local gem for +dep_name+ been added to this set?

def local? dep_name # :nodoc:
spec, = @local[dep_name]
spec, _ = @local[dep_name]

spec
end
@@ -226,4 +225,3 @@ def remote= remote # :nodoc:
end

end

2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/security.rb
Original file line number Diff line number Diff line change
@@ -462,7 +462,7 @@ def self.create_cert_self_signed subject, key, age = ONE_YEAR,

##
# Creates a new key pair of the specified +length+ and +algorithm+. The
# default is a 2048 bit RSA key.
# default is a 3072 bit RSA key.

def self.create_key length = KEY_LENGTH, algorithm = KEY_ALGORITHM
algorithm.new length
18 changes: 5 additions & 13 deletions lib/ruby/stdlib/rubygems/server.rb
Original file line number Diff line number Diff line change
@@ -573,19 +573,11 @@ def quick(req, res)
add_date res

case req.request_uri.path
when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)-([0-9.]+[^-]*?)(-.*?)?\.gemspec\.rz$| then
marshal_format, name, version, platform = $1, $2, $3, $4
specs = Gem::Specification.find_all_by_name name, version
when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)\.gemspec\.rz$| then
marshal_format, full_name = $1, $2
specs = Gem::Specification.find_all_by_full_name(full_name)

selector = [name, version, platform].map(&:inspect).join ' '

platform = if platform then
Gem::Platform.new platform.sub(/^-/, '')
else
Gem::Platform::RUBY
end

specs = specs.select { |s| s.platform == platform }
selector = full_name.inspect

if specs.empty? then
res.status = 404
@@ -657,7 +649,7 @@ def root(req, res)
"only_one_executable" => true,
"full_name" => "rubygems-#{Gem::VERSION}",
"has_deps" => false,
"homepage" => "http://docs.rubygems.org/",
"homepage" => "http://guides.rubygems.org/",
"name" => 'rubygems',
"ri_installed" => true,
"summary" => "RubyGems itself",
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/source.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true
autoload :FileUtils, 'fileutils'
autoload :URI, 'uri'
require 'fileutils'

##
# A Source knows how to list and fetch gems from a RubyGems marshal index.
73 changes: 38 additions & 35 deletions lib/ruby/stdlib/rubygems/source/local.rb
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ def initialize # :nodoc:
@specs = nil
@api_uri = nil
@uri = nil
@load_specs_names = {}
end

##
@@ -34,45 +35,47 @@ def inspect # :nodoc:
end

def load_specs type # :nodoc:
names = []

@specs = {}

Dir["*.gem"].each do |file|
begin
pkg = Gem::Package.new(file)
rescue SystemCallError, Gem::Package::FormatError
# ignore
else
tup = pkg.spec.name_tuple
@specs[tup] = [File.expand_path(file), pkg]

case type
when :released
unless pkg.spec.version.prerelease?
names << pkg.spec.name_tuple
end
when :prerelease
if pkg.spec.version.prerelease?
names << pkg.spec.name_tuple
end
when :latest
tup = pkg.spec.name_tuple
@load_specs_names[type] ||= begin
names = []

cur = names.find { |x| x.name == tup.name }
if !cur
names << tup
elsif cur.version < tup.version
names.delete cur
names << tup
end
@specs = {}

Dir["*.gem"].each do |file|
begin
pkg = Gem::Package.new(file)
rescue SystemCallError, Gem::Package::FormatError
# ignore
else
names << pkg.spec.name_tuple
tup = pkg.spec.name_tuple
@specs[tup] = [File.expand_path(file), pkg]

case type
when :released
unless pkg.spec.version.prerelease?
names << pkg.spec.name_tuple
end
when :prerelease
if pkg.spec.version.prerelease?
names << pkg.spec.name_tuple
end
when :latest
tup = pkg.spec.name_tuple

cur = names.find { |x| x.name == tup.name }
if !cur
names << tup
elsif cur.version < tup.version
names.delete cur
names << tup
end
else
names << pkg.spec.name_tuple
end
end
end
end

names
names
end
end

def find_gem gem_name, version = Gem::Requirement.default, # :nodoc:
@@ -88,7 +91,7 @@ def find_gem gem_name, version = Gem::Requirement.default, # :nodoc:
if version.satisfied_by?(s.version)
if prerelease
found << s
elsif !s.version.prerelease?
elsif !s.version.prerelease? || version.prerelease?
found << s
end
end
4 changes: 3 additions & 1 deletion lib/ruby/stdlib/rubygems/source_local.rb
Original file line number Diff line number Diff line change
@@ -2,5 +2,7 @@
require 'rubygems/source'
require 'rubygems/source_local'

# TODO warn upon require, this file is deprecated.
unless Gem::Deprecate.skip
Kernel.warn "#{Gem.location_of_caller(3).join(':')}: Warning: Requiring rubygems/source_local is deprecated; please use rubygems/source/local instead."
end

5 changes: 3 additions & 2 deletions lib/ruby/stdlib/rubygems/source_specific_file.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true
require 'rubygems/source/specific_file'

# TODO warn upon require, this file is deprecated.

unless Gem::Deprecate.skip
Kernel.warn "#{Gem.location_of_caller(3).join(':')}: Warning: Requiring rubygems/source_specific_file is deprecated; please use rubygems/source/specific_file instead."
end
51 changes: 39 additions & 12 deletions lib/ruby/stdlib/rubygems/specification.rb
Original file line number Diff line number Diff line change
@@ -108,6 +108,8 @@ class Gem::Specification < Gem::BasicSpecification

private_constant :LOAD_CACHE if defined? private_constant

VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc:

# :startdoc:

##
@@ -456,15 +458,16 @@ def files
# * All strings must be UTF-8, no binary data is allowed
#
# You can use metadata to specify links to your gem's homepage, codebase,
# documentation, wiki, mailing list and issue tracker.
# documentation, wiki, mailing list, issue tracker and changelog.
#
# s.metadata = {
# "home" => "https://bestgemever.example.io",
# "code" => "https://example.com/user/bestgemever",
# "docs" => "https://www.example.info/gems/bestgemever/0.0.1",
# "wiki" => "https://example.com/user/bestgemever/wiki",
# "mail" => "https://groups.example.com/bestgemever",
# "bugs" => "https://example.com/user/bestgemever/issues"
# "bug_tracker_uri" => "https://example.com/user/bestgemever/issues",
# "changelog_uri" => "https://example.com/user/bestgemever/CHANGELOG.md",
# "documentation_uri" => "https://www.example.info/gems/bestgemever/0.0.1",
# "homepage_uri" => "https://bestgemever.example.io",
# "mailing_list_uri" => "https://groups.example.com/bestgemever",
# "source_code_uri" => "https://example.com/user/bestgemever",
# "wiki_uri" => "https://example.com/user/bestgemever/wiki"
# }
#
# These links will be used on your gem's page on rubygems.org and must pass
@@ -1031,6 +1034,13 @@ def self.find_all_by_name name, *requirements
Gem::Dependency.new(name, *requirements).matching_specs
end

##
# Returns every spec that has the given +full_name+

def self.find_all_by_full_name(full_name)
stubs.select {|s| s.full_name == full_name }.map(&:to_spec)
end

##
# Find the best specification matching a +name+ and +requirements+. Raises
# if the dependency doesn't resolve to a valid specification.
@@ -1049,6 +1059,7 @@ def self.find_by_name name, *requirements
def self.find_by_path path
path = path.dup.freeze
spec = @@spec_with_requirable_file[path] ||= (stubs.find { |s|
next unless Gem::BundlerVersionFinder.compatible?(s)
s.contains_requirable_file? path
} || NOT_FOUND)
spec.to_spec
@@ -1060,7 +1071,9 @@ def self.find_by_path path

def self.find_inactive_by_path path
stub = stubs.find { |s|
s.contains_requirable_file? path unless s.activated?
next if s.activated?
next unless Gem::BundlerVersionFinder.compatible?(s)
s.contains_requirable_file? path
}
stub && stub.to_spec
end
@@ -2124,7 +2137,7 @@ def inspect # :nodoc:
if $DEBUG
super
else
"#<#{self.class}:0x#{__id__.to_s(16)} #{full_name}>"
"#{super[0..-2]} #{full_name}>"
end
end

@@ -2690,9 +2703,15 @@ def validate packaging = true
end
end

unless String === name then
if !name.is_a?(String) then
raise Gem::InvalidSpecificationException,
"invalid value for attribute name: \"#{name.inspect}\" must be a string"
elsif name !~ /[a-zA-Z]/ then
raise Gem::InvalidSpecificationException,
"invalid value for attribute name: #{name.dump} must include at least one letter"
elsif name !~ VALID_NAME_PATTERN then
raise Gem::InvalidSpecificationException,
"invalid value for attribute name: \"#{name.inspect}\""
"invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores"
end

if raw_require_paths.empty? then
@@ -2845,7 +2864,15 @@ def validate packaging = true

def validate_metadata
url_validation_regex = %r{\Ahttps?:\/\/([^\s:@]+:[^\s:@]*@)?[A-Za-z\d\-]+(\.[A-Za-z\d\-]+)+\.?(:\d{1,5})?([\/?]\S*)?\z}
link_keys = ["home", "code", "docs", "wiki", "mail", "bugs"]
link_keys = %w(
bug_tracker_uri
changelog_uri
documentation_uri
homepage_uri
mailing_list_uri
source_code_uri
wiki_uri
)

metadata.each do|key, value|
if !key.kind_of?(String)
1 change: 0 additions & 1 deletion lib/ruby/stdlib/rubygems/ssl_certs/.document

This file was deleted.

25 changes: 0 additions & 25 deletions lib/ruby/stdlib/rubygems/ssl_certs/AddTrustExternalCARoot-2048.pem

This file was deleted.

32 changes: 0 additions & 32 deletions lib/ruby/stdlib/rubygems/ssl_certs/AddTrustExternalCARoot.pem

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

20 changes: 0 additions & 20 deletions lib/ruby/stdlib/rubygems/ssl_certs/GeoTrustGlobalCA.pem

This file was deleted.

This file was deleted.

This file was deleted.

9 changes: 5 additions & 4 deletions lib/ruby/stdlib/rubygems/test_case.rb
Original file line number Diff line number Diff line change
@@ -225,14 +225,12 @@ def setup
@orig_rubygems_gemdeps = ENV['RUBYGEMS_GEMDEPS']
@orig_bundle_gemfile = ENV['BUNDLE_GEMFILE']
@orig_rubygems_host = ENV['RUBYGEMS_HOST']
@orig_bundle_disable_postit = ENV['BUNDLE_TRAMPOLINE_DISABLE']
ENV.keys.find_all { |k| k.start_with?('GEM_REQUIREMENT_') }.each do |k|
ENV.delete k
end
@orig_gem_env_requirements = ENV.to_hash

ENV['GEM_VENDOR'] = nil
ENV['BUNDLE_TRAMPOLINE_DISABLE'] = 'true'

@current_dir = Dir.pwd
@fetcher = nil
@@ -406,7 +404,6 @@ def teardown
ENV['RUBYGEMS_GEMDEPS'] = @orig_rubygems_gemdeps
ENV['BUNDLE_GEMFILE'] = @orig_bundle_gemfile
ENV['RUBYGEMS_HOST'] = @orig_rubygems_host
ENV['BUNDLE_TRAMPOLINE_DISABLE'] = @orig_bundle_disable_postit

Gem.ruby = @orig_ruby if @orig_ruby

@@ -422,6 +419,7 @@ def teardown

Gem::Specification._clear_load_cache
Gem::Specification.unresolved_deps.clear
Gem::refresh
end

def common_installer_setup
@@ -496,7 +494,7 @@ def git_gem name = 'a', version = 1

system @git, 'add', gemspec
system @git, 'commit', '-a', '-m', 'a non-empty commit message', '--quiet'
head = Gem::Util.popen('git', 'rev-parse', 'master').strip
head = Gem::Util.popen(@git, 'rev-parse', 'master').strip
end

return name, git_spec.version, directory, head
@@ -1510,6 +1508,8 @@ def self.key_path key_name
begin
gem 'rdoc'
require 'rdoc'

require 'rubygems/rdoc'
rescue LoadError, Gem::LoadError
end

@@ -1526,3 +1526,4 @@ def self.key_path key_name
pid = $$
END {tmpdirs.each {|dir| Dir.rmdir(dir)} if $$ == pid}
Gem.clear_paths
Gem.loaded_specs.clear
15 changes: 14 additions & 1 deletion lib/ruby/stdlib/rubygems/text.rb
Original file line number Diff line number Diff line change
@@ -6,13 +6,26 @@

module Gem::Text

##
# Remove any non-printable characters and make the text suitable for
# printing.
def clean_text(text)
text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze)
end

def truncate_text(text, description, max_length = 100_000)
raise ArgumentError, "max_length must be positive" unless max_length > 0
return text if text.size <= max_length
"Truncating #{description} to #{max_length.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse} characters:\n" + text[0, max_length]
end

##
# Wraps +text+ to +wrap+ characters and optionally indents by +indent+
# characters

def format_text(text, wrap, indent=0)
result = []
work = text.dup
work = clean_text(text)

while work.length > wrap do
if work =~ /^(.{0,#{wrap}})[ \n]/ then
23 changes: 6 additions & 17 deletions lib/ruby/stdlib/rubygems/util.rb
Original file line number Diff line number Diff line change
@@ -109,26 +109,15 @@ def self.silent_system *command
##
# Enumerates the parents of +directory+.

def self.traverse_parents directory
def self.traverse_parents directory, &block
return enum_for __method__, directory unless block_given?

here = File.expand_path directory
start = here

Dir.chdir start

begin
loop do
yield here

Dir.chdir '..'

return if Dir.pwd == here # toplevel

here = Dir.pwd
end
ensure
Dir.chdir start
loop do
Dir.chdir here, &block
new_here = File.expand_path('..', here)
return if new_here == here # toplevel
here = new_here
end
end

2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/version.rb
Original file line number Diff line number Diff line change
@@ -170,7 +170,7 @@ def version
# True if the +version+ string matches RubyGems' requirements.

def self.correct? version
version.to_s =~ ANCHORED_VERSION_PATTERN
!!(version.to_s =~ ANCHORED_VERSION_PATTERN)
end

##

0 comments on commit 1695f1f

Please sign in to comment.