summaryrefslogtreecommitdiff
path: root/lib/rubygems
diff options
context:
space:
mode:
-rw-r--r--lib/rubygems/available_set.rb2
-rw-r--r--lib/rubygems/command_manager.rb4
-rw-r--r--lib/rubygems/commands/build_command.rb57
-rw-r--r--lib/rubygems/commands/cert_command.rb2
-rw-r--r--lib/rubygems/commands/help_command.rb2
-rw-r--r--lib/rubygems/commands/owner_command.rb12
-rw-r--r--lib/rubygems/commands/pristine_command.rb2
-rw-r--r--lib/rubygems/commands/push_command.rb10
-rw-r--r--lib/rubygems/commands/query_command.rb17
-rw-r--r--lib/rubygems/commands/server_command.rb4
-rw-r--r--lib/rubygems/commands/setup_command.rb70
-rw-r--r--lib/rubygems/commands/sources_command.rb8
-rw-r--r--lib/rubygems/commands/specification_command.rb6
-rw-r--r--lib/rubygems/commands/yank_command.rb8
-rw-r--r--lib/rubygems/core_ext/kernel_require.rb3
-rw-r--r--lib/rubygems/core_ext/kernel_warn.rb13
-rw-r--r--lib/rubygems/defaults.rb4
-rw-r--r--lib/rubygems/dependency.rb2
-rw-r--r--lib/rubygems/dependency_installer.rb7
-rw-r--r--lib/rubygems/ext/builder.rb45
-rw-r--r--lib/rubygems/ext/cmake_builder.rb8
-rw-r--r--lib/rubygems/ext/configure_builder.rb8
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb33
-rw-r--r--lib/rubygems/ext/rake_builder.rb6
-rw-r--r--lib/rubygems/gemcutter_utilities.rb104
-rw-r--r--lib/rubygems/indexer.rb1
-rw-r--r--lib/rubygems/install_update_options.rb4
-rw-r--r--lib/rubygems/installer.rb21
-rw-r--r--lib/rubygems/installer_test_case.rb13
-rw-r--r--lib/rubygems/name_tuple.rb2
-rw-r--r--lib/rubygems/openssl.rb8
-rw-r--r--lib/rubygems/package.rb5
-rw-r--r--lib/rubygems/package/tar_header.rb2
-rw-r--r--lib/rubygems/package/tar_test_case.rb2
-rw-r--r--lib/rubygems/platform.rb25
-rw-r--r--lib/rubygems/query_utils.rb9
-rw-r--r--lib/rubygems/remote_fetcher.rb3
-rw-r--r--lib/rubygems/request.rb7
-rw-r--r--lib/rubygems/request_set/gem_dependency_api.rb8
-rw-r--r--lib/rubygems/requirement.rb2
-rw-r--r--lib/rubygems/resolver.rb2
-rw-r--r--lib/rubygems/resolver/activation_request.rb10
-rw-r--r--lib/rubygems/resolver/api_specification.rb6
-rw-r--r--lib/rubygems/resolver/conflict.rb2
-rw-r--r--lib/rubygems/resolver/dependency_request.rb2
-rw-r--r--lib/rubygems/resolver/index_specification.rb11
-rw-r--r--lib/rubygems/resolver/installer_set.rb3
-rw-r--r--lib/rubygems/resolver/lock_set.rb2
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo.rb11
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state.rb7
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider.rb1
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph.rb44
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action.rb1
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log.rb13
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag.rb7
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex.rb53
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/errors.rb82
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/gem_metadata.rb3
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider.rb1
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/modules/ui.rb4
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolution.rb671
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/resolver.rb5
-rw-r--r--lib/rubygems/resolver/molinillo/lib/molinillo/state.rb12
-rw-r--r--lib/rubygems/resolver/specification.rb2
-rw-r--r--lib/rubygems/s3_uri_signer.rb2
-rw-r--r--lib/rubygems/security.rb3
-rw-r--r--lib/rubygems/security/policy.rb2
-rw-r--r--lib/rubygems/security/signer.rb2
-rw-r--r--lib/rubygems/server.rb2
-rw-r--r--lib/rubygems/source.rb14
-rw-r--r--lib/rubygems/spec_fetcher.rb2
-rw-r--r--lib/rubygems/specification.rb16
-rw-r--r--lib/rubygems/ssl_certs/rubygems.global.ssl.fastly.net/DigiCertHighAssuranceEVRootCA.pem23
-rw-r--r--lib/rubygems/ssl_certs/rubygems.org/GlobalSignRootCA.pem (renamed from lib/rubygems/ssl_certs/index.rubygems.org/GlobalSignRootCA.pem)0
-rw-r--r--lib/rubygems/stub_specification.rb2
-rw-r--r--lib/rubygems/test_case.rb39
-rw-r--r--lib/rubygems/uri_formatter.rb3
-rw-r--r--lib/rubygems/version_option.rb6
83 files changed, 1124 insertions, 511 deletions
@@ -73,7 +73,7 @@ class Gem::AvailableSet
end
def match_platform!
- @set.reject! {|t| !Gem::Platform.match(t.spec.platform) }
@sorted = nil
self
end
@@ -73,7 +73,7 @@ class Gem::CommandManager
].freeze
ALIAS_COMMANDS = {
- 'i' => 'install'
}.freeze
##
@@ -174,8 +174,8 @@ class Gem::CommandManager
else
cmd_name = args.shift.downcase
cmd = find_command cmd_name
- cmd.invoke_with_build_args args, build_args
cmd.deprecation_warning if cmd.deprecated?
end
end
@@ -61,14 +61,18 @@ Gems can be saved to a specified filename with the output option:
end
def execute
- gem_name = get_one_optional_argument || find_gemspec
- build_gem(gem_name)
end
private
- def find_gemspec
- gemspecs = Dir.glob("*.gemspec").sort
if gemspecs.size > 1
alert_error "Multiple gemspecs found: #{gemspecs}, please specify one"
@@ -78,28 +82,19 @@ Gems can be saved to a specified filename with the output option:
gemspecs.first
end
- def build_gem(gem_name)
- gemspec = File.exist?(gem_name) ? gem_name : "#{gem_name}.gemspec"
-
- if File.exist?(gemspec)
- spec = Gem::Specification.load(gemspec)
-
- if options[:build_path]
- Dir.chdir(File.dirname(gemspec)) do
- spec = Gem::Specification.load(File.basename(gemspec))
- build_package(spec)
- end
- else
- build_package(spec)
- end
else
- alert_error "Gemspec file not found: #{gemspec}"
terminate_interaction(1)
end
end
- def build_package(spec)
if spec
Gem::Package.build(
spec,
@@ -112,4 +107,26 @@ Gems can be saved to a specified filename with the output option:
terminate_interaction 1
end
end
end
@@ -311,4 +311,4 @@ For further reading on signing gems see `ri Gem::Security`.
# It's simple, but is all we need
email =~ /\A.+@.+\z/
end
-end if defined?(OpenSSL::SSL)
@@ -332,6 +332,8 @@ platform.
@command_manager.command_names.each do |cmd_name|
command = @command_manager[cmd_name]
summary =
if command
command.summary
@@ -53,7 +53,7 @@ permission to.
def execute
@host = options[:host]
- sign_in
name = get_one_gem_name
add_owners name, options[:add]
@@ -102,10 +102,18 @@ permission to.
private
def send_owner_request(method, name, owner)
- rubygems_api_request method, "api/v1/gems/#{name}/owners" do |request|
request.set_form_data 'email' => owner
request.add_field "Authorization", api_key
request.add_field "OTP", options[:otp] if options[:otp]
end
end
end
@@ -170,7 +170,7 @@ extensions will be restored.
:install_dir => spec.base_dir,
:env_shebang => env_shebang,
:build_args => spec.build_args,
- :bin_dir => bin_dir
}
if options[:only_executables]
@@ -61,7 +61,7 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
options[:host]
end
- sign_in @host
send_gem(gem_name)
end
@@ -86,7 +86,7 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
private
def send_push_request(name, args)
- rubygems_api_request(*args) do |request|
request.body = Gem.read_binary name
request.add_field "Content-Length", request.body.size
request.add_field "Content-Type", "application/octet-stream"
@@ -100,7 +100,11 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
[
gem_metadata["default_gem_server"],
- gem_metadata["allowed_push_host"]
]
end
end
@@ -9,6 +9,14 @@ class Gem::Commands::QueryCommand < Gem::Command
include Gem::QueryUtils
def initialize(name = 'query',
summary = 'Query gem information in local or remote repositories')
super name, summary,
@@ -23,4 +31,13 @@ class Gem::Commands::QueryCommand < Gem::Command
add_query_options
end
end
@@ -1,8 +1,12 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/server'
class Gem::Commands::ServerCommand < Gem::Command
def initialize
super 'server', 'Documentation and gem repository HTTP server',
:port => 8808, :gemdir => [], :daemon => false
@@ -322,13 +322,10 @@ By default, this RubyGems will install gem as:
libs.each do |tool, path|
say "Installing #{tool}" if @verbose
- lib_files = rb_files_in path
- lib_files.concat(bundler_template_files) if tool == 'Bundler'
-
- pem_files = pem_files_in path
Dir.chdir path do
- install_file_list(lib_files + pem_files, lib_dir)
end
end
end
@@ -394,10 +391,6 @@ By default, this RubyGems will install gem as:
specs_dir = File.join(options[:destdir], specs_dir) unless Gem.win_platform?
mkdir_p specs_dir, :mode => 0755
- # Workaround for non-git environment.
- gemspec = File.open('bundler/bundler.gemspec', 'rb'){|f| f.read.gsub(/`git ls-files -z`/, "''") }
- File.open('bundler/bundler.gemspec', 'w'){|f| f.write gemspec }
-
bundler_spec = Gem::Specification.load("bundler/bundler.gemspec")
bundler_spec.files = Dir.chdir("bundler") { Dir["{*.md,{lib,exe,man}/**/*}"] }
bundler_spec.executables -= %w[bundler bundle_ruby]
@@ -518,44 +511,24 @@ By default, this RubyGems will install gem as:
[lib_dir, bin_dir]
end
- def pem_files_in(dir)
- Dir.chdir dir do
- Dir[File.join('**', '*pem')]
- end
- end
-
- def rb_files_in(dir)
Dir.chdir dir do
- Dir[File.join('**', '*rb')]
end
end
# for installation of bundler as default gems
def bundler_man1_files_in(dir)
Dir.chdir dir do
- Dir['bundle*.1{,.txt,.ronn}']
end
end
# for installation of bundler as default gems
def bundler_man5_files_in(dir)
Dir.chdir dir do
- Dir['gemfile.5{,.txt,.ronn}']
- end
- end
-
- def bundler_template_files
- Dir.chdir "bundler/lib" do
- Dir.glob(File.join('bundler', 'templates', '**', '*'), File::FNM_DOTMATCH).
- select{|f| !File.directory?(f) }
- end
- end
-
- # for cleanup old bundler files
- def template_files_in(dir)
- Dir.chdir dir do
- Dir.glob(File.join('templates', '**', '*'), File::FNM_DOTMATCH).
- select{|f| !File.directory?(f) }
end
end
@@ -595,11 +568,9 @@ abort "#{deprecation_message}"
lib_dirs = { File.join(lib_dir, 'rubygems') => 'lib/rubygems' }
lib_dirs[File.join(lib_dir, 'bundler')] = 'bundler/lib/bundler'
lib_dirs.each do |old_lib_dir, new_lib_dir|
- lib_files = rb_files_in(new_lib_dir)
- lib_files.concat(template_files_in(new_lib_dir)) if new_lib_dir =~ /bundler/
- old_lib_files = rb_files_in(old_lib_dir)
- old_lib_files.concat(template_files_in(old_lib_dir)) if old_lib_dir =~ /bundler/
to_remove = old_lib_files - lib_files
@@ -617,16 +588,25 @@ abort "#{deprecation_message}"
def remove_old_man_files(man_dir)
man_dirs = { man_dir => "bundler/man" }
man_dirs.each do |old_man_dir, new_man_dir|
- ["1", "5"].each do |section|
- man_files = send(:"bundler_man#{section}_files_in", new_man_dir)
- old_man_dir_with_section = "#{old_man_dir}/man#{section}"
- old_man_files = send(:"bundler_man#{section}_files_in", old_man_dir_with_section)
- man_to_remove = old_man_files - man_files
- remove_file_list(man_to_remove, old_man_dir_with_section)
- end
end
end
@@ -34,6 +34,10 @@ class Gem::Commands::SourcesCommand < Gem::Command
options[:update] = value
end
add_proxy_option
end
@@ -71,7 +75,7 @@ class Gem::Commands::SourcesCommand < Gem::Command
Do you want to add this source?
QUESTION
- terminate_interaction 1 unless ask_yes_no question
end
end
@@ -86,7 +90,7 @@ https://rubygems.org is recommended for security over #{uri}
Do you want to add this insecure source?
QUESTION
- terminate_interaction 1 unless ask_yes_no question
end
end
@@ -126,6 +126,12 @@ Specific fields in the specification can be extracted in YAML format:
terminate_interaction 1
end
unless options[:all]
specs = [specs.max_by {|s| s.version }]
end
@@ -47,7 +47,7 @@ data you will need to change them immediately and yank your gem.
def execute
@host = options[:host]
- sign_in @host
version = get_version_from_requirements(options[:version])
platform = get_platform_from_requirements(options)
@@ -72,7 +72,7 @@ data you will need to change them immediately and yank your gem.
def yank_api_request(method, version, platform, api)
name = get_one_gem_name
- response = rubygems_api_request(method, api, host) do |request|
request.add_field("Authorization", api_key)
request.add_field("OTP", options[:otp]) if options[:otp]
@@ -93,7 +93,7 @@ data you will need to change them immediately and yank your gem.
nil
end
- def get_platform_from_requirements(requirements)
- Gem.platforms[1].to_s if requirements.key? :added_platform
end
end
@@ -17,6 +17,8 @@ module Kernel
private :gem_original_require
end
##
# When RubyGems is required, Kernel#require is replaced with our own which
# is capable of loading gems on demand.
@@ -166,6 +168,7 @@ module Kernel
end
end
end
private :require
@@ -1,12 +1,12 @@
# frozen_string_literal: true
# `uplevel` keyword argument of Kernel#warn is available since ruby 2.5.
-if RUBY_VERSION >= "2.5"
module Kernel
rubygems_path = "#{__dir__}/" # Frames to be skipped start with this path.
- original_warn = method(:warn)
remove_method :warn
@@ -17,9 +17,9 @@ if RUBY_VERSION >= "2.5"
module_function define_method(:warn) {|*messages, **kw|
unless uplevel = kw[:uplevel]
if Gem.java_platform?
- return original_warn.call(*messages)
else
- return original_warn.call(*messages, **kw)
end
end
@@ -45,11 +45,10 @@ if RUBY_VERSION >= "2.5"
end
end
end
- uplevel = start
end
- kw[:uplevel] = uplevel
- original_warn.call(*messages, **kw)
}
end
end
@@ -38,13 +38,13 @@ module Gem
[
File.dirname(RbConfig::CONFIG['sitedir']),
'Gems',
- RbConfig::CONFIG['ruby_version']
]
else
[
RbConfig::CONFIG['rubylibprefix'],
'gems',
- RbConfig::CONFIG['ruby_version']
]
end
@@ -281,7 +281,7 @@ class Gem::Dependency
if platform_only
matches.reject! do |spec|
- spec.nil? || !Gem::Platform.match(spec.platform)
end
end
@@ -27,7 +27,7 @@ class Gem::DependencyInstaller
:wrappers => true,
:build_args => nil,
:build_docs_in_background => false,
- :install_as_default => false
}.freeze
##
@@ -283,10 +283,9 @@ class Gem::DependencyInstaller
request_set.development_shallow = @dev_shallow
request_set.soft_missing = @force
request_set.prerelease = @prerelease
- request_set.remote = false unless consider_remote?
installer_set = Gem::Resolver::InstallerSet.new @domain
- installer_set.ignore_installed = @only_install_dir
if consider_local?
if dep_or_name =~ /\.gem$/ and File.file? dep_or_name
@@ -307,6 +306,7 @@ class Gem::DependencyInstaller
dependency =
if spec = installer_set.local?(dep_or_name)
Gem::Dependency.new spec.name, version
elsif String === dep_or_name
Gem::Dependency.new dep_or_name, version
@@ -321,6 +321,7 @@ class Gem::DependencyInstaller
installer_set.add_always_install dependency
request_set.always_install = installer_set.always_install
if @ignore_dependencies
installer_set.ignore_dependencies = true
@@ -10,14 +10,6 @@ require_relative '../user_interaction'
class Gem::Ext::Builder
include Gem::UserInteraction
- ##
- # The builder shells-out to run various commands after changing the
- # directory. This means multiple installations cannot be allowed to build
- # extensions in parallel as they may change each other's directories leading
- # to broken extensions or failed installations.
-
- CHDIR_MUTEX = Mutex.new # :nodoc:
-
attr_accessor :build_args # :nodoc:
def self.class_name
@@ -25,8 +17,8 @@ class Gem::Ext::Builder
$1.downcase
end
- def self.make(dest_path, results)
- unless File.exist? 'Makefile'
raise Gem::InstallError, 'Makefile not found'
end
@@ -44,32 +36,32 @@ class Gem::Ext::Builder
cmd = [
make_program,
destdir,
- target
].join(' ').rstrip
begin
- run(cmd, results, "make #{target}".rstrip)
rescue Gem::InstallError
raise unless target == 'clean' # ignore clean failure
end
end
end
- def self.run(command, results, command_name = nil)
verbose = Gem.configuration.really_verbose
begin
rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], nil
if verbose
- puts("current directory: #{Dir.pwd}")
p(command)
end
- results << "current directory: #{Dir.pwd}"
results << (command.respond_to?(:shelljoin) ? command.shelljoin : command)
require "open3"
# Set $SOURCE_DATE_EPOCH for the subprocess.
env = {'SOURCE_DATE_EPOCH' => Gem.source_date_epoch_string}
- output, status = Open3.capture2e(env, *command)
if verbose
puts output
else
@@ -161,22 +153,10 @@ EOF
begin
FileUtils.mkdir_p dest_path
- CHDIR_MUTEX.synchronize do
- pwd = Dir.getwd
- Dir.chdir extension_dir
- begin
- results = builder.build(extension, dest_path,
- results, @build_args, lib_dir)
-
- verbose { results.join("\n") }
- ensure
- begin
- Dir.chdir pwd
- rescue SystemCallError
- Dir.chdir dest_path
- end
- end
- end
write_gem_make_out results.join "\n"
rescue => e
@@ -201,6 +181,7 @@ EOF
dest_path = @spec.extension_dir
FileUtils.rm_f @spec.gem_build_complete_path
@spec.extensions.each do |extension|
@@ -2,15 +2,15 @@
require_relative '../command'
class Gem::Ext::CmakeBuilder < Gem::Ext::Builder
- def self.build(extension, dest_path, results, args=[], lib_dir=nil)
- unless File.exist?('Makefile')
cmd = "cmake . -DCMAKE_INSTALL_PREFIX=#{dest_path}"
cmd << " #{Gem::Command.build_args.join ' '}" unless Gem::Command.build_args.empty?
- run cmd, results
end
- make dest_path, results
results
end
@@ -6,15 +6,15 @@
#++
class Gem::Ext::ConfigureBuilder < Gem::Ext::Builder
- def self.build(extension, dest_path, results, args=[], lib_dir=nil)
- unless File.exist?('Makefile')
cmd = "sh ./configure --prefix=#{dest_path}"
cmd << " #{args.join ' '}" unless args.empty?
- run cmd, results
end
- make dest_path, results
results
end
@@ -8,11 +8,11 @@
require 'shellwords'
class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
- def self.build(extension, dest_path, results, args=[], lib_dir=nil)
require 'fileutils'
require 'tempfile'
- tmp_dest = Dir.mktmpdir(".gem.", ".")
# Some versions of `mktmpdir` return absolute paths, which will break make
# if the paths contain spaces. However, on Ruby 1.9.x on Windows, relative
@@ -23,9 +23,9 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
# spaces do not work.
#
# Details: https://.com/rubygems/rubygems/issues/977#issuecomment-171544940
- tmp_dest = get_relative_path(tmp_dest)
- Tempfile.open %w[siteconf .rb], "." do |siteconf|
siteconf.puts "require 'rbconfig'"
siteconf.puts "dest_path = #{tmp_dest.dump}"
%w[sitearchdir sitelibdir].each do |dir|
@@ -38,19 +38,22 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
destdir = ENV["DESTDIR"]
begin
cmd = Gem.ruby.shellsplit << "-I" << File.expand_path("../../..", __FILE__) <<
- "-r" << get_relative_path(siteconf.path) << File.basename(extension)
cmd.push(*args)
begin
- run(cmd, results) do |s, r|
- if File.exist? 'mkmf.log'
unless s.success?
r << "To see why this extension failed to compile, please check" \
" the mkmf.log which can be found here:\n"
r << " " + File.join(dest_path, 'mkmf.log') + "\n"
end
- FileUtils.mv 'mkmf.log', dest_path
end
end
siteconf.unlink
@@ -58,18 +61,20 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
ENV["DESTDIR"] = nil
- make dest_path, results
if tmp_dest
# TODO remove in RubyGems 3
if Gem.install_extension_in_lib and lib_dir
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, :remove_destination => true
end
- FileUtils::Entry_.new(tmp_dest).traverse do |ent|
destent = ent.class.new(dest_path, ent.rel)
destent.exist? or FileUtils.mv(ent.path, destent.path)
end
@@ -87,8 +92,8 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
private
- def self.get_relative_path(path)
- path[0..Dir.pwd.length - 1] = '.' if path.start_with?(Dir.pwd)
path
end
end
@@ -8,9 +8,9 @@
require "shellwords"
class Gem::Ext::RakeBuilder < Gem::Ext::Builder
- def self.build(extension, dest_path, results, args=[], lib_dir=nil)
if File.basename(extension) =~ /mkrf_conf/i
- run([Gem.ruby, File.basename(extension), *args], results)
end
rake = ENV['rake']
@@ -26,7 +26,7 @@ class Gem::Ext::RakeBuilder < Gem::Ext::Builder
end
rake_args = ["RUBYARCHDIR=#{dest_path}", "RUBYLIBDIR=#{dest_path}", *args]
- run(rake + rake_args, results)
results
end
@@ -8,10 +8,12 @@ require 'rubygems/text'
module Gem::GemcutterUtilities
ERROR_CODE = 1
include Gem::Text
attr_writer :host
##
# Add the --key option
@@ -72,7 +74,7 @@ module Gem::GemcutterUtilities
#
# If +allowed_push_host+ metadata is present, then it will only allow that host.
- def rubygems_api_request(method, path, host = nil, allowed_push_host = nil, &block)
require 'net/http'
self.host = host if host
@@ -95,11 +97,19 @@ module Gem::GemcutterUtilities
request_method = Net::HTTP.const_get method.to_s.capitalize
response = Gem::RemoteFetcher.fetcher.request(uri, request_method, &block)
- return response unless mfa_unauthorized?(response)
- Gem::RemoteFetcher.fetcher.request(uri, request_method) do |req|
- req.add_field "OTP", get_otp
- block.call(req)
end
end
@@ -112,19 +122,37 @@ module Gem::GemcutterUtilities
ask 'Code: '
end
##
# Signs in with the RubyGems API at +sign_in_host+ and sets the rubygems API
# key.
- def sign_in(sign_in_host = nil)
sign_in_host ||= self.host
return if api_key
- pretty_host = if Gem::DEFAULT_HOST == sign_in_host
- 'RubyGems.org'
- else
- sign_in_host
- end
say "Enter your #{pretty_host} credentials."
say "Don't have an account yet? " +
@@ -134,14 +162,18 @@ module Gem::GemcutterUtilities
password = ask_for_password "Password: "
say "\n"
- response = rubygems_api_request(:get, "api/v1/api_key",
- sign_in_host) do |request|
request.basic_auth email, password
request.add_field "OTP", options[:otp] if options[:otp]
end
with_response response do |resp|
- say "Signed in."
set_api_key host, resp.body
end
end
@@ -195,4 +227,48 @@ module Gem::GemcutterUtilities
end
end
end
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require 'rubygems'
require 'rubygems/package'
-require 'time'
require 'tmpdir'
##
@@ -122,10 +122,10 @@ module Gem::InstallUpdateOptions
options[:minimal_deps] = true
end
- add_option(:"Install/Update", "--minimal-deps",
"Don't upgrade any dependencies that already",
"meet version requirements") do |value, options|
- options[:minimal_deps] = true
end
add_option(:"Install/Update", "--[no-]post-install-message",
@@ -12,7 +12,6 @@ require 'rubygems/deprecate'
require 'rubygems/package'
require 'rubygems/ext'
require 'rubygems/user_interaction'
-require 'fileutils'
##
# The installer installs the files contained in the .gem into the Gem.home.
@@ -433,7 +432,7 @@ class Gem::Installer
#
def default_spec_file
- File.join Gem.default_specifications_dir, "#{spec.full_name}.gemspec"
end
##
@@ -492,7 +491,11 @@ class Gem::Installer
mode = File.stat(bin_path).mode
dir_mode = options[:prog_mode] || (mode | 0111)
- FileUtils.chmod dir_mode, bin_path unless dir_mode == mode
check_executable_overwrite filename
@@ -527,6 +530,7 @@ class Gem::Installer
def generate_bin_script(filename, bindir)
bin_script_path = File.join bindir, formatted_program_filename(filename)
FileUtils.rm_f bin_script_path # prior install may have been --no-wrappers
File.open bin_script_path, 'wb', 0755 do |file|
@@ -670,7 +674,7 @@ class Gem::Installer
:env_shebang => false,
:force => false,
:only_install_dir => false,
- :post_install_message => true
}.merge options
@env_shebang = options[:env_shebang]
@@ -693,11 +697,10 @@ class Gem::Installer
@build_args = options[:build_args] || Gem::Command.build_args
unless @build_root.nil?
- require 'pathname'
- @build_root = Pathname.new(@build_root).expand_path
- @bin_dir = File.join(@build_root, options[:bin_dir] || Gem.bindir(@gem_home))
- @gem_home = File.join(@build_root, @gem_home)
- alert_warning "You build with buildroot.\n Build root: #{@build_root}\n Bin dir: #{@bin_dir}\n Gem home: #{@gem_home}"
end
end
@@ -108,9 +108,9 @@ class Gem::InstallerTestCase < Gem::TestCase
#
# And returns a Gem::Installer for the @spec that installs into @gemhome
- def setup_base_installer
@gem = setup_base_gem
- util_installer @spec, @gemhome
end
##
@@ -182,7 +182,7 @@ class Gem::InstallerTestCase < Gem::TestCase
# lib/code.rb
# ext/a/mkrf_conf.rb
- def util_setup_gem(ui = @ui)
@spec.files << File.join('lib', 'code.rb')
@spec.extensions << File.join('ext', 'a', 'mkrf_conf.rb')
@@ -214,17 +214,18 @@ class Gem::InstallerTestCase < Gem::TestCase
end
end
- Gem::Installer.at @gem
end
##
# Creates an installer for +spec+ that will install into +gem_home+. If
# +user+ is true a user-install will be performed.
- def util_installer(spec, gem_home, user=false)
Gem::Installer.at(spec.cache_file,
:install_dir => gem_home,
- :user_install => user)
end
@@symlink_supported = nil
@@ -59,7 +59,7 @@ class Gem::NameTuple
# Indicate if this NameTuple matches the current platform.
def match_platform?
- Gem::Platform.match @platform
end
##
@@ -1,7 +1,7 @@
# frozen_string_literal: true
-begin
- require "openssl"
-rescue LoadError => e
- raise unless e.path == 'openssl'
end
@@ -44,7 +44,6 @@
require "rubygems"
require 'rubygems/security'
require 'rubygems/user_interaction'
-require 'zlib'
class Gem::Package
include Gem::UserInteraction
@@ -186,6 +185,8 @@ class Gem::Package
# Creates a new package that will read or write to the file +gem+.
def initialize(gem, security_policy) # :notnew:
@gem = gem
@build_time = Gem.source_date_epoch
@@ -297,7 +298,7 @@ class Gem::Package
setup_signer(
signer_options: {
- expiration_length_days: Gem.configuration.cert_expiration_length_days
}
)
@@ -229,7 +229,7 @@ class Gem::Package::TarHeader
gname,
oct(devmajor, 7),
oct(devminor, 7),
- prefix
]
header = header.pack PACK_FORMAT
@@ -90,7 +90,7 @@ class Gem::Package::TarTestCase < Gem::TestCase
ASCIIZ("wheel", 32), # char gname[32]; ASCIIZ
Z(to_oct(0, 7)), # char devmajor[8]; 0 padded, octal, null
Z(to_oct(0, 7)), # char devminor[8]; 0 padded, octal, null
- ASCIIZ(dname, 155) # char prefix[155]; ASCII + (Z unless filled)
]
h = arr.join
@@ -9,11 +9,7 @@ require "rubygems/deprecate"
class Gem::Platform
@local = nil
- attr_accessor :cpu
-
- attr_accessor :os
-
- attr_accessor :version
def self.local
arch = RbConfig::CONFIG['arch']
@@ -22,18 +18,33 @@ class Gem::Platform
end
def self.match(platform)
- Gem.platforms.any? do |local_platform|
platform.nil? or
local_platform == platform or
(local_platform != Gem::Platform::RUBY and local_platform =~ platform)
end
end
def self.installable?(spec)
if spec.respond_to? :installable_platform?
spec.installable_platform?
else
- match spec.platform
end
end
@@ -57,15 +57,6 @@ module Gem::QueryUtils
"--local --name-matches // --no-details --versions --no-installed"
end
- def description # :nodoc:
- <<-EOF
-The query command is the basis for the list and search commands.
-
-You should really use the list and search commands instead. This command
-is too hard to use.
- EOF
- end
-
def execute
gem_names = Array(options[:name])
@@ -78,7 +78,6 @@ class Gem::RemoteFetcher
def initialize(proxy=nil, dns=nil, headers={})
require 'net/http'
require 'stringio'
- require 'time'
require 'uri'
Socket.do_not_reverse_lookup = true
@@ -263,7 +262,7 @@ class Gem::RemoteFetcher
rescue Timeout::Error
raise UnknownHostError.new('timed out', uri)
rescue IOError, SocketError, SystemCallError,
- *(OpenSSL::SSL::SSLError if defined?(OpenSSL)) => e
if e.message =~ /getaddrinfo/
raise UnknownHostError.new('no such name', uri)
else
@@ -1,6 +1,5 @@
# frozen_string_literal: true
require 'net/http'
-require 'time'
require 'rubygems/user_interaction'
class Gem::Request
@@ -45,7 +44,8 @@ class Gem::Request
end
def self.configure_connection_for_https(connection, cert_files)
- require 'openssl'
connection.use_ssl = true
connection.verify_mode =
Gem.configuration.ssl_verify_mode || OpenSSL::SSL::VERIFY_PEER
@@ -125,7 +125,7 @@ class Gem::Request
def connection_for(uri)
@connection_pool.checkout
- rescue defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : Errno::EHOSTDOWN,
Errno::EHOSTDOWN => e
raise Gem::RemoteFetcher::FetchError.new(e.message, uri)
end
@@ -143,6 +143,7 @@ class Gem::Request
request.add_field 'Keep-Alive', '30'
if @last_modified
request.add_field 'If-Modified-Since', @last_modified.httpdate
end
@@ -88,7 +88,7 @@ class Gem::RequestSet::GemDependencyAPI
:truffleruby => Gem::Platform::RUBY,
:x64_mingw => x64_mingw,
:x64_mingw_20 => x64_mingw,
- :x64_mingw_21 => x64_mingw
}.freeze
gt_eq_0 = Gem::Requirement.new '>= 0'
@@ -379,7 +379,7 @@ class Gem::RequestSet::GemDependencyAPI
Gem::Requirement.create requirements
end
- return unless gem_platforms options
groups = gem_group name, options
@@ -532,7 +532,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
# Handles the platforms: option from +options+. Returns true if the
# platform matches the current platform.
- def gem_platforms(options) # :nodoc:
platform_names = Array(options.delete :platform)
platform_names.concat Array(options.delete :platforms)
platform_names.concat @current_platforms if @current_platforms
@@ -543,7 +543,7 @@ Gem dependencies file #{@path} includes git reference for both ref/branch and ta
raise ArgumentError, "unknown platform #{platform_name.inspect}" unless
platform = PLATFORM_MAP[platform_name]
- next false unless Gem::Platform.match platform
if engines = ENGINE_MAP[platform_name]
next false unless engines.include? Gem.ruby_engine
@@ -16,7 +16,7 @@ class Gem::Requirement
"<" => lambda {|v, r| v < r },
">=" => lambda {|v, r| v >= r },
"<=" => lambda {|v, r| v <= r },
- "~>" => lambda {|v, r| v >= r && v.release < r.bump }
}.freeze
SOURCE_SET_REQUIREMENT = Struct.new(:for_lockfile).new "!" # :nodoc:
@@ -281,7 +281,7 @@ class Gem::Resolver
amount_constrained(dependency),
conflicts[name] ? 0 : 1,
activated.vertex_named(name).payload ? 0 : search_for(dependency).count,
- i # for stable sort
]
end
end
@@ -28,12 +28,20 @@ class Gem::Resolver::ActivationRequest
when Gem::Specification
@spec == other
when Gem::Resolver::ActivationRequest
- @spec == other.spec && @request == other.request
else
false
end
end
##
# Is this activation request for a development dependency?
@@ -46,6 +46,10 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
@dependencies == other.dependencies
end
def fetch_development_dependencies # :nodoc:
spec = source.fetch_spec Gem::NameTuple.new @name, @version, @platform
@@ -53,7 +57,7 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
end
def installable_platform? # :nodoc:
- Gem::Platform.match @platform
end
def pretty_print(q) # :nodoc:
@@ -85,7 +85,7 @@ class Gem::Resolver::Conflict
activated, requirement,
request_path(@activated).reverse.join(", depends on\n "),
request_path(@failed_dep).reverse.join(", depends on\n "),
- matching,
]
end
@@ -28,7 +28,7 @@ class Gem::Resolver::DependencyRequest
when Gem::Dependency
@dependency == other
when Gem::Resolver::DependencyRequest
- @dependency == other.dependency && @requester == other.requester
else
false
end
@@ -33,6 +33,17 @@ class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
spec.dependencies
end
def inspect # :nodoc:
'#<%s %s source %s>' % [self.class, full_name, @source]
end
@@ -32,7 +32,6 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
super()
@domain = domain
- @remote = consider_remote?
@f = Gem::SpecFetcher.fetcher
@@ -170,7 +169,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
always_install = @always_install.map {|s| s.full_name }
'#<%s domain: %s specs: %p always install: %p>' % [
- self.class, @domain, @specs.keys, always_install,
]
end
@@ -28,7 +28,7 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set
def add(name, version, platform) # :nodoc:
version = Gem::Version.new version
specs = [
- Gem::Resolver::LockSpecification.new(self, name, version, @sources, platform)
]
@specs.concat specs
@@ -1,9 +1,10 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/gem_metadata'
-require 'rubygems/resolver/molinillo/lib/molinillo/errors'
-require 'rubygems/resolver/molinillo/lib/molinillo/resolver'
-require 'rubygems/resolver/molinillo/lib/molinillo/modules/ui'
-require 'rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider'
# Gem::Resolver::Molinillo is a generic dependency resolution algorithm.
module Gem::Resolver::Molinillo
@@ -1,4 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# @!visibility private
module Delegates
@@ -45,6 +46,12 @@ module Gem::Resolver::Molinillo
current_state = state || Gem::Resolver::Molinillo::ResolutionState.empty
current_state.conflicts
end
end
end
end
@@ -1,4 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
module Delegates
# Delegates all {Gem::Resolver::Molinillo::SpecificationProvider} methods to a
@@ -1,9 +1,10 @@
# frozen_string_literal: true
require 'set'
require 'tsort'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/log'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/vertex'
module Gem::Resolver::Molinillo
# A directed acyclic graph that is tuned to hold named dependencies
@@ -123,6 +124,7 @@ module Gem::Resolver::Molinillo
dot.join("\n")
end
# @return [Boolean] whether the two dependency graphs are equal, determined
# by a recursive traversal of each {#root_vertices} and its
# {Vertex#successors}
@@ -147,8 +149,8 @@ module Gem::Resolver::Molinillo
vertex = add_vertex(name, payload, root)
vertex.explicit_requirements << requirement if root
parent_names.each do |parent_name|
- parent_node = vertex_named(parent_name)
- add_edge(parent_node, vertex, requirement)
end
vertex
end
@@ -189,7 +191,7 @@ module Gem::Resolver::Molinillo
# @return [Edge] the added edge
def add_edge(origin, destination, requirement)
if destination.path_to?(origin)
- raise CircularDependencyError.new([origin, destination])
end
add_edge_no_circular(origin, destination, requirement)
end
@@ -218,5 +220,37 @@ module Gem::Resolver::Molinillo
def add_edge_no_circular(origin, destination, requirement)
log.add_edge_no_circular(self, origin.name, destination.name, requirement)
end
end
end
@@ -1,4 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
class DependencyGraph
# An action that modifies a {DependencyGraph} that is reversible.
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
@@ -1,10 +1,11 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_edge_no_circular'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/add_vertex'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/delete_edge'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/detach_vertex_named'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/set_payload'
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/tag'
module Gem::Resolver::Molinillo
class DependencyGraph
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph/action'
module Gem::Resolver::Molinillo
class DependencyGraph
# @!visibility private
@@ -13,11 +14,11 @@ module Gem::Resolver::Molinillo
end
# (see Action#up)
- def up(_graph)
end
# (see Action#down)
- def down(_graph)
end
# @!group Tag
@@ -1,4 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
class DependencyGraph
# A vertex in a {DependencyGraph} that encapsulates a {#name} and a
@@ -32,7 +33,7 @@ module Gem::Resolver::Molinillo
# @return [Array<Object>] all of the requirements that required
# this vertex
def requirements
- incoming_edges.map(&:requirement) + explicit_requirements
end
# @return [Array<Edge>] the edges of {#graph} that have `self` as their
@@ -49,14 +50,25 @@ module Gem::Resolver::Molinillo
incoming_edges.map(&:origin)
end
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is a
# {#descendent?}
def recursive_predecessors
- vertices = predecessors
- vertices += vertices.map(&:recursive_predecessors).flatten(1)
- vertices.uniq!
vertices
end
# @return [Array<Vertex>] the vertices of {#graph} that have an edge with
# `self` as their {Edge#origin}
@@ -64,14 +76,25 @@ module Gem::Resolver::Molinillo
outgoing_edges.map(&:destination)
end
- # @return [Array<Vertex>] the vertices of {#graph} where `self` is an
# {#ancestor?}
def recursive_successors
- vertices = successors
- vertices += vertices.map(&:recursive_successors).flatten(1)
- vertices.uniq!
vertices
end
# @return [String] a string suitable for debugging
def inspect
@@ -107,11 +130,21 @@ module Gem::Resolver::Molinillo
# dependency graph?
# @return true iff there is a path following edges within this {#graph}
def path_to?(other)
- equal?(other) || successors.any? { |v| v.path_to?(other) }
end
alias descendent? path_to?
# Is there a path from `other` to `self` following edges in the
# dependency graph?
# @return true iff there is a path following edges within this {#graph}
@@ -1,4 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# An error that occurred during the resolution process
class ResolverError < StandardError; end
@@ -17,7 +18,7 @@ module Gem::Resolver::Molinillo
# @param [Array<Object>] required_by @see {#required_by}
def initialize(dependency, required_by = [])
@dependency = dependency
- @required_by = required_by
super()
end
@@ -41,11 +42,11 @@ module Gem::Resolver::Molinillo
attr_reader :dependencies
# Initializes a new error with the given circular vertices.
- # @param [Array<DependencyGraph::Vertex>] nodes the nodes in the dependency
# that caused the error
- def initialize(nodes)
- super "There is a circular dependency between #{nodes.map(&:name).join(' and ')}"
- @dependencies = nodes.map(&:payload).to_set
end
end
@@ -55,11 +56,16 @@ module Gem::Resolver::Molinillo
# resolution to fail
attr_reader :conflicts
# Initializes a new error with the given version conflicts.
# @param [{String => Resolution::Conflict}] conflicts see {#conflicts}
- def initialize(conflicts)
pairs = []
- conflicts.values.flatten.map(&:requirements).flatten.each do |conflicting|
conflicting.each do |source, conflict_requirements|
conflict_requirements.each do |c|
pairs << [c, source]
@@ -69,7 +75,69 @@ module Gem::Resolver::Molinillo
super "Unable to satisfy the following requirements:\n\n" \
"#{pairs.map { |r, d| "- `#{r}` required by `#{d}`" }.join("\n")}"
@conflicts = conflicts
end
end
end
@@ -1,5 +1,6 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# The version of Gem::Resolver::Molinillo.
- VERSION = '0.5.7'.freeze
end
@@ -1,4 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# Provides information about specifcations and dependencies to the resolver,
# allowing the {Resolver} class to remain generic while still providing power
@@ -1,4 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# Conveys information about the resolution process to a user.
module UI
@@ -48,7 +49,8 @@ module Gem::Resolver::Molinillo
if debug?
debug_info = yield
debug_info = debug_info.inspect unless debug_info.is_a?(String)
- output.puts debug_info.split("\n").map { |s| ' ' * depth + s }
end
end
@@ -1,4 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
class Resolver
# A specific resolution from a given {Resolver}
@@ -8,22 +9,125 @@ module Gem::Resolver::Molinillo
# @attr [{String,Nil=>[Object]}] requirements the requirements that caused the conflict
# @attr [Object, nil] existing the existing spec that was in conflict with
# the {#possibility}
- # @attr [Object] possibility the spec that was unable to be activated due
- # to a conflict
# @attr [Object] locked_requirement the relevant locking requirement.
# @attr [Array<Array<Object>>] requirement_trees the different requirement
# trees that led to every requirement for the conflicting name.
# @attr [{String=>Object}] activated_by_name the already-activated specs.
Conflict = Struct.new(
:requirement,
:requirements,
:existing,
- :possibility,
:locked_requirement,
:requirement_trees,
- :activated_by_name
)
# @return [SpecificationProvider] the provider that knows about
# dependencies, requirements, specifications, versions, etc.
attr_reader :specification_provider
@@ -64,7 +168,7 @@ module Gem::Resolver::Molinillo
start_resolution
while state
- break unless state.requirements.any? || state.requirement
indicate_progress
if state.respond_to?(:pop_possibility_state) # DependencyState
debug(depth) { "Creating possibility state for #{requirement} (#{possibilities.count} remaining)" }
@@ -78,7 +182,7 @@ module Gem::Resolver::Molinillo
process_topmost_state
end
- activated.freeze
ensure
end_resolution
end
@@ -103,12 +207,25 @@ module Gem::Resolver::Molinillo
def start_resolution
@started_at = Time.now
- handle_missing_or_push_dependency_state(initial_state)
debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" }
resolver_ui.before_resolution
end
# Ends the resolution process
# @return [void]
def end_resolution
@@ -121,11 +238,11 @@ module Gem::Resolver::Molinillo
debug { 'Activated: ' + Hash[activated.vertices.select { |_n, v| v.payload }].keys.join(', ') } if state
end
- require 'rubygems/resolver/molinillo/lib/molinillo/state'
- require 'rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider'
- require 'rubygems/resolver/molinillo/lib/molinillo/delegates/resolution_state'
- require 'rubygems/resolver/molinillo/lib/molinillo/delegates/specification_provider'
include Gem::Resolver::Molinillo::Delegates::ResolutionState
include Gem::Resolver::Molinillo::Delegates::SpecificationProvider
@@ -136,9 +253,12 @@ module Gem::Resolver::Molinillo
if possibility
attempt_to_activate
else
- create_conflict if state.is_a? PossibilityState
- unwind_for_conflict until possibility && state.is_a?(DependencyState)
end
end
# @return [Object] the current possibility that the resolution is trying
@@ -153,63 +273,292 @@ module Gem::Resolver::Molinillo
states.last
end
- # Creates the initial state for the resolution, based upon the
# {#requested} dependencies
- # @return [DependencyState] the initial state for the resolution
- def initial_state
graph = DependencyGraph.new.tap do |dg|
- original_requested.each { |r| dg.add_vertex(name_for(r), nil, true).tap { |v| v.explicit_requirements << r } }
dg.tag(:initial_state)
end
- requirements = sort_dependencies(original_requested, graph, {})
- initial_requirement = requirements.shift
- DependencyState.new(
- initial_requirement && name_for(initial_requirement),
- requirements,
- graph,
- initial_requirement,
- initial_requirement && search_for(initial_requirement),
- 0,
- {}
- )
end
# Unwinds the states stack because a conflict has been encountered
# @return [void]
def unwind_for_conflict
- debug(depth) { "Unwinding for conflict: #{requirement} to #{state_index_for_unwind / 2}" }
conflicts.tap do |c|
- sliced_states = states.slice!((state_index_for_unwind + 1)..-1)
- raise VersionConflict.new(c) unless state
activated.rewind_to(sliced_states.first || :initial_state) if sliced_states
state.conflicts = c
index = states.size - 1
@parents_of.each { |_, a| a.reject! { |i| i >= index } }
end
end
- # @return [Integer] The index to which the resolution should unwind in the
- # case of conflict.
- def state_index_for_unwind
- current_requirement = requirement
- existing_requirement = requirement_for_existing_name(name)
- index = -1
- [current_requirement, existing_requirement].each do |r|
- until r.nil?
- current_state = find_state_for(r)
- if state_any?(current_state)
- current_index = states.index(current_state)
- index = current_index if current_index > index
- break
end
- r = parent_of(r)
end
end
- index
end
# @return [Object] the requirement that led to `requirement` being added
# to the list of requirements.
def parent_of(requirement)
@@ -219,29 +568,27 @@ module Gem::Resolver::Molinillo
parent_state.requirement
end
# @return [Object] the requirement that led to a version of a possibility
# with the given name being activated.
def requirement_for_existing_name(name)
- return nil unless activated.vertex_named(name).payload
states.find { |s| s.name == name }.requirement
end
# @return [ResolutionState] the state whose `requirement` is the given
# `requirement`.
def find_state_for(requirement)
return nil unless requirement
- states.reverse_each.find { |i| requirement == i.requirement && i.is_a?(DependencyState) }
- end
-
- # @return [Boolean] whether or not the given state has any possibilities
- # left.
- def state_any?(state)
- state && state.possibilities.any?
end
# @return [Conflict] a {Conflict} that reflects the failure to activate
# the {#possibility} in conjunction with the current {#state}
- def create_conflict
vertex = activated.vertex_named(name)
locked_requirement = locked_requirement_named(name)
@@ -250,18 +597,21 @@ module Gem::Resolver::Molinillo
requirements[name_for_explicit_dependency_source] = vertex.explicit_requirements
end
requirements[name_for_locking_dependency_source] = [locked_requirement] if locked_requirement
- vertex.incoming_edges.each { |edge| (requirements[edge.origin.payload] ||= []).unshift(edge.requirement) }
activated_by_name = {}
- activated.each { |v| activated_by_name[v.name] = v.payload if v.payload }
conflicts[name] = Conflict.new(
requirement,
requirements,
- vertex.payload,
possibility,
locked_requirement,
requirement_trees,
- activated_by_name
)
end
@@ -272,6 +622,7 @@ module Gem::Resolver::Molinillo
vertex.requirements.map { |r| requirement_tree_for(r) }
end
# @return [Array<Object>] the list of requirements that led to
# `requirement` being required.
def requirement_tree_for(requirement)
@@ -311,116 +662,47 @@ module Gem::Resolver::Molinillo
# @return [void]
def attempt_to_activate
debug(depth) { 'Attempting to activate ' + possibility.to_s }
- existing_node = activated.vertex_named(name)
- if existing_node.payload
- debug(depth) { "Found existing spec (#{existing_node.payload})" }
- attempt_to_activate_existing_spec(existing_node)
else
- attempt_to_activate_new_spec
- end
- end
-
- # Attempts to activate the current {#possibility} (given that it has
- # already been activated)
- # @return [void]
- def attempt_to_activate_existing_spec(existing_node)
- existing_spec = existing_node.payload
- if requirement_satisfied_by?(requirement, activated, existing_spec)
- new_requirements = requirements.dup
- push_state_for_requirements(new_requirements, false)
- else
- return if attempt_to_swap_possibility
- create_conflict
- debug(depth) { "Unsatisfied by existing spec (#{existing_node.payload})" }
- unwind_for_conflict
- end
- end
-
- # Attempts to swp the current {#possibility} with the already-activated
- # spec with the given name
- # @return [Boolean] Whether the possibility was swapped into {#activated}
- def attempt_to_swap_possibility
- activated.tag(:swap)
- vertex = activated.vertex_named(name)
- activated.set_payload(name, possibility)
- if !vertex.requirements.
- all? { |r| requirement_satisfied_by?(r, activated, possibility) } ||
- !new_spec_satisfied?
- activated.rewind_to(:swap)
- return
- end
- fixup_swapped_children(vertex)
- activate_spec
- end
-
- # Ensures there are no orphaned successors to the given {vertex}.
- # @param [DependencyGraph::Vertex] vertex the vertex to fix up.
- # @return [void]
- def fixup_swapped_children(vertex) # rubocop:disable Metrics/CyclomaticComplexity
- payload = vertex.payload
- deps = dependencies_for(payload).group_by(&method(:name_for))
- vertex.outgoing_edges.each do |outgoing_edge|
- requirement = outgoing_edge.requirement
- parent_index = @parents_of[requirement].last
- succ = outgoing_edge.destination
- matching_deps = Array(deps[succ.name])
- dep_matched = matching_deps.include?(requirement)
-
- # only push the current index when it was originally required by the
- # same named spec
- if parent_index && states[parent_index].name == name
- @parents_of[requirement].push(states.size - 1)
end
-
- if matching_deps.empty? && !succ.root? && succ.predecessors.to_a == [vertex]
- debug(depth) { "Removing orphaned spec #{succ.name} after swapping #{name}" }
- succ.requirements.each { |r| @parents_of.delete(r) }
-
- removed_names = activated.detach_vertex_named(succ.name).map(&:name)
- requirements.delete_if do |r|
- # the only removed vertices are those with no other requirements,
- # so it's safe to delete only based upon name here
- removed_names.include?(name_for(r))
- end
- elsif !dep_matched
- debug(depth) { "Removing orphaned dependency #{requirement} after swapping #{name}" }
- # also reset if we're removing the edge, but only if its parent has
- # already been fixed up
- @parents_of[requirement].push(states.size - 1) if @parents_of[requirement].empty?
-
- activated.delete_edge(outgoing_edge)
- requirements.delete(requirement)
end
end
end
- # Attempts to activate the current {#possibility} (given that it hasn't
- # already been activated)
# @return [void]
- def attempt_to_activate_new_spec
- if new_spec_satisfied?
- activate_spec
else
create_conflict
unwind_for_conflict
end
end
- # @return [Boolean] whether the current spec is satisfied as a new
- # possibility.
- def new_spec_satisfied?
- unless requirement_satisfied_by?(requirement, activated, possibility)
- debug(depth) { 'Unsatisfied by requested spec' }
- return false
- end
-
- locked_requirement = locked_requirement_named(name)
-
- locked_spec_satisfied = !locked_requirement ||
- requirement_satisfied_by?(locked_requirement, activated, possibility)
- debug(depth) { 'Unsatisfied by locked spec' } unless locked_spec_satisfied
-
- locked_spec_satisfied
end
# @param [String] requirement_name the spec name to search for
@@ -434,7 +716,7 @@ module Gem::Resolver::Molinillo
# Add the current {#possibility} to the dependency graph of the current
# {#state}
# @return [void]
- def activate_spec
conflicts.delete(name)
debug(depth) { "Activated #{name} at #{possibility}" }
activated.set_payload(name, possibility)
@@ -442,14 +724,14 @@ module Gem::Resolver::Molinillo
end
# Requires the dependencies that the recently activated spec has
- # @param [Object] activated_spec the specification that has just been
# activated
# @return [void]
- def require_nested_dependencies_for(activated_spec)
- nested_dependencies = dependencies_for(activated_spec)
debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
nested_dependencies.each do |d|
- activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d)
parent_index = states.size - 1
parents = @parents_of[d]
parents << parent_index if parents.empty?
@@ -461,23 +743,82 @@ module Gem::Resolver::Molinillo
# Pushes a new {DependencyState} that encapsulates both existing and new
# requirements
# @param [Array] new_requirements
# @return [void]
def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
- new_requirement = new_requirements.shift
new_name = new_requirement ? name_for(new_requirement) : ''.freeze
- possibilities = new_requirement ? search_for(new_requirement) : []
handle_missing_or_push_dependency_state DependencyState.new(
new_name, new_requirements, new_activated,
- new_requirement, possibilities, depth, conflicts.dup
)
end
# Pushes a new {DependencyState}.
# If the {#specification_provider} says to
# {SpecificationProvider#allow_missing?} that particular requirement, and
# there are no possibilities for that requirement, then `state` is not
- # pushed, and the node in {#activated} is removed, and we continue
# resolving the remaining requirements.
# @param [DependencyState] state
# @return [void]
@@ -1,5 +1,6 @@
# frozen_string_literal: true
-require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph'
module Gem::Resolver::Molinillo
# This class encapsulates a dependency resolver.
@@ -8,7 +9,7 @@ module Gem::Resolver::Molinillo
#
#
class Resolver
- require 'rubygems/resolver/molinillo/lib/molinillo/resolution'
# @return [SpecificationProvider] the specification provider used
# in the resolution process
@@ -1,4 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# A state that a {Resolution} can be in
# @attr [String] name the name of the current requirement
@@ -7,7 +8,8 @@ module Gem::Resolver::Molinillo
# @attr [Object] requirement the current requirement
# @attr [Object] possibilities the possibilities to satisfy the current requirement
# @attr [Integer] depth the depth of the resolution
- # @attr [Set<Object>] conflicts unresolved conflicts
ResolutionState = Struct.new(
:name,
:requirements,
@@ -15,14 +17,15 @@ module Gem::Resolver::Molinillo
:requirement,
:possibilities,
:depth,
- :conflicts
)
class ResolutionState
# Returns an empty resolution state
# @return [ResolutionState] an empty state
def self.empty
- new(nil, [], DependencyGraph.new, nil, nil, 0, Set.new)
end
end
@@ -40,7 +43,8 @@ module Gem::Resolver::Molinillo
requirement,
[possibilities.pop],
depth + 1,
- conflicts.dup
).tap do |state|
state.activated.tag(state)
end
@@ -104,7 +104,7 @@ class Gem::Resolver::Specification
# Returns true if this specification is installable on this platform.
def installable_platform?
- Gem::Platform.match spec.platform
end
def local? # :nodoc:
@@ -88,7 +88,7 @@ class Gem::S3URISigner
"AWS4-HMAC-SHA256",
date_time,
credential_info,
- Digest::SHA256.hexdigest(canonical_request)
].join("\n")
end
@@ -6,7 +6,6 @@
#++
require 'rubygems/exceptions'
-require 'fileutils'
require_relative 'openssl'
##
@@ -592,7 +591,7 @@ module Gem::Security
end
-if defined?(OpenSSL::SSL)
require 'rubygems/security/policy'
require 'rubygems/security/policies'
require 'rubygems/security/trust_dir'
@@ -194,7 +194,7 @@ class Gem::Security::Policy
("[Policy: %s - data: %p signer: %p chain: %p root: %p " +
"signed-only: %p trusted-only: %p]") % [
@name, @verify_chain, @verify_data, @verify_root, @verify_signer,
- @only_signed, @only_trusted,
]
end
@@ -34,7 +34,7 @@ class Gem::Security::Signer
attr_reader :options
DEFAULT_OPTIONS = {
- expiration_length_days: 365
}.freeze
##
@@ -771,7 +771,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
doc_items << {
:name => base_name,
:url => doc_root(new_path),
- :summary => ''
}
end
@@ -79,7 +79,7 @@ class Gem::Source
def dependency_resolver_set # :nodoc:
return Gem::Resolver::IndexSet.new self if 'file' == uri.scheme
- bundler_api_uri = uri + './api/v1/dependencies'
begin
fetcher = Gem::RemoteFetcher.fetcher
@@ -130,7 +130,7 @@ class Gem::Source
spec_file_name = name_tuple.spec_name
- source_uri = uri + "#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}"
cache_dir = cache_dir source_uri
@@ -174,7 +174,7 @@ class Gem::Source
file = FILES[type]
fetcher = Gem::RemoteFetcher.fetcher
file_name = "#{file}.#{Gem.marshal_version}"
- spec_path = uri + "#{file_name}.gz"
cache_dir = cache_dir spec_path
local_file = File.join(cache_dir, file_name)
retried = false
@@ -223,7 +223,13 @@ class Gem::Source
def typo_squatting?(host, distance_threshold=4)
return if @uri.host.nil?
- levenshtein_distance(@uri.host, host) <= distance_threshold
end
end
@@ -98,7 +98,7 @@ class Gem::SpecFetcher
found[source] = specs.select do |tup|
if dependency.match?(tup)
- if matching_platform and !Gem::Platform.match(tup.platform)
pm = (
rejected_specs[dependency] ||= \
Gem::PlatformMismatch.new(tup.name, tup.version))
@@ -77,18 +77,18 @@ class Gem::Specification < Gem::BasicSpecification
-1 => ['(RubyGems versions up to and including 0.7 did not have versioned specifications)'],
1 => [
'Deprecated "test_suite_file" in favor of the new, but equivalent, "test_files"',
- '"test_file=x" is a shortcut for "test_files=[x]"'
],
2 => [
'Added "required_rubygems_version"',
'Now forward-compatible with future versions',
],
3 => [
- 'Added Fixnum validation to the specification_version'
],
4 => [
- 'Added sandboxed freeform metadata to the specification version.'
- ]
}.freeze
MARSHAL_FIELDS = { # :nodoc:
@@ -804,7 +804,7 @@ class Gem::Specification < Gem::BasicSpecification
stubs = stubs.uniq {|stub| stub.full_name }
_resort!(stubs)
- @@stubs_by_name = stubs.select {|s| Gem::Platform.match s.platform }.group_by(&:name)
stubs
end
end
@@ -831,7 +831,7 @@ class Gem::Specification < Gem::BasicSpecification
@@stubs_by_name[name]
else
pattern = "#{name}-*.gemspec"
- stubs = installed_stubs(dirs, pattern).select {|s| Gem::Platform.match s.platform } + default_stubs(pattern)
stubs = stubs.uniq {|stub| stub.full_name }.group_by(&:name)
stubs.each_value {|v| _resort!(v) }
@@ -1344,7 +1344,7 @@ class Gem::Specification < Gem::BasicSpecification
true, # has_rdoc
@new_platform,
@licenses,
- @metadata
]
end
@@ -2450,7 +2450,7 @@ class Gem::Specification < Gem::BasicSpecification
:version,
:has_rdoc,
:default_executable,
- :metadata
]
@@attributes.each do |attr_name|
@@ -1,23 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
-+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
-PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
-xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
-Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
-hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
-EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
-FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
-nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
-eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
-hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
-Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
-vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
-+OkuE6N36B9K
------END CERTIFICATE-----
@@ -29,7 +29,7 @@ class Gem::StubSpecification < Gem::BasicSpecification
# in their require paths, so lets take advantage of that by pre-allocating
# a require path list for that case.
REQUIRE_PATH_LIST = { # :nodoc:
- 'lib' => ['lib'].freeze
}.freeze
def initialize(data, extensions)
@@ -252,14 +252,14 @@ class Gem::TestCase < Minitest::Test
msg = message(msg) do
'Expected output containing make command "%s": %s' % [
('%s %s' % [make_command, target]).rstrip,
- output.inspect
]
end
else
msg = message(msg) do
'Expected make command "%s": %s' % [
('%s %s' % [make_command, target]).rstrip,
- output.inspect
]
end
end
@@ -335,6 +335,7 @@ class Gem::TestCase < Minitest::Test
@git = ENV['GIT'] || (win_platform? ? 'git.exe' : 'git')
Gem.ensure_gem_subdirectories @gemhome
@orig_LOAD_PATH = $LOAD_PATH.dup
$LOAD_PATH.map! do |s|
@@ -360,26 +361,23 @@ class Gem::TestCase < Minitest::Test
Gem.send :remove_instance_variable, :@ruby_version if
Gem.instance_variables.include? :@ruby_version
- FileUtils.mkdir_p @gemhome
FileUtils.mkdir_p @userhome
ENV['GEM_PRIVATE_KEY_PASSPHRASE'] = PRIVATE_KEY_PASSPHRASE
- @default_dir = File.join @tempdir, 'default'
- @default_spec_dir = File.join @default_dir, "specifications", "default"
if Gem.java_platform?
@orig_default_gem_home = RbConfig::CONFIG['default_gem_home']
- RbConfig::CONFIG['default_gem_home'] = @default_dir
else
- Gem.instance_variable_set(:@default_dir, @default_dir)
end
- FileUtils.mkdir_p @default_spec_dir
Gem::Specification.unresolved_deps.clear
Gem.use_paths(@gemhome)
- Gem::Security.reset
-
Gem.loaded_specs.clear
Gem.instance_variable_set(:@activated_gem_paths, 0)
Gem.clear_default_specs
@@ -448,6 +446,8 @@ class Gem::TestCase < Minitest::Test
Gem.ruby = @orig_ruby if @orig_ruby
if Gem.java_platform?
RbConfig::CONFIG['default_gem_home'] = @orig_default_gem_home
else
@@ -741,7 +741,7 @@ class Gem::TestCase < Minitest::Test
def install_specs(*specs)
specs.each do |spec|
- Gem::Installer.for_spec(spec).install
end
Gem.searcher = nil
@@ -751,19 +751,6 @@ class Gem::TestCase < Minitest::Test
# Installs the provided default specs including writing the spec file
def install_default_gems(*specs)
- install_default_specs(*specs)
-
- specs.each do |spec|
- File.open spec.loaded_from, 'w' do |io|
- io.write spec.to_ruby_for_cache
- end
- end
- end
-
- ##
- # Install the provided default specs
-
- def install_default_specs(*specs)
specs.each do |spec|
installer = Gem::Installer.for_spec(spec, :install_as_default => true)
installer.install
@@ -792,7 +779,7 @@ class Gem::TestCase < Minitest::Test
def new_default_spec(name, version, deps = nil, *files)
spec = util_spec name, version, deps
- spec.loaded_from = File.join(@default_spec_dir, spec.spec_name)
spec.files = files
lib_dir = File.join(@tempdir, "default_gems", "lib")
@@ -1517,7 +1504,7 @@ Also, a list:
PRIVATE_KEY = nil
PUBLIC_KEY = nil
PUBLIC_CERT = nil
- end if defined?(OpenSSL::SSL)
end
require 'rubygems/test_utilities'
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require 'cgi'
##
# The UriFormatter handles URIs from user-input and escaping.
@@ -18,6 +17,8 @@ class Gem::UriFormatter
# Creates a new URI formatter for +uri+.
def initialize(uri)
@uri = uri
end
@@ -73,4 +73,10 @@ module Gem::VersionOption
end
end
end