summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDavid Rodríguez <[email protected]>2022-06-23 11:22:36 +0200
committerHiroshi SHIBATA <[email protected]>2022-06-24 10:52:02 +0900
commit12a5fa408bd318f8fb242e86beb225f2dcae8df9 ()
treef132650f5999535da69ee998956f260007afd371 /lib
parent333754ace8ae9bc5d2dfb4aee160fcfa0f38350d (diff)
Sync RubyGems & Bundler with upstream repo
Notes: Merged: https://.com/ruby/ruby/pull/6054
-rw-r--r--lib/bundler/definition.rb36
-rw-r--r--lib/bundler/dependency.rb2
-rw-r--r--lib/bundler/dsl.rb4
-rw-r--r--lib/bundler/errors.rb2
-rw-r--r--lib/bundler/fetcher.rb4
-rw-r--r--lib/bundler/fetcher/base.rb14
-rw-r--r--lib/bundler/plugin/api/source.rb6
-rw-r--r--lib/bundler/resolver.rb22
-rw-r--r--lib/bundler/source/git.rb12
-rw-r--r--lib/rubygems.rb2
-rw-r--r--lib/rubygems/commands/install_command.rb2
-rw-r--r--lib/rubygems/commands/sources_command.rb2
-rw-r--r--lib/rubygems/core_ext/kernel_require.rb2
-rw-r--r--lib/rubygems/errors.rb2
-rw-r--r--lib/rubygems/ext/builder.rb6
-rw-r--r--lib/rubygems/ext/cargo_builder.rb151
-rw-r--r--lib/rubygems/ext/cargo_builder/link_flag_converter.rb23
-rw-r--r--lib/rubygems/local_remote_options.rb2
-rw-r--r--lib/rubygems/psych_additions.rb10
-rw-r--r--lib/rubygems/request.rb2
-rw-r--r--lib/rubygems/source.rb11
-rw-r--r--lib/rubygems/source/git.rb4
-rw-r--r--lib/rubygems/source_list.rb6
-rw-r--r--lib/rubygems/specification.rb22
-rw-r--r--lib/rubygems/uri.rb67
25 files changed, 232 insertions, 184 deletions
@@ -255,20 +255,18 @@ module Bundler
#
# @return [SpecSet] resolved dependencies
def resolve
- @resolve ||= begin
- if Bundler.frozen_bundle?
- Bundler.ui.debug "Frozen, using resolution from the lockfile"
- @locked_specs
- elsif !unlocking? && nothing_changed?
- Bundler.ui.debug("Found no changes, using resolution from the lockfile")
- SpecSet.new(filter_specs(@locked_specs, @dependencies.select {|dep| @locked_specs[dep].any? }))
- else
- last_resolve = converge_locked_specs
- # Run a resolve against the locally available gems
- Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
- expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true)
- Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
- end
end
end
@@ -735,12 +733,10 @@ module Bundler
end
def metadata_dependencies
- @metadata_dependencies ||= begin
- [
- Dependency.new("Ruby\0", RubyVersion.system.gem_version),
- Dependency.new("RubyGems\0", Gem::VERSION),
- ]
- end
end
def expand_dependencies(dependencies, remote = false)
@@ -9,6 +9,7 @@ module Bundler
attr_reader :autorequire
attr_reader :groups, :platforms, :gemfile, :git, :, :branch, :ref
PLATFORM_MAP = {
:ruby => Gem::Platform::RUBY,
:ruby_18 => Gem::Platform::RUBY,
@@ -91,6 +92,7 @@ module Bundler
:x64_mingw_30 => Gem::Platform::X64_MINGW,
:x64_mingw_31 => Gem::Platform::X64_MINGW,
}.freeze
def initialize(name, version, options = {}, &blk)
type = options["type"] || :runtime
@@ -511,9 +511,7 @@ module Bundler
# be raised.
#
def contents
- @contents ||= begin
- dsl_path && File.exist?(dsl_path) && File.read(dsl_path)
- end
end
# The message of the exception reports the content of podspec for the
@@ -41,12 +41,14 @@ module Bundler
class GemspecError < BundlerError; status_code(14); end
class InvalidOption < BundlerError; status_code(15); end
class ProductionError < BundlerError; status_code(16); end
class HTTPError < BundlerError
status_code(17)
def filter_uri(uri)
URICredentialsFilter.credential_filtered_uri(uri)
end
end
class RubyVersionMismatch < BundlerError; status_code(18); end
class SecurityError < BundlerError; status_code(19); end
class LockfileError < BundlerError; status_code(20); end
@@ -20,6 +20,7 @@ module Bundler
class TooManyRequestsError < HTTPError; end
# This error is raised if the API returns a 413 (only printed in verbose)
class FallbackError < HTTPError; end
# This is the error raised if OpenSSL fails the cert verification
class CertificateFailureError < HTTPError
def initialize(remote_uri)
@@ -33,6 +34,7 @@ module Bundler
" sources and change 'https' to 'http'."
end
end
# This is the error raised when a source is HTTPS and OpenSSL didn't load
class SSLError < HTTPError
def initialize(msg = nil)
@@ -42,6 +44,7 @@ module Bundler
"using RVM are available at rvm.io/packages/openssl."
end
end
# This error is raised if HTTP authentication is required, but not provided.
class AuthenticationRequiredError < HTTPError
def initialize(remote_uri)
@@ -52,6 +55,7 @@ module Bundler
"or by storing the credentials in the `#{Settings.key_for(remote_uri)}` environment variable"
end
end
# This error is raised if HTTP authentication is provided, but incorrect.
class BadAuthenticationError < HTTPError
def initialize(remote_uri)
@@ -19,14 +19,12 @@ module Bundler
end
def fetch_uri
- @fetch_uri ||= begin
- if remote_uri.host == "rubygems.org"
- uri = remote_uri.dup
- uri.host = "index.rubygems.org"
- uri
- else
- remote_uri
- end
end
end
@@ -258,7 +258,7 @@ module Bundler
@dependencies |= Array(names)
end
- # Note: Do not override if you don't know what you are doing.
def can_lock?(spec)
spec.source == self
end
@@ -285,7 +285,7 @@ module Bundler
end
alias_method :identifier, :to_s
- # Note: Do not override if you don't know what you are doing.
def include?(other)
other == self
end
@@ -294,7 +294,7 @@ module Bundler
SharedHelpers.digest(:SHA1).hexdigest(uri)
end
- # Note: Do not override if you don't know what you are doing.
def gem_install_dir
Bundler.install_path
end
@@ -233,19 +233,17 @@ module Bundler
# before dependencies that are unconstrained
def amount_constrained(dependency)
@amount_constrained ||= {}
- @amount_constrained[dependency.name] ||= begin
- if (base = @base[dependency.name]) && !base.empty?
- dependency.requirement.satisfied_by?(base.first.version) ? 0 : 1
- else
- all = index_for(dependency).search(dependency.name).size
- if all <= 1
- all - 1_000_000
- else
- search = search_for(dependency)
- search = @prerelease_specified[dependency.name] ? search.count : search.count {|s| !s.version.prerelease? }
- search - all
- end
end
end
end
@@ -219,13 +219,11 @@ module Bundler
# across different projects, this cache will be shared.
# When using local git repos, this is set to the local repo.
def cache_path
- @cache_path ||= begin
- if Bundler.requires_sudo? || Bundler.feature_flag.global_gem_cache?
- Bundler.user_cache
- else
- Bundler.bundle_path.join("cache", "bundler")
- end.join("git", git_scope)
- end
end
def app_cache_dirname
@@ -607,7 +607,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
return if @yaml_loaded
require 'psych'
- require_relative 'rubygems/psych_additions'
require_relative 'rubygems/psych_tree'
require_relative 'rubygems/safe_yaml'
@@ -1018,7 +1017,6 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
def self.load_plugin_files(plugins) # :nodoc:
plugins.each do |plugin|
-
# Skip older versions of the GemCutter plugin: Its commands are in
# RubyGems proper now.
@@ -261,7 +261,7 @@ You can use `i` command instead of `install`.
return unless Gem::SourceFetchProblem === x
require_relative "../uri"
- msg = "Unable to pull data from '#{Gem::Uri.new(x.source.uri).redacted}': #{x.error.message}"
alert_warning msg
end
@@ -62,7 +62,7 @@ class Gem::Commands::SourcesCommand < Gem::Command
say "#{source_uri} is not a URI"
terminate_interaction 1
rescue Gem::RemoteFetcher::FetchError => e
- say "Error fetching #{source_uri}:\n\t#{e.message}"
terminate_interaction 1
end
end
@@ -18,7 +18,7 @@ module Kernel
end
file = Gem::KERNEL_WARN_IGNORES_INTERNAL_ENTRIES ? "<internal:#{__FILE__}>" : __FILE__
- module_eval <<'RUBY', file, __LINE__ + 1
##
# When RubyGems is required, Kernel#require is replaced with our own which
# is capable of loading gems on demand.
@@ -168,7 +168,7 @@ module Gem
# An English description of the error.
def wordy
- "Unable to download data from #{Gem::Uri.new(@source.uri).redacted} - #{@error.message}"
end
##
@@ -55,7 +55,7 @@ class Gem::Ext::Builder
end
end
- def self.run(command, results, command_name = nil, dir = Dir.pwd)
verbose = Gem.configuration.really_verbose
begin
@@ -70,9 +70,9 @@ class Gem::Ext::Builder
require "open3"
# Set $SOURCE_DATE_EPOCH for the subprocess.
- env = { 'SOURCE_DATE_EPOCH' => Gem.source_date_epoch_string }
output, status = begin
- Open3.capture2e(env, *command, :chdir => dir)
rescue => error
raise Gem::InstallError, "#{command_name || class_name} failed#{error.message}"
end
@@ -4,48 +4,67 @@
# over the `cargo rustc` command which takes care of building Rust code in a way
# that Ruby can use.
class Gem::Ext::CargoBuilder < Gem::Ext::Builder
- attr_reader :spec
def initialize(spec)
@spec = spec
end
def build(_extension, dest_path, results, args = [], lib_dir = nil, cargo_dir = Dir.pwd)
- require "rubygems/command"
require "fileutils"
require "shellwords"
build_crate(dest_path, results, args, cargo_dir)
- ext_path = rename_cdylib_for_ruby_compatibility(dest_path)
- finalize_directory(ext_path, dest_path, lib_dir, cargo_dir)
results
end
- private
-
def build_crate(dest_path, results, args, cargo_dir)
- manifest = File.join(cargo_dir, "Cargo.toml")
- given_ruby_static = ENV["RUBY_STATIC"]
- ENV["RUBY_STATIC"] = "true" if ruby_static? && !given_ruby_static
cargo = ENV.fetch("CARGO", "cargo")
cmd = []
cmd += [cargo, "rustc"]
cmd += ["--target-dir", dest_path]
cmd += ["--manifest-path", manifest]
- cmd += ["--lib", "--release", "--locked"]
- cmd += ["--"]
- cmd += [*cargo_rustc_args(dest_path)]
cmd += Gem::Command.build_args
cmd += args
- self.class.run cmd, results, self.class.class_name, cargo_dir
- results
- ensure
- ENV["RUBY_STATIC"] = given_ruby_static
end
def cargo_rustc_args(dest_dir)
@@ -92,7 +111,7 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
def libruby_args(dest_dir)
libs = makefile_config(ruby_static? ? "LIBRUBYARG_STATIC" : "LIBRUBYARG_SHARED")
raw_libs = Shellwords.split(libs)
- raw_libs.flat_map {|l| ldflag_to_link_modifier(l, dest_dir) }
end
def ruby_static?
@@ -103,22 +122,33 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
# Ruby expects the dylib to follow a file name convention for loading
def rename_cdylib_for_ruby_compatibility(dest_path)
- dylib_path = validate_cargo_build!(dest_path)
- dlext_name = "#{spec.name}.#{makefile_config("DLEXT")}"
- new_name = dylib_path.gsub(File.basename(dylib_path), dlext_name)
- FileUtils.cp(dylib_path, new_name)
- new_name
end
def validate_cargo_build!(dir)
- prefix = so_ext == "dll" ? "" : "lib"
- dylib_path = File.join(dir, "release", "#{prefix}#{cargo_crate_name}.#{so_ext}")
raise DylibNotFoundError, dir unless File.exist?(dylib_path)
dylib_path
end
def cargo_crate_name
spec.metadata.fetch('cargo_crate_name', spec.name).tr('-', '_')
end
@@ -127,42 +157,19 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
split_flags("DLDFLAGS")
.map {|arg| maybe_resolve_ldflag_variable(arg, dest_dir) }
.compact
- .flat_map {|arg| ldflag_to_link_modifier(arg, dest_dir) }
end
def rustc_lib_flags(dest_dir)
- split_flags("LIBS").flat_map {|arg| ldflag_to_link_modifier(arg, dest_dir) }
end
def split_flags(var)
Shellwords.split(RbConfig::CONFIG.fetch(var, ""))
end
- def ldflag_to_link_modifier(arg, dest_dir)
- flag = arg[0..1]
- val = arg[2..-1]
-
- case flag
- when "-L" then ["-L", "native=#{val}"]
- when "-l" then ["-l", val.to_s]
- when "-F" then ["-l", "framework=#{val}"]
- else ["-C", "link_arg=#{arg}"]
- end
- end
-
- def link_flag(link_name)
- # These are provided by the CRT with MSVC
- # @see https://.com/rust-lang/pkg-config-rs/blob/49a4ac189aafa365167c72e8e503565a7c2697c2/src/lib.rs#L622
- return [] if msvc_target? && ["m", "c", "pthread"].include?(link_name)
-
- if link_name.include?("ruby")
- # Specify the lib kind and give it the name "ruby" for linking
- kind = ruby_static? ? "static" : "dylib"
-
- ["-l", "#{kind}=ruby:#{link_name}"]
- else
- ["-l", link_name]
- end
end
def msvc_target?
@@ -182,20 +189,24 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
!!Gem::WIN_PATTERNS.find {|r| target_platform =~ r }
end
- # Intepolate substition vars in the arg (i.e. $(DEFFILE))
def maybe_resolve_ldflag_variable(input_arg, dest_dir)
- str = input_arg.gsub(/\$\((\w+)\)/) do |var_name|
- case var_name
- # On windows, it is assumed that mkmf has setup an exports file for the
- # extension, so we have to to create one ourselves.
- when "DEFFILE"
- write_deffile(dest_dir)
- else
- RbConfig::CONFIG[var_name]
- end
- end.strip
- str == "" ? nil : str
end
def write_deffile(dest_dir)
@@ -241,14 +252,18 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
# Good balance between binary size and debugability
def debug_flags
["-C", "debuginfo=1"]
end
# Copied from ExtConfBuilder
- def finalize_directory(ext_path, dest_path, lib_dir, extension_dir)
require "fileutils"
require "tempfile"
begin
tmp_dest = Dir.mktmpdir(".gem.", extension_dir)
@@ -280,6 +295,14 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
path
end
# Error raised when no cdylib artifact was created
class DylibNotFoundError < StandardError
def initialize(dir)
@@ -0,0 +1,23 @@
@@ -78,7 +78,6 @@ module Gem::LocalRemoteOptions
def add_clear_sources_option
add_option(:"Local/Remote", '--clear-sources',
'Clear the gem sources') do |value, options|
-
Gem.sources = nil
options[:sources_cleared] = true
end
@@ -105,7 +104,6 @@ module Gem::LocalRemoteOptions
add_option(:"Local/Remote", '-s', '--source URL', URI::HTTP,
'Append URL to list of remote gem sources') do |source, options|
-
source << '/' if source !~ /\/\z/
if options.delete :sources_cleared
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-# This exists just to satisfy bugs in marshal'd gemspecs that
-# contain a reference to Psych::PrivateType. We prune these out
-# in Specification._load, but if we don't have the constant, Marshal
-# blows up.
-
-module Psych # :nodoc:
- class PrivateType # :nodoc:
- end
-end
@@ -193,7 +193,7 @@ class Gem::Request
begin
@requests[connection.object_id] += 1
- verbose "#{request.method} #{Gem::Uri.new(@uri).redacted}"
file_name = File.basename(@uri.path)
# perform download progress reporter only for gems
@@ -26,15 +26,8 @@ class Gem::Source
# Creates a new Source which will use the index located at +uri+.
def initialize(uri)
- begin
- unless uri.kind_of? URI
- uri = URI.parse(uri.to_s)
- end
- rescue URI::InvalidURIError
- raise if Gem::Source == self.class
- end
-
- @uri = uri
@update_cache = nil
end
@@ -49,8 +49,8 @@ class Gem::Source::Git < Gem::Source
# will be checked out when the gem is installed.
def initialize(name, repository, reference, submodules = false)
- super repository
-
@name = name
@repository = repository
@reference = reference
@@ -48,15 +48,11 @@ class Gem::SourceList
# String.
def <<(obj)
- require "uri"
-
src = case obj
- when URI
- Gem::Source.new(obj)
when Gem::Source
obj
else
- Gem::Source.new(URI.parse(obj))
end
@sources << src unless @sources.include?(src)
@@ -1272,10 +1272,26 @@ class Gem::Specification < Gem::BasicSpecification
array = begin
Marshal.load str
rescue ArgumentError => e
- raise unless e.message.include?("YAML")
- Object.const_set "YAML", Psych
- Marshal.load str
end
spec = Gem::Specification.new
@@ -5,6 +5,44 @@
#
class Gem::Uri
def initialize(source_uri)
@parsed_uri = parse(source_uri)
end
@@ -26,7 +64,7 @@ class Gem::Uri
end
def redact_credentials_from(text)
- return text unless valid_uri? && password?
text.sub(password, 'REDACTED')
end
@@ -50,35 +88,12 @@ class Gem::Uri
private
- ##
- # Parses the #uri, raising if it's invalid
-
def parse!(uri)
- require "uri"
-
- raise URI::InvalidURIError unless uri
-
- # Always escape URI's to deal with potential spaces and such
- # It should also be considered that source_uri may already be
- # a valid URI with escaped characters. e.g. "{DESede}" is encoded
- # as "%7BDESede%7D". If this is escaped again the percentage
- # symbols will be escaped.
- begin
- URI.parse(uri)
- rescue URI::InvalidURIError
- URI.parse(URI::DEFAULT_PARSER.escape(uri))
- end
end
- ##
- # Parses the #uri, returning the original uri if it's invalid
-
def parse(uri)
- return uri unless uri.is_a?(String)
-
- parse!(uri)
- rescue URI::InvalidURIError
- uri
end
def with_redacted_user