diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index e1c284130b..3d93ce5e6f 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -251,9 +251,7 @@ module Bundler remembered_negative_flag_deprecation("no-deployment") require_relative "cli/install" - Bundler.settings.temporary(:no_install => false) do - Install.new(options.dup).run - end + Install.new(options.dup).run end map aliases_for("install") @@ -299,9 +297,7 @@ module Bundler def update(*gems) SharedHelpers.major_deprecation(2, "The `--force` option has been renamed to `--redownload`") if ARGV.include?("--force") require_relative "cli/update" - Bundler.settings.temporary(:no_install => false) do - Update.new(options, gems).run - end + Update.new(options, gems).run end desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem" diff --git a/lib/bundler/cli/cache.rb b/lib/bundler/cli/cache.rb index c8698ed7e3..eb5dd23092 100644 --- a/lib/bundler/cli/cache.rb +++ b/lib/bundler/cli/cache.rb @@ -14,7 +14,7 @@ module Bundler Bundler.settings.set_command_option_if_given :cache_path, options["cache-path"] setup_cache_all - install + install unless Bundler.settings[:no_install] # TODO: move cache contents here now that all bundles are locked custom_path = Bundler.settings[:path] if options[:path] diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb index e9b85f7f6f..acf92f28ad 100644 --- a/lib/bundler/cli/install.rb +++ b/lib/bundler/cli/install.rb @@ -161,8 +161,6 @@ module Bundler Bundler.settings.set_command_option_if_given :no_prune, options["no-prune"] - Bundler.settings.set_command_option_if_given :no_install, options["no-install"] - Bundler.settings.set_command_option_if_given :clean, options["clean"] normalize_groups if options[:without] || options[:with] diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 4fca763bcc..2e0f23a402 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -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 + @resolve ||= 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 @@ -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 + @metadata_dependencies ||= [ + Dependency.new("Ruby\0", RubyVersion.system.gem_version), + Dependency.new("RubyGems\0", Gem::VERSION), + ] end def expand_dependencies(dependencies, remote = false) diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb index d12b120bba..018a3182b9 100644 --- a/lib/bundler/dependency.rb +++ b/lib/bundler/dependency.rb @@ -9,6 +9,7 @@ module Bundler attr_reader :autorequire attr_reader :groups, :platforms, :gemfile, :git, :github, :branch, :ref + # rubocop:disable Naming/VariableNumber 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 + # rubocop:enable Naming/VariableNumber def initialize(name, version, options = {}, &blk) type = options["type"] || :runtime diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb index 1ae19a46e9..bfa078046c 100644 --- a/lib/bundler/dsl.rb +++ b/lib/bundler/dsl.rb @@ -511,9 +511,7 @@ module Bundler # be raised. # def contents - @contents ||= begin - dsl_path && File.exist?(dsl_path) && File.read(dsl_path) - end + @contents ||= dsl_path && File.exist?(dsl_path) && File.read(dsl_path) end # The message of the exception reports the content of podspec for the diff --git a/lib/bundler/errors.rb b/lib/bundler/errors.rb index 0bc1a860df..f10b6cc68f 100644 --- a/lib/bundler/errors.rb +++ b/lib/bundler/errors.rb @@ -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 diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb index 6fe047568f..e9d5dd505c 100644 --- a/lib/bundler/fetcher.rb +++ b/lib/bundler/fetcher.rb @@ -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) diff --git a/lib/bundler/fetcher/base.rb b/lib/bundler/fetcher/base.rb index 16cc98273a..62cc75add8 100644 --- a/lib/bundler/fetcher/base.rb +++ b/lib/bundler/fetcher/base.rb @@ -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 + @fetch_uri ||= if remote_uri.host == "rubygems.org" + uri = remote_uri.dup + uri.host = "index.rubygems.org" + uri + else + remote_uri end end diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb index a6ae08237c..67c45bd204 100644 --- a/lib/bundler/plugin/api/source.rb +++ b/lib/bundler/plugin/api/source.rb @@ -258,7 +258,7 @@ module Bundler @dependencies |= Array(names) end - # Note: Do not override if you don't know what you are doing. + # 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. + # 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. + # NOTE: Do not override if you don't know what you are doing. def gem_install_dir Bundler.install_path end diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index d749694952..18eb18160d 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -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 + @amount_constrained[dependency.name] ||= 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 + 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 diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb index 87b9772c27..df2dcdb454 100644 --- a/lib/bundler/rubygems_gem_installer.rb +++ b/lib/bundler/rubygems_gem_installer.rb @@ -90,6 +90,14 @@ module Bundler end end + def spec + if Bundler.rubygems.provides?("< 3.3.12") # RubyGems implementation rescues and re-raises errors before 3.3.12 and we don't want that + @package.spec + else + super + end + end + private def strict_rm_rf(dir) diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb index 1c2b374d8b..a6180d5160 100644 --- a/lib/bundler/rubygems_integration.rb +++ b/lib/bundler/rubygems_integration.rb @@ -203,20 +203,9 @@ module Bundler EXT_LOCK end - def spec_from_gem(path, policy = nil) - require "rubygems/security" - require "psych" - gem_from_path(path, security_policies[policy]).spec - rescue Exception, Gem::Exception, Gem::Security::Exception => e # rubocop:disable Lint/RescueException - if e.is_a?(Gem::Security::Exception) || - e.message =~ /unknown trust policy|unsigned gem/i || - e.message =~ /couldn't verify (meta)?data signature/i - raise SecurityError, - "The gem #{File.basename(path, ".gem")} can't be installed because " \ - "the security policy didn't allow it, with the message: #{e.message}" - else - raise e - end + def spec_from_gem(path) + require "rubygems/package" + Gem::Package.new(path).spec end def build_gem(gem_dir, spec) @@ -514,13 +503,6 @@ module Bundler Gem::RemoteFetcher.new(proxy) end - def gem_from_path(path, policy = nil) - require "rubygems/package" - p = Gem::Package.new(path) - p.security_policy = policy if policy - p - end - def build(spec, skip_validation = false) require "rubygems/package" Gem::Package.build(spec, skip_validation) diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb index eb82544b86..ed66dcdc12 100644 --- a/lib/bundler/source/git.rb +++ b/lib/bundler/source/git.rb @@ -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 + @cache_path ||= 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 def app_cache_dirname diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index 5dceacbae4..f78e6a443b 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -139,13 +139,9 @@ module Bundler force = options[:force] ensure_builtin_gems_cached = options[:ensure_builtin_gems_cached] - if ensure_builtin_gems_cached && spec.default_gem? - if !cached_path(spec) - cached_built_in_gem(spec) unless spec.remote - force = true - else - spec.loaded_from = loaded_from(spec) - end + if ensure_builtin_gems_cached && spec.default_gem? && !cached_path(spec) + cached_built_in_gem(spec) unless spec.remote + force = true end if installed?(spec) && !force @@ -153,84 +149,90 @@ module Bundler return nil # no post-install message end - # Download the gem to get the spec, because some specs that are returned - # by rubygems.org are broken and wrong. if spec.remote # Check for this spec from other sources - uris = [spec.remote.anonymized_uri] - uris += remotes_for_spec(spec).map(&:anonymized_uri) - uris.uniq! + uris = [spec.remote, *remotes_for_spec(spec)].map(&:anonymized_uri).uniq Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1 path = fetch_gem(spec, options[:previous_spec]) - begin - s = Bundler.rubygems.spec_from_gem(path, Bundler.settings["trust-policy"]) - spec.__swap__(s) + else + path = cached_gem(spec) + raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path + end + + if requires_sudo? + install_path = Bundler.tmp(spec.full_name) + bin_path = install_path.join("bin") + else + install_path = rubygems_dir + bin_path = Bundler.system_bindir + end + + Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5") + + require_relative "../rubygems_gem_installer" + + installer = Bundler::RubyGemsGemInstaller.at( + path, + :security_policy => Bundler.rubygems.security_policies[Bundler.settings["trust-policy"]], + :install_dir => install_path.to_s, + :bin_dir => bin_path.to_s, + :ignore_dependencies => true, + :wrappers => true, + :env_shebang => true, + :build_args => options[:build_args], + :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum, + :bundler_extension_cache_path => extension_cache_path(spec) + ) + + if spec.remote + s = begin + installer.spec rescue Gem::Package::FormatError Bundler.rm_rf(path) raise + rescue Gem::Security::Exception => e + raise SecurityError, + "The gem #{File.basename(path, ".gem")} can't be installed because " \ + "the security policy didn't allow it, with the message: #{e.message}" end + + spec.__swap__(s) end - unless Bundler.settings[:no_install] - message = "Installing #{version_message(spec, options[:previous_spec])}" - message += " with native extensions" if spec.extensions.any? - Bundler.ui.confirm message + message = "Installing #{version_message(spec, options[:previous_spec])}" + message += " with native extensions" if spec.extensions.any? + Bundler.ui.confirm message - path = cached_gem(spec) - raise GemNotFound, "Could not find #{spec.file_name} for installation" unless path - if requires_sudo? - install_path = Bundler.tmp(spec.full_name) - bin_path = install_path.join("bin") - else - install_path = rubygems_dir - bin_path = Bundler.system_bindir + installed_spec = installer.install + + spec.full_gem_path = installed_spec.full_gem_path + spec.loaded_from = installed_spec.loaded_from + + # SUDO HAX + if requires_sudo? + Bundler.rubygems.repository_subdirectories.each do |name| + src = File.join(install_path, name, "*") + dst = File.join(rubygems_dir, name) + if name == "extensions" && Dir.glob(src).any? + src = File.join(src, "*/*") + ext_src = Dir.glob(src).first + ext_src.gsub!(src[0..-6], "") + dst = File.dirname(File.join(dst, ext_src)) + end + SharedHelpers.filesystem_access(dst) do |p| + Bundler.mkdir_p(p) + end + Bundler.sudo "cp -R #{src} #{dst}" if Dir[src].any? end - Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5") - - require_relative "../rubygems_gem_installer" - - installed_spec = Bundler::RubyGemsGemInstaller.at( - path, - :install_dir => install_path.to_s, - :bin_dir => bin_path.to_s, - :ignore_dependencies => true, - :wrappers => true, - :env_shebang => true, - :build_args => options[:build_args], - :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum, - :bundler_extension_cache_path => extension_cache_path(spec) - ).install - spec.full_gem_path = installed_spec.full_gem_path - - # SUDO HAX - if requires_sudo? - Bundler.rubygems.repository_subdirectories.each do |name| - src = File.join(install_path, name, "*") - dst = File.join(rubygems_dir, name) - if name == "extensions" && Dir.glob(src).any? - src = File.join(src, "*/*") - ext_src = Dir.glob(src).first - ext_src.gsub!(src[0..-6], "") - dst = File.dirname(File.join(dst, ext_src)) - end - SharedHelpers.filesystem_access(dst) do |p| - Bundler.mkdir_p(p) - end - Bundler.sudo "cp -R #{src} #{dst}" if Dir[src].any? - end - - spec.executables.each do |exe| - SharedHelpers.filesystem_access(Bundler.system_bindir) do |p| - Bundler.mkdir_p(p) - end - Bundler.sudo "cp -R #{install_path}/bin/#{exe} #{Bundler.system_bindir}/" + spec.executables.each do |exe| + SharedHelpers.filesystem_access(Bundler.system_bindir) do |p| + Bundler.mkdir_p(p) end + Bundler.sudo "cp -R #{install_path}/bin/#{exe} #{Bundler.system_bindir}/" end - installed_spec.loaded_from = loaded_from(spec) end - spec.loaded_from = loaded_from(spec) spec.post_install_message ensure @@ -348,10 +350,6 @@ module Bundler end end - def loaded_from(spec) - "#{rubygems_dir}/specifications/#{spec.full_name}.gemspec" - end - def cached_gem(spec) if spec.default_gem? cached_built_in_gem(spec) @@ -364,10 +362,14 @@ module Bundler global_cache_path = download_cache_path(spec) @caches << global_cache_path if global_cache_path - possibilities = @caches.map {|p| "#{p}/#{spec.file_name}" } + possibilities = @caches.map {|p| package_path(p, spec) } possibilities.find {|p| File.exist?(p) } end + def package_path(cache_path, spec) + "#{cache_path}/#{spec.file_name}" + end + def normalize_uri(uri) uri = uri.to_s uri = "#{uri}/" unless uri =~ %r{/$} @@ -459,12 +461,11 @@ module Bundler end def fetch_gem(spec, previous_spec = nil) - return false unless spec.remote - spec.fetch_platform cache_path = download_cache_path(spec) || default_cache_path_for(rubygems_dir) - gem_path = "#{cache_path}/#{spec.file_name}" + gem_path = package_path(cache_path, spec) + return gem_path if File.exist?(gem_path) if requires_sudo? download_path = Bundler.tmp(spec.full_name) @@ -482,7 +483,7 @@ module Bundler SharedHelpers.filesystem_access(cache_path) do |p| Bundler.mkdir_p(p) end - Bundler.sudo "mv #{download_cache_path}/#{spec.file_name} #{gem_path}" + Bundler.sudo "mv #{package_path(download_cache_path, spec)} #{gem_path}" end gem_path diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb index 9e8fa48a1d..a9a2934be8 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module Bundler - VERSION = "2.3.15".freeze + VERSION = "2.3.16".freeze def self.bundler_major_version @bundler_major_version ||= VERSION.split(".").first.to_i diff --git a/lib/rubygems.rb b/lib/rubygems.rb index 8c2c465ad4..1dd8e27486 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = "3.3.15".freeze + VERSION = "3.3.16".freeze end # Must be first since it unloads the prelude from 1.9.2 @@ -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' diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb index adf2cdba84..87563accb0 100644 --- a/lib/rubygems/commands/install_command.rb +++ b/lib/rubygems/commands/install_command.rb @@ -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}" + msg = "Unable to pull data from '#{Gem::Uri.redact(x.source.uri)}': #{x.error.message}" alert_warning msg end diff --git a/lib/rubygems/commands/sources_command.rb b/lib/rubygems/commands/sources_command.rb index 9e74f3c47d..35fba1bd04 100644 --- a/lib/rubygems/commands/sources_command.rb +++ b/lib/rubygems/commands/sources_command.rb @@ -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}" + say "Error fetching #{Gem::Uri.redact(source.uri)}:\n\t#{e.message}" terminate_interaction 1 end end diff --git a/lib/rubygems/core_ext/kernel_require.rb b/lib/rubygems/core_ext/kernel_require.rb index 4b867c55e9..23badd75d2 100644 --- a/lib/rubygems/core_ext/kernel_require.rb +++ b/lib/rubygems/core_ext/kernel_require.rb @@ -18,7 +18,7 @@ module Kernel end file = Gem::KERNEL_WARN_IGNORES_INTERNAL_ENTRIES ? "" : __FILE__ - module_eval <<'RUBY', file, __LINE__ + 1 + module_eval <<'RUBY', file, __LINE__ + 1 # rubocop:disable Style/EvalWithLocation ## # When RubyGems is required, Kernel#require is replaced with our own which # is capable of loading gems on demand. diff --git a/lib/rubygems/errors.rb b/lib/rubygems/errors.rb index f115ce23d0..e6e222033d 100644 --- a/lib/rubygems/errors.rb +++ b/lib/rubygems/errors.rb @@ -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}" + "Unable to download data from #{Gem::Uri.redact(@source.uri)} - #{@error.message}" end ## diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb index d9aa68c067..e9986a3fc8 100644 --- a/lib/rubygems/ext/builder.rb +++ b/lib/rubygems/ext/builder.rb @@ -48,7 +48,7 @@ class Gem::Ext::Builder end end - def self.run(command, results, command_name = nil, dir = Dir.pwd) + def self.run(command, results, command_name = nil, dir = Dir.pwd, env = {}) verbose = Gem.configuration.really_verbose begin @@ -63,9 +63,9 @@ class Gem::Ext::Builder require "open3" # Set $SOURCE_DATE_EPOCH for the subprocess. - env = {'SOURCE_DATE_EPOCH' => Gem.source_date_epoch_string} + build_env = { 'SOURCE_DATE_EPOCH' => Gem.source_date_epoch_string }.merge(env) output, status = begin - Open3.capture2e(env, *command, :chdir => dir) + Open3.capture2e(build_env, *command, :chdir => dir) rescue => error raise Gem::InstallError, "#{command_name || class_name} failed#{error.message}" end diff --git a/lib/rubygems/ext/cargo_builder.rb b/lib/rubygems/ext/cargo_builder.rb index 4c16063224..8465e9ef05 100644 --- a/lib/rubygems/ext/cargo_builder.rb +++ b/lib/rubygems/ext/cargo_builder.rb @@ -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 + attr_accessor :spec, :runner, :profile def initialize(spec) + require_relative "../command" + require_relative "cargo_builder/link_flag_converter" + @spec = spec + @runner = self.class.method(:run) + @profile = :release 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) + validate_cargo_build!(dest_path) + rename_cdylib_for_ruby_compatibility(dest_path) + finalize_directory(dest_path, lib_dir, cargo_dir) results end - private - def build_crate(dest_path, results, args, cargo_dir) + env = build_env + cmd = cargo_command(cargo_dir, dest_path, args) + runner.call cmd, results, 'cargo', cargo_dir, env + + results + end + + def build_env + build_env = rb_config_env + build_env["RUBY_STATIC"] = "true" if ruby_static? && ENV.key?('RUBY_STATIC') + build_env + end + + def cargo_command(cargo_dir, dest_path, args = []) 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", ENV['CARGO_BUILD_TARGET']] if ENV['CARGO_BUILD_TARGET'] cmd += ["--target-dir", dest_path] cmd += ["--manifest-path", manifest] - cmd += ["--lib", "--release", "--locked"] - cmd += ["--"] - cmd += [*cargo_rustc_args(dest_path)] + cmd += ["--lib"] + cmd += ["--profile", profile.to_s] + cmd += ["--locked"] if profile == :release cmd += Gem::Command.build_args cmd += args + cmd += ["--"] + cmd += [*cargo_rustc_args(dest_path)] + cmd + end - self.class.run cmd, results, self.class.class_name, cargo_dir - results - ensure - ENV["RUBY_STATIC"] = given_ruby_static + private + + def rb_config_env + result = {} + RbConfig::CONFIG.each {|k, v| result["RBCONFIG_#{k}"] = v } + result 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) } + raw_libs.flat_map {|l| ldflag_to_link_modifier(l) } 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 + new_path = final_extension_path(dest_path) + FileUtils.cp(cargo_dylib_path(dest_path), new_path) + new_path end def validate_cargo_build!(dir) - prefix = so_ext == "dll" ? "" : "lib" - dylib_path = File.join(dir, "release", "#{prefix}#{cargo_crate_name}.#{so_ext}") + dylib_path = cargo_dylib_path(dir) raise DylibNotFoundError, dir unless File.exist?(dylib_path) dylib_path end + def final_extension_path(dest_path) + dylib_path = cargo_dylib_path(dest_path) + dlext_name = "#{spec.name}.#{makefile_config("DLEXT")}" + dylib_path.gsub(File.basename(dylib_path), dlext_name) + end + + def cargo_dylib_path(dest_path) + prefix = so_ext == "dll" ? "" : "lib" + path_parts = [dest_path] + path_parts << ENV['CARGO_BUILD_TARGET'] if ENV['CARGO_BUILD_TARGET'] + path_parts += [profile_target_directory, "#{prefix}#{cargo_crate_name}.#{so_ext}"] + File.join(*path_parts) + 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) } + .flat_map {|arg| ldflag_to_link_modifier(arg) } end def rustc_lib_flags(dest_dir) - split_flags("LIBS").flat_map {|arg| ldflag_to_link_modifier(arg, dest_dir) } + split_flags("LIBS").flat_map {|arg| ldflag_to_link_modifier(arg) } 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://github.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 + def ldflag_to_link_modifier(arg) + LinkFlagConverter.convert(arg) 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)) + # Interpolate 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 + var_matches = input_arg.match(/\$\((\w+)\)/) - str == "" ? nil : str + return input_arg unless var_matches + + var_name = var_matches[1] + + return input_arg if var_name.nil? || var_name.chomp.empty? + + 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 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 + return [] if profile == :dev + ["-C", "debuginfo=1"] end # Copied from ExtConfBuilder - def finalize_directory(ext_path, dest_path, lib_dir, extension_dir) + def finalize_directory(dest_path, lib_dir, extension_dir) require "fileutils" require "tempfile" + ext_path = final_extension_path(dest_path) + begin tmp_dest = Dir.mktmpdir(".gem.", extension_dir) @@ -287,6 +302,14 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder path end + def profile_target_directory + case profile + when :release then 'release' + when :dev then 'debug' + else raise "unknown target directory for profile: #{profile}" + end + end + # Error raised when no cdylib artifact was created class DylibNotFoundError < StandardError def initialize(dir) diff --git a/lib/rubygems/ext/cargo_builder/link_flag_converter.rb b/lib/rubygems/ext/cargo_builder/link_flag_converter.rb new file mode 100644 index 0000000000..111bb05492 --- /dev/null +++ b/lib/rubygems/ext/cargo_builder/link_flag_converter.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +class Gem::Ext::CargoBuilder < Gem::Ext::Builder + # Converts Ruby link flags into something cargo understands + class LinkFlagConverter + def self.convert(arg) + case arg.chomp + when /^-L\s*(.+)$/ + ["-L", "native=#{$1}"] + when /^--library=(\w+\S+)$/, /^-l\s*(\w+\S+)$/ + ["-l", $1] + when /^-l\s*:lib(\S+).a$/ + ["-l", "static=#{$1}"] + when /^-l\s*:lib(\S+).(so|dylib|dll)$/ + ["-l", "dylib=#{$1}"] + when /^-F\s*(.*)$/ + ["-l", "framework=#{$1}"] + else + ["-C", "link_arg=#{arg}"] + end + end + end +end diff --git a/lib/rubygems/gemcutter_utilities.rb b/lib/rubygems/gemcutter_utilities.rb index 7cb5fe9448..af0d957bc8 100644 --- a/lib/rubygems/gemcutter_utilities.rb +++ b/lib/rubygems/gemcutter_utilities.rb @@ -135,7 +135,7 @@ module Gem::GemcutterUtilities sign_in_host, scope: scope) do |request| request.basic_auth email, password request["OTP"] = otp if otp - request.body = URI.encode_www_form({:api_key => api_key }.merge(update_scope_params)) + request.body = URI.encode_www_form({ :api_key => api_key }.merge(update_scope_params)) end with_response response do |resp| diff --git a/lib/rubygems/psych_additions.rb b/lib/rubygems/psych_additions.rb deleted file mode 100644 index a13c1ec676..0000000000 --- a/lib/rubygems/psych_additions.rb +++ /dev/null @@ -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 diff --git a/lib/rubygems/request.rb b/lib/rubygems/request.rb index 136b154bee..6d6c2d8de8 100644 --- a/lib/rubygems/request.rb +++ b/lib/rubygems/request.rb @@ -193,7 +193,7 @@ class Gem::Request begin @requests[connection.object_id] += 1 - verbose "#{request.method} #{Gem::Uri.new(@uri).redacted}" + verbose "#{request.method} #{Gem::Uri.redact(@uri)}" file_name = File.basename(@uri.path) # perform download progress reporter only for gems diff --git a/lib/rubygems/source.rb b/lib/rubygems/source.rb index 85c300a8f8..5f49a0d216 100644 --- a/lib/rubygems/source.rb +++ b/lib/rubygems/source.rb @@ -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 + require_relative "uri" + @uri = Gem::Uri.parse!(uri) @update_cache = nil end diff --git a/lib/rubygems/source/git.rb b/lib/rubygems/source/git.rb index 8d5dc1f69d..1d964eb59a 100644 --- a/lib/rubygems/source/git.rb +++ b/lib/rubygems/source/git.rb @@ -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 - + require_relative "../uri" + @uri = Gem::Uri.parse(repository) @name = name @repository = repository @reference = reference diff --git a/lib/rubygems/source_list.rb b/lib/rubygems/source_list.rb index 16e90e1ef7..7abe796409 100644 --- a/lib/rubygems/source_list.rb +++ b/lib/rubygems/source_list.rb @@ -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)) + Gem::Source.new(obj) end @sources << src unless @sources.include?(src) diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 33eb0a2bff..01aa8fd942 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -157,7 +157,7 @@ class Gem::Specification < Gem::BasicSpecification }.freeze # rubocop:disable Style/MutableConstant - INITIALIZE_CODE_FOR_DEFAULTS = { } # :nodoc: + INITIALIZE_CODE_FOR_DEFAULTS = {} # :nodoc: # rubocop:enable Style/MutableConstant @@default_value.each do |k,v| @@ -1082,6 +1082,7 @@ class Gem::Specification < Gem::BasicSpecification spec.specification_version ||= NONEXISTENT_SPECIFICATION_VERSION spec.reset_nil_attributes_to_default + spec.flatten_require_paths spec end @@ -1273,10 +1274,26 @@ class Gem::Specification < Gem::BasicSpecification array = begin Marshal.load str rescue ArgumentError => e - raise unless e.message.include?("YAML") + # + # Some very old marshaled specs included references to `YAML::PrivateType` + # and `YAML::Syck::DefaultKey` constants due to bugs in the old emitter + # that generated them. Workaround the issue by defining the necessary + # constants and retrying. + # + message = e.message + raise unless message.include?("YAML::") - Object.const_set "YAML", Psych - Marshal.load str + Object.const_set "YAML", Psych unless Object.const_defined?(:YAML) + + if message.include?("YAML::Syck::") + YAML.const_set "Syck", YAML unless YAML.const_defined?(:Syck) + + YAML::Syck.const_set "DefaultKey", Class.new if message.include?("YAML::Syck::DefaultKey") + elsif message.include?("YAML::PrivateType") + YAML.const_set "PrivateType", Class.new + end + + retry end spec = Gem::Specification.new @@ -2676,6 +2693,13 @@ class Gem::Specification < Gem::BasicSpecification @installed_by_version ||= nil end + def flatten_require_paths # :nodoc: + return unless raw_require_paths.first.is_a?(Array) + + warn "#{name} #{version} includes a gemspec with `require_paths` set to an array of arrays. Newer versions of this gem might've already fixed this" + raw_require_paths.flatten! + end + def raw_require_paths # :nodoc: @require_paths end diff --git a/lib/rubygems/specification_policy.rb b/lib/rubygems/specification_policy.rb index 002b3c20c4..8b5d01dda2 100644 --- a/lib/rubygems/specification_policy.rb +++ b/lib/rubygems/specification_policy.rb @@ -154,7 +154,7 @@ class Gem::SpecificationPolicy def validate_duplicate_dependencies # :nodoc: # NOTE: see REFACTOR note in Gem::Dependency about types - this might be brittle - seen = Gem::Dependency::TYPES.inject({}) {|types, type| types.merge({ type => {}}) } + seen = Gem::Dependency::TYPES.inject({}) {|types, type| types.merge({ type => {} }) } error_messages = [] @specification.dependencies.each do |dep| diff --git a/lib/rubygems/uri.rb b/lib/rubygems/uri.rb index ba30fac2f5..6acb9041f9 100644 --- a/lib/rubygems/uri.rb +++ b/lib/rubygems/uri.rb @@ -5,6 +5,44 @@ # class Gem::Uri + ## + # Parses and redacts uri + + def self.redact(uri) + new(uri).redacted + end + + ## + # Parses uri, raising if it's invalid + + def self.parse!(uri) + require "uri" + + raise URI::InvalidURIError unless uri + + return uri unless uri.is_a?(String) + + # 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 uri, returning the original uri if it's invalid + + def self.parse(uri) + parse!(uri) + rescue URI::InvalidURIError + uri + end + 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? + return text unless valid_uri? && password? && text.include?(to_s) 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 + self.class.parse!(uri) 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 + self.class.parse(uri) end def with_redacted_user diff --git a/lib/rubygems/util.rb b/lib/rubygems/util.rb index 4363c5adce..9fd78ab2bc 100644 --- a/lib/rubygems/util.rb +++ b/lib/rubygems/util.rb @@ -60,7 +60,7 @@ module Gem::Util # Invokes system, but silences all output. def self.silent_system(*command) - opt = {:out => IO::NULL, :err => [:child, :out]} + opt = { :out => IO::NULL, :err => [:child, :out] } if Hash === command.last opt.update(command.last) cmds = command[0...-1] diff --git a/spec/bundler/bundler/dsl_spec.rb b/spec/bundler/bundler/dsl_spec.rb index 4802b62a58..19c8f2e889 100644 --- a/spec/bundler/bundler/dsl_spec.rb +++ b/spec/bundler/bundler/dsl_spec.rb @@ -137,6 +137,7 @@ RSpec.describe Bundler::Dsl do end describe "#gem" do + # rubocop:disable Naming/VariableNumber [:ruby, :ruby_18, :ruby_19, :ruby_20, :ruby_21, :ruby_22, :ruby_23, :ruby_24, :ruby_25, :ruby_26, :ruby_27, :ruby_30, :ruby_31, :mri, :mri_18, :mri_19, :mri_20, :mri_21, :mri_22, :mri_23, :mri_24, :mri_25, :mri_26, :mri_27, :mri_30, :mri_31, :jruby, :rbx, :truffleruby].each do |platform| @@ -144,6 +145,7 @@ RSpec.describe Bundler::Dsl do subject.gem("foo", :platform => platform) end end + # rubocop:enable Naming/VariableNumber it "rejects invalid platforms" do expect { subject.gem("foo", :platform => :bogus) }. diff --git a/spec/bundler/bundler/plugin_spec.rb b/spec/bundler/bundler/plugin_spec.rb index 8a1a6cd97a..d28479cf31 100644 --- a/spec/bundler/bundler/plugin_spec.rb +++ b/spec/bundler/bundler/plugin_spec.rb @@ -280,12 +280,12 @@ RSpec.describe Bundler::Plugin do end Bundler::Plugin::Events.send(:reset) - Bundler::Plugin::Events.send(:define, :EVENT_1, "event-1") - Bundler::Plugin::Events.send(:define, :EVENT_2, "event-2") + Bundler::Plugin::Events.send(:define, :EVENT1, "event-1") + Bundler::Plugin::Events.send(:define, :EVENT2, "event-2") - allow(index).to receive(:hook_plugins).with(Bundler::Plugin::Events::EVENT_1). + allow(index).to receive(:hook_plugins).with(Bundler::Plugin::Events::EVENT1). and_return(["foo-plugin", "", nil]) - allow(index).to receive(:hook_plugins).with(Bundler::Plugin::Events::EVENT_2). + allow(index).to receive(:hook_plugins).with(Bundler::Plugin::Events::EVENT2). and_return(["foo-plugin"]) allow(index).to receive(:plugin_path).with("foo-plugin").and_return(path) allow(index).to receive(:load_paths).with("foo-plugin").and_return([]) @@ -303,33 +303,33 @@ RSpec.describe Bundler::Plugin do it "executes the hook" do expect do - Plugin.hook(Bundler::Plugin::Events::EVENT_1) + Plugin.hook(Bundler::Plugin::Events::EVENT1) end.to output("hook for event 1\n").to_stdout end context "single plugin declaring more than one hook" do let(:code) { <<-RUBY } - Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT_1) {} - Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT_2) {} + Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT1) {} + Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT2) {} puts "loaded" RUBY it "evals plugins.rb once" do expect do - Plugin.hook(Bundler::Plugin::Events::EVENT_1) - Plugin.hook(Bundler::Plugin::Events::EVENT_2) + Plugin.hook(Bundler::Plugin::Events::EVENT1) + Plugin.hook(Bundler::Plugin::Events::EVENT2) end.to output("loaded\n").to_stdout end end context "a block is passed" do let(:code) { <<-RUBY } - Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT_1) { |&blk| blk.call } + Bundler::Plugin::API.hook(Bundler::Plugin::Events::EVENT1) { |&blk| blk.call } RUBY it "is passed to the hook" do expect do - Plugin.hook(Bundler::Plugin::Events::EVENT_1) { puts "win" } + Plugin.hook(Bundler::Plugin::Events::EVENT1) { puts "win" } end.to output("win\n").to_stdout end end diff --git a/spec/bundler/install/gemfile/platform_spec.rb b/spec/bundler/install/gemfile/platform_spec.rb index cf80844b02..68d794ed84 100644 --- a/spec/bundler/install/gemfile/platform_spec.rb +++ b/spec/bundler/install/gemfile/platform_spec.rb @@ -466,11 +466,9 @@ RSpec.describe "bundle install with platform conditionals" do it "does not attempt to install gems from other rubies when using --local" do bundle "config set --local force_ruby_platform true" - other_ruby_version_tag = RUBY_VERSION =~ /^1\.8/ ? :ruby_19 : :ruby_18 - gemfile <<-G source "#{file_uri_for(gem_repo1)}" - gem "some_gem", platform: :#{other_ruby_version_tag} + gem "some_gem", platform: :ruby_22 G bundle "install --local" diff --git a/spec/bundler/install/gems/flex_spec.rb b/spec/bundler/install/gems/flex_spec.rb index 28ffaff3d5..ed61531574 100644 --- a/spec/bundler/install/gems/flex_spec.rb +++ b/spec/bundler/install/gems/flex_spec.rb @@ -230,7 +230,6 @@ RSpec.describe "bundle flex_install" do gem "jekyll-feed", "~> 0.12" G - puts lockfile lockfile <<-L GEM remote: #{file_uri_for(gem_repo4)}/ diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb index df5eeda9fe..30c922efb0 100644 --- a/spec/bundler/realworld/edgecases_spec.rb +++ b/spec/bundler/realworld/edgecases_spec.rb @@ -196,7 +196,7 @@ RSpec.describe "real world edgecases", :realworld => true do expect(lockfile).to include(rubygems_version("paperclip", "~> 5.1.0")) end - it "outputs a helpful error message when gems have invalid gemspecs" do + it "outputs a helpful error message when gems have invalid gemspecs", :rubygems => "< 3.3.16" do install_gemfile <<-G, :standalone => true, :raise_on_error => false, :env => { "BUNDLE_FORCE_RUBY_PLATFORM" => "1" } source 'https://rubygems.org' gem "resque-scheduler", "2.2.0" @@ -207,6 +207,16 @@ RSpec.describe "real world edgecases", :realworld => true do expect(err).to include("resque-scheduler 2.2.0 has an invalid gemspec") end + it "outputs a helpful warning when gems have a gemspec with invalid `require_paths`", :rubygems => ">= 3.3.16" do + install_gemfile <<-G, :standalone => true, :env => { "BUNDLE_FORCE_RUBY_PLATFORM" => "1" } + source 'https://rubygems.org' + gem "resque-scheduler", "2.2.0" + gem "redis-namespace", "1.6.0" # for a consistent resolution including ruby 2.3.0 + gem "ruby2_keywords", "0.0.5" + G + expect(err).to include("resque-scheduler 2.2.0 includes a gemspec with `require_paths` set to an array of arrays. Newer versions of this gem might've already fixed this").once + end + it "doesn't hang on big gemfile" do skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM =~ /darwin/ diff --git a/spec/bundler/realworld/slow_perf_spec.rb b/spec/bundler/realworld/slow_perf_spec.rb index aced5a1641..9f11821bf5 100644 --- a/spec/bundler/realworld/slow_perf_spec.rb +++ b/spec/bundler/realworld/slow_perf_spec.rb @@ -17,6 +17,6 @@ RSpec.describe "bundle install with complex dependencies", :realworld => true do duration = Time.now - start_time - expect(duration.to_f).to be < 12 # seconds + expect(duration.to_f).to be < 18 # seconds end end diff --git a/test/rubygems/data/excon-0.7.7.gemspec.rz b/test/rubygems/data/excon-0.7.7.gemspec.rz new file mode 100644 index 0000000000..159bd4bb1c Binary files /dev/null and b/test/rubygems/data/excon-0.7.7.gemspec.rz differ diff --git a/test/rubygems/data/null-type.gemspec.rz b/test/rubygems/data/pry-0.4.7.gemspec.rz similarity index 100% rename from test/rubygems/data/null-type.gemspec.rz rename to test/rubygems/data/pry-0.4.7.gemspec.rz diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb index a0b2c98505..75eed7be6b 100644 --- a/test/rubygems/helper.rb +++ b/test/rubygems/helper.rb @@ -618,7 +618,7 @@ class Gem::TestCase < Test::Unit::TestCase gem = File.join(@tempdir, File.basename(gem)).tap(&Gem::UNTAINT) end - Gem::Installer.at(gem, options.merge({:wrappers => true})).install + Gem::Installer.at(gem, options.merge({ :wrappers => true })).install end ## @@ -1191,7 +1191,7 @@ Also, a list: # Is this test being run on a ruby/ruby repository? # - def testing_ruby_repo? + def ruby_repo? !ENV["GEM_COMMAND"].nil? end diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index 53fb058e99..4d9644d5c9 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -1430,7 +1430,7 @@ class TestGem < Gem::TestCase a = util_spec "a", "1" b = util_spec "b", "1", "c" => nil c = util_spec "c", "2" - d = util_spec "d", "1", {'e' => '= 1'}, "lib/d#{$$}.rb" + d = util_spec "d", "1", { 'e' => '= 1' }, "lib/d#{$$}.rb" e = util_spec "e", "1" install_specs a, c, b, e, d diff --git a/test/rubygems/test_gem_commands_sources_command.rb b/test/rubygems/test_gem_commands_sources_command.rb index 7bca0f3803..6a5d8b06f5 100644 --- a/test/rubygems/test_gem_commands_sources_command.rb +++ b/test/rubygems/test_gem_commands_sources_command.rb @@ -202,6 +202,56 @@ Error fetching http://beta-gems.example.com: assert_equal '', @ui.error end + def test_execute_add_existent_source_invalid_uri + spec_fetcher + + uri = "https://u:p@example.com/specs.#{@marshal_version}.gz" + + @cmd.handle_options %w[--add https://u:p@example.com] + @fetcher.data[uri] = proc do + raise Gem::RemoteFetcher::FetchError.new('it died', uri) + end + + use_ui @ui do + assert_raise Gem::MockGemUi::TermError do + @cmd.execute + end + end + + expected = <<-EOF +Error fetching https://u:REDACTED@example.com: +\tit died (https://u:REDACTED@example.com/specs.#{@marshal_version}.gz) + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + end + + def test_execute_add_existent_source_invalid_uri_with_error_by_chance_including_the_uri_password + spec_fetcher + + uri = "https://u:secret@example.com/specs.#{@marshal_version}.gz" + + @cmd.handle_options %w[--add https://u:secret@example.com] + @fetcher.data[uri] = proc do + raise Gem::RemoteFetcher::FetchError.new('it secretly died', uri) + end + + use_ui @ui do + assert_raise Gem::MockGemUi::TermError do + @cmd.execute + end + end + + expected = <<-EOF +Error fetching https://u:REDACTED@example.com: +\tit secretly died (https://u:REDACTED@example.com/specs.#{@marshal_version}.gz) + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + end + def test_execute_add_redundant_source spec_fetcher diff --git a/test/rubygems/test_gem_config_file.rb b/test/rubygems/test_gem_config_file.rb index 32375e6936..3e09079df8 100644 --- a/test/rubygems/test_gem_config_file.rb +++ b/test/rubygems/test_gem_config_file.rb @@ -190,7 +190,7 @@ class TestGemConfigFile < Gem::TestCase util_config_file - assert_equal({:rubygems => '701229f217cdf23b1344c7b4b54ca97'}, + assert_equal({ :rubygems => '701229f217cdf23b1344c7b4b54ca97' }, @cfg.api_keys) end @@ -317,8 +317,8 @@ if you believe they were disclosed to a third party. util_config_file - assert_equal({:rubygems => '701229f217cdf23b1344c7b4b54ca97', - :other => 'a5fdbb6ba150cbb83aad2bb2fede64c'}, @cfg.api_keys) + assert_equal({ :rubygems => '701229f217cdf23b1344c7b4b54ca97', + :other => 'a5fdbb6ba150cbb83aad2bb2fede64c' }, @cfg.api_keys) end def test_load_api_keys_bad_permission diff --git a/test/rubygems/test_gem_ext_cargo_builder.rb b/test/rubygems/test_gem_ext_cargo_builder.rb index 559a31f5ad..2da98c03e2 100644 --- a/test/rubygems/test_gem_ext_cargo_builder.rb +++ b/test/rubygems/test_gem_ext_cargo_builder.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + require_relative 'helper' require 'rubygems/ext' @@ -7,12 +8,9 @@ class TestGemExtCargoBuilder < Gem::TestCase super @rust_envs = { - 'CARGO_HOME' => File.join(@orig_env['HOME'], '.cargo'), - 'RUSTUP_HOME' => File.join(@orig_env['HOME'], '.rustup'), + 'CARGO_HOME' => ENV.fetch('CARGO_HOME', File.join(@orig_env['HOME'], '.cargo')), + 'RUSTUP_HOME' => ENV.fetch('RUSTUP_HOME', File.join(@orig_env['HOME'], '.rustup')), } - - system(@rust_envs, 'cargo', '-V', out: IO::NULL, err: [:child, :out]) - pend 'cargo not present' unless $?.success? end def setup_rust_gem(name) @@ -57,15 +55,35 @@ class TestGemExtCargoBuilder < Gem::TestCase end output = output.join "\n" - bundle = File.join(@dest_path, "release/rust_ruby_example.#{RbConfig::CONFIG['DLEXT']}") - require(bundle) - - assert_match RustRubyExample.reverse('hello'), 'olleh' - - assert_match "Compiling rust_ruby_example v0.1.0", output assert_match "Finished release [optimized] target(s)", output + assert_ffi_handle bundle, 'Init_rust_ruby_example' + rescue Exception => e + pp output if output + + raise(e) + end + + def test_build_dev_profile + skip_unsupported_platforms! + setup_rust_gem "rust_ruby_example" + + output = [] + + Dir.chdir @ext do + ENV.update(@rust_envs) + spec = Gem::Specification.new 'rust_ruby_example', '0.1.0' + builder = Gem::Ext::CargoBuilder.new(spec) + builder.profile = :dev + builder.build nil, @dest_path, output + end + + output = output.join "\n" + bundle = File.join(@dest_path, "debug/rust_ruby_example.#{RbConfig::CONFIG['DLEXT']}") + + assert_match "Finished dev [unoptimized + debuginfo] target(s)", output + assert_ffi_handle bundle, 'Init_rust_ruby_example' rescue Exception => e pp output if output @@ -98,21 +116,23 @@ class TestGemExtCargoBuilder < Gem::TestCase skip_unsupported_platforms! setup_rust_gem "rust_ruby_example" + require 'open3' + Dir.chdir @ext do require 'tmpdir' - gem = [@rust_envs, *ruby_with_rubygems_in_load_path, File.expand_path('../../bin/gem', __dir__)] + env_for_subprocess = @rust_envs.merge("GEM_HOME" => Gem.paths.home) + gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path('../../bin/gem', __dir__)] Dir.mktmpdir("rust_ruby_example") do |dir| built_gem = File.expand_path(File.join(dir, "rust_ruby_example.gem")) Open3.capture2e(*gem, "build", "rust_ruby_example.gemspec", "--output", built_gem) Open3.capture2e(*gem, "install", "--verbose", "--local", built_gem, *ARGV) + + stdout_and_stderr_str, status = Open3.capture2e(env_for_subprocess, *ruby_with_rubygems_in_load_path, "-rrust_ruby_example", "-e", "puts 'Result: ' + RustRubyExample.reverse('hello world')") + assert status.success?, stdout_and_stderr_str + assert_match "Result: #{"hello world".reverse}", stdout_and_stderr_str end - - stdout_and_stderr_str, status = Open3.capture2e(@rust_envs, *ruby_with_rubygems_in_load_path, "-rrust_ruby_example", "-e", "puts 'Result: ' + RustRubyExample.reverse('hello world')") - - assert status.success?, stdout_and_stderr_str - assert_match "Result: #{"hello world".reverse}", stdout_and_stderr_str end end @@ -123,7 +143,8 @@ class TestGemExtCargoBuilder < Gem::TestCase Dir.chdir @ext do require 'tmpdir' - gem = [@rust_envs, *ruby_with_rubygems_in_load_path, File.expand_path('../../bin/gem', __dir__)] + env_for_subprocess = @rust_envs.merge("GEM_HOME" => Gem.paths.home) + gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path('../../bin/gem', __dir__)] Dir.mktmpdir("custom_name") do |dir| built_gem = File.expand_path(File.join(dir, "custom_name.gem")) @@ -131,17 +152,27 @@ class TestGemExtCargoBuilder < Gem::TestCase Open3.capture2e(*gem, "install", "--verbose", "--local", built_gem, *ARGV) end - stdout_and_stderr_str, status = Open3.capture2e(@rust_envs, *ruby_with_rubygems_in_load_path, "-rcustom_name", "-e", "puts 'Result: ' + CustomName.say_hello") + stdout_and_stderr_str, status = Open3.capture2e(env_for_subprocess, *ruby_with_rubygems_in_load_path, "-rcustom_name", "-e", "puts 'Result: ' + CustomName.say_hello") assert status.success?, stdout_and_stderr_str assert_match "Result: Hello world!", stdout_and_stderr_str end end + private + def skip_unsupported_platforms! pend "jruby not supported" if java_platform? pend "truffleruby not supported (yet)" if RUBY_ENGINE == 'truffleruby' pend "mswin not supported (yet)" if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') - pend "ruby.h is not provided by ruby repo" if testing_ruby_repo? + system(@rust_envs, 'cargo', '-V', out: IO::NULL, err: [:child, :out]) + pend 'cargo not present' unless $?.success? + pend "ruby.h is not provided by ruby repo" if ruby_repo? + end + + def assert_ffi_handle(bundle, name) + require 'fiddle' + dylib_handle = Fiddle.dlopen bundle + assert_nothing_raised { dylib_handle[name] } end end diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock index b1b94017b5..cb1bdb3c61 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock @@ -11,6 +11,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "atty" version = "0.2.14" @@ -22,16 +31,11 @@ dependencies = [ "winapi", ] -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - [[package]] name = "bindgen" version = "0.59.2" -source = "git+https://github.com/rust-lang/rust-bindgen?rev=f34e4103f304500c96d332f5cecc9067c980d0f9#f34e4103f304500c96d332f5cecc9067c980d0f9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" dependencies = [ "bitflags", "cexpr", @@ -56,6 +60,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + [[package]] name = "cexpr" version = "0.6.0" @@ -73,9 +83,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clang-sys" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" +checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b" dependencies = [ "glob", "libc", @@ -84,17 +94,17 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.5" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced1892c55c910c1219e98d6fc8d71f6bddba7905866ce740066d8bfea859312" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ + "ansi_term", "atty", "bitflags", - "indexmap", - "os_str_bytes", "strsim", - "termcolor", "textwrap", + "unicode-width", + "vec_map", ] [[package]] @@ -129,12 +139,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -150,16 +154,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "indexmap" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -174,9 +168,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.119" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "libloading" @@ -189,19 +183,28 @@ dependencies = [ ] [[package]] -name = "log" -version = "0.4.14" +name = "linkify" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "28d9967eb7d0bc31c39c6f52e8fce42991c0cd1f7a2078326f0b7a399a584c8d" +dependencies = [ + "memchr", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "minimal-lexical" @@ -211,22 +214,12 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "nom" -version = "7.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ "memchr", "minimal-lexical", - "version_check", -] - -[[package]] -name = "os_str_bytes" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", ] [[package]] @@ -237,43 +230,47 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] [[package]] name = "rb-sys" -version = "0.6.0" -source = "git+https://github.com/ianks/rb-sys?tag=v0.6.0#1aa5b589e86a14e01aba806511818c19f85d71f6" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5465c5bd695ef70959b91b4ca9cfd515e9af012f6d9f0ae46f09fa4bcc3b722" dependencies = [ "bindgen", - "libc", + "cc", + "lazy_static", + "linkify", "pkg-config", + "shell-words", ] [[package]] name = "regex" -version = "1.5.5" +version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" dependencies = [ "aho-corasick", "memchr", @@ -282,9 +279,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "rustc-hash" @@ -292,6 +289,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "shlex" version = "1.1.0" @@ -300,9 +303,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "strsim" -version = "0.10.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "termcolor" @@ -315,27 +318,36 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.15.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-ident" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" [[package]] -name = "version_check" -version = "0.9.4" +name = "unicode-width" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "which" -version = "4.2.4" +version = "4.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" dependencies = [ "either", "lazy_static", diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml index e0232f729d..cbc9225140 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml @@ -6,5 +6,4 @@ version = "0.1.0" crate-type = ["cdylib"] [dependencies] -# Needed until bindgen has the `allowlist_file` feature -rb-sys = { git = "https://github.com/ianks/rb-sys", tag = "v0.6.0" } +rb-sys = "0.9.4" diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock index accff220e5..edbeda8420 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock @@ -11,6 +11,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "atty" version = "0.2.14" @@ -22,16 +31,11 @@ dependencies = [ "winapi", ] -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - [[package]] name = "bindgen" version = "0.59.2" -source = "git+https://github.com/rust-lang/rust-bindgen?rev=f34e4103f304500c96d332f5cecc9067c980d0f9#f34e4103f304500c96d332f5cecc9067c980d0f9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" dependencies = [ "bitflags", "cexpr", @@ -56,6 +60,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + [[package]] name = "cexpr" version = "0.6.0" @@ -73,9 +83,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clang-sys" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" +checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b" dependencies = [ "glob", "libc", @@ -84,17 +94,17 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.5" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced1892c55c910c1219e98d6fc8d71f6bddba7905866ce740066d8bfea859312" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ + "ansi_term", "atty", "bitflags", - "indexmap", - "os_str_bytes", "strsim", - "termcolor", "textwrap", + "unicode-width", + "vec_map", ] [[package]] @@ -122,12 +132,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - [[package]] name = "hermit-abi" version = "0.1.19" @@ -143,16 +147,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "indexmap" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -167,9 +161,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.119" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "libloading" @@ -182,19 +176,28 @@ dependencies = [ ] [[package]] -name = "log" -version = "0.4.14" +name = "linkify" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "28d9967eb7d0bc31c39c6f52e8fce42991c0cd1f7a2078326f0b7a399a584c8d" +dependencies = [ + "memchr", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "minimal-lexical" @@ -204,22 +207,12 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "nom" -version = "7.1.0" +version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d11e1ef389c76fe5b81bcaf2ea32cf88b62bc494e19f493d0b30e7a930109" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ "memchr", "minimal-lexical", - "version_check", -] - -[[package]] -name = "os_str_bytes" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", ] [[package]] @@ -230,43 +223,47 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] [[package]] name = "rb-sys" -version = "0.6.0" -source = "git+https://github.com/ianks/rb-sys?tag=v0.6.0#1aa5b589e86a14e01aba806511818c19f85d71f6" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5465c5bd695ef70959b91b4ca9cfd515e9af012f6d9f0ae46f09fa4bcc3b722" dependencies = [ "bindgen", - "libc", + "cc", + "lazy_static", + "linkify", "pkg-config", + "shell-words", ] [[package]] name = "regex" -version = "1.5.5" +version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" dependencies = [ "aho-corasick", "memchr", @@ -275,9 +272,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "rust_ruby_example" @@ -292,6 +289,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "shlex" version = "1.1.0" @@ -300,9 +303,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "strsim" -version = "0.10.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "termcolor" @@ -315,27 +318,36 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.15.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-ident" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" [[package]] -name = "version_check" -version = "0.9.4" +name = "unicode-width" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "which" -version = "4.2.4" +version = "4.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5a7e487e921cf220206864a94a89b6c6905bfc19f1057fa26a4cb360e5c1d2" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" dependencies = [ "either", "lazy_static", diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml index 66a98f3885..3aec0690b0 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml @@ -6,5 +6,4 @@ version = "0.1.0" crate-type = ["cdylib"] [dependencies] -# Needed until bindgen has the `allowlist_file` feature -rb-sys = { git = "https://github.com/ianks/rb-sys", tag = "v0.6.0" } +rb-sys = "0.9.4" diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb index da9e82315e..869bbb5de8 100644 --- a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb @@ -15,7 +15,7 @@ gemspec = File.expand_path('rust_ruby_example.gemspec', __dir__) Dir.mktmpdir("rust_ruby_example") do |dir| built_gem = File.expand_path(File.join(dir, "rust_ruby_example.gem")) - system *gem, "build", gemspec, "--output", built_gem - system *gem, "install", "--verbose", "--local", built_gem, *ARGV + system(*gem, "build", gemspec, "--output", built_gem) + system(*gem, "install", "--verbose", "--local", built_gem, *ARGV) system %q(ruby -rrust_ruby_example -e "puts 'Result: ' + RustRubyExample.reverse('hello world')") end diff --git a/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb b/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb new file mode 100644 index 0000000000..3abcb83fa9 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true +require_relative 'helper' +require 'rubygems/ext' +require 'rubygems/ext/cargo_builder/link_flag_converter' + +class TestGemExtCargoBuilderLinkFlagConverter < Gem::TestCase + CASES = { + test_search_path_basic: ["-L/usr/local/lib", ["-L", "native=/usr/local/lib"]], + test_search_path_space: ["-L /usr/local/lib", ["-L", "native=/usr/local/lib"]], + test_search_path_space_in_path: ["-L/usr/local/my\ lib", ["-L", "native=/usr/local/my\ lib"]], + test_simple_lib: ["-lfoo", ["-l", "foo"]], + test_lib_with_nonascii: ["-lws2_32", ["-l", "ws2_32"]], + test_simple_lib_space: ["-l foo", ["-l", "foo"]], + test_verbose_lib_space: ["--library=foo", ["-l", "foo"]], + test_libstatic_with_colon: ["-l:libssp.a", ["-l", "static=ssp"]], + test_libstatic_with_colon_space: ["-l :libssp.a", ["-l", "static=ssp"]], + test_unconventional_lib_with_colon: ["-l:ssp.a", ["-C", "link_arg=-l:ssp.a"]], + test_dylib_with_colon_space: ["-l :libssp.dylib", ["-l", "dylib=ssp"]], + test_so_with_colon_space: ["-l :libssp.so", ["-l", "dylib=ssp"]], + test_dll_with_colon_space: ["-l :libssp.dll", ["-l", "dylib=ssp"]], + test_framework: ["-F/some/path", ["-l", "framework=/some/path"]], + test_framework_space: ["-F /some/path", ["-l", "framework=/some/path"]], + test_non_lib_dash_l: ["test_rubygems_20220413-976-lemgf9/prefix", ["-C", "link_arg=test_rubygems_20220413-976-lemgf9/prefix"]], + }.freeze + + CASES.each do |test_name, (arg, expected)| + raise "duplicate test name" if instance_methods.include?(test_name) + + define_method(test_name) do + assert_equal(expected, Gem::Ext::CargoBuilder::LinkFlagConverter.convert(arg)) + end + end +end diff --git a/test/rubygems/test_gem_ext_cargo_builder_unit.rb b/test/rubygems/test_gem_ext_cargo_builder_unit.rb new file mode 100644 index 0000000000..f6712e44a1 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder_unit.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require_relative 'helper' +require 'rubygems/ext' + +class TestGemExtCargoBuilderUnit < Gem::TestCase + def test_cargo_command_passes_args + skip_unsupported_platforms! + spec = Gem::Specification.new 'rust_ruby_example', '0.1.0' + builder = Gem::Ext::CargoBuilder.new(spec) + command = builder.cargo_command(Dir.pwd, @tempdir, ['--all-features']) + + assert_includes command, '--all-features' + end + + def test_cargo_command_locks_in_release_profile + skip_unsupported_platforms! + spec = Gem::Specification.new 'rust_ruby_example', '0.1.0' + builder = Gem::Ext::CargoBuilder.new(spec) + builder.profile = :release + command = builder.cargo_command(Dir.pwd, @tempdir) + + assert_includes command, '--locked' + end + + def test_cargo_command_does_not_lock_in_dev_profile + skip_unsupported_platforms! + spec = Gem::Specification.new 'rust_ruby_example', '0.1.0' + builder = Gem::Ext::CargoBuilder.new(spec) + builder.profile = :dev + command = builder.cargo_command(Dir.pwd, @tempdir) + + assert_not_includes command, '--locked' + end + + def test_cargo_command_passes_respects_cargo_env_var + skip_unsupported_platforms! + old_cargo = ENV['CARGO'] + ENV['CARGO'] = 'mycargo' + spec = Gem::Specification.new 'rust_ruby_example', '0.1.0' + builder = Gem::Ext::CargoBuilder.new(spec) + command = builder.cargo_command(Dir.pwd, @tempdir) + + assert_includes command, 'mycargo' + ensure + ENV['CARGO'] = old_cargo + end + + def test_build_env_includes_rbconfig + skip_unsupported_platforms! + spec = Gem::Specification.new 'rust_ruby_example', '0.1.0' + builder = Gem::Ext::CargoBuilder.new(spec) + env = builder.build_env + + assert_equal env.fetch('RBCONFIG_RUBY_SO_NAME'), RbConfig::CONFIG['RUBY_SO_NAME'] + end + + def test_cargo_command_passes_respects_cargo_build_target + skip_unsupported_platforms! + old_cargo = ENV['CARGO_BUILD_TARGET'] + ENV['CARGO_BUILD_TARGET'] = 'x86_64-unknown-linux-gnu' + spec = Gem::Specification.new 'rust_ruby_example', '0.1.0' + builder = Gem::Ext::CargoBuilder.new(spec) + command = builder.cargo_command(Dir.pwd, @tempdir, ['--locked']) + + assert_includes command, '--target' + assert_includes command, 'x86_64-unknown-linux-gnu' + ensure + ENV['CARGO_BUILD_TARGET'] = old_cargo + end + + def skip_unsupported_platforms! + pend "jruby not supported" if java_platform? + end +end diff --git a/test/rubygems/test_gem_gemcutter_utilities.rb b/test/rubygems/test_gem_gemcutter_utilities.rb index 667aba4701..9bfc22a202 100644 --- a/test/rubygems/test_gem_gemcutter_utilities.rb +++ b/test/rubygems/test_gem_gemcutter_utilities.rb @@ -254,7 +254,7 @@ class TestGemGemcutterUtilities < Gem::TestCase end def test_verify_api_key - keys = {:other => 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'} + keys = { :other => 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' } File.open Gem.configuration.credentials_path, 'w' do |f| f.write keys.to_yaml end diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index 9172b7eef5..34660bdccd 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -218,7 +218,7 @@ class TestGemPackage < Gem::Package::TarTestCase end assert_equal %w[lib/code.rb], files - assert_equal [{'lib/code_sym.rb' => 'code.rb'}, {'lib/code_sym2.rb' => '../lib/code.rb'}], symlinks + assert_equal [{ 'lib/code_sym.rb' => 'code.rb' }, { 'lib/code_sym2.rb' => '../lib/code.rb' }], symlinks end def test_build diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb index 3ce9be7c90..fa82a117a1 100644 --- a/test/rubygems/test_gem_remote_fetcher.rb +++ b/test/rubygems/test_gem_remote_fetcher.rb @@ -705,7 +705,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_http_with_additional_headers ENV["http_proxy"] = @proxy_uri ENV["no_proxy"] = URI::parse(@server_uri).host - fetcher = Gem::RemoteFetcher.new nil, nil, {"X-Captain" => "murphy"} + fetcher = Gem::RemoteFetcher.new nil, nil, { "X-Captain" => "murphy" } @fetcher = fetcher assert_equal "murphy", fetcher.fetch_path(@server_uri) end @@ -745,7 +745,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_config_creds Gem.configuration[:s3_source] = { - 'my-bucket' => {:id => 'testuser', :secret => 'testpass'}, + 'my-bucket' => { :id => 'testuser', :secret => 'testpass' }, } url = 's3://my-bucket/gems/specs.4.8.gz' Time.stub :now, Time.at(1561353581) do @@ -757,7 +757,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_config_creds_with_region Gem.configuration[:s3_source] = { - 'my-bucket' => {:id => 'testuser', :secret => 'testpass', :region => 'us-west-2'}, + 'my-bucket' => { :id => 'testuser', :secret => 'testpass', :region => 'us-west-2' }, } url = 's3://my-bucket/gems/specs.4.8.gz' Time.stub :now, Time.at(1561353581) do @@ -769,7 +769,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_config_creds_with_token Gem.configuration[:s3_source] = { - 'my-bucket' => {:id => 'testuser', :secret => 'testpass', :security_token => 'testtoken'}, + 'my-bucket' => { :id => 'testuser', :secret => 'testpass', :security_token => 'testtoken' }, } url = 's3://my-bucket/gems/specs.4.8.gz' Time.stub :now, Time.at(1561353581) do @@ -784,7 +784,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== ENV['AWS_SECRET_ACCESS_KEY'] = 'testpass' ENV['AWS_SESSION_TOKEN'] = nil Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'env'}, + 'my-bucket' => { :provider => 'env' }, } url = 's3://my-bucket/gems/specs.4.8.gz' Time.stub :now, Time.at(1561353581) do @@ -800,7 +800,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== ENV['AWS_SECRET_ACCESS_KEY'] = 'testpass' ENV['AWS_SESSION_TOKEN'] = nil Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'env', :region => 'us-west-2'}, + 'my-bucket' => { :provider => 'env', :region => 'us-west-2' }, } url = 's3://my-bucket/gems/specs.4.8.gz' Time.stub :now, Time.at(1561353581) do @@ -816,7 +816,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== ENV['AWS_SECRET_ACCESS_KEY'] = 'testpass' ENV['AWS_SESSION_TOKEN'] = 'testtoken' Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'env'}, + 'my-bucket' => { :provider => 'env' }, } url = 's3://my-bucket/gems/specs.4.8.gz' Time.stub :now, Time.at(1561353581) do @@ -836,7 +836,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_instance_profile_creds Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'instance_profile'}, + 'my-bucket' => { :provider => 'instance_profile' }, } url = 's3://my-bucket/gems/specs.4.8.gz' @@ -850,7 +850,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_instance_profile_creds_with_region Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'instance_profile', :region => 'us-west-2'}, + 'my-bucket' => { :provider => 'instance_profile', :region => 'us-west-2' }, } url = 's3://my-bucket/gems/specs.4.8.gz' @@ -864,7 +864,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_instance_profile_creds_with_token Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'instance_profile'}, + 'my-bucket' => { :provider => 'instance_profile' }, } url = 's3://my-bucket/gems/specs.4.8.gz' @@ -894,7 +894,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_no_host Gem.configuration[:s3_source] = { - 'my-bucket' => {:id => 'testuser', :secret => 'testpass'}, + 'my-bucket' => { :id => 'testuser', :secret => 'testpass' }, } url = 's3://other-bucket/gems/specs.4.8.gz' @@ -904,7 +904,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== end def test_fetch_s3_no_id - Gem.configuration[:s3_source] = { 'my-bucket' => {:secret => 'testpass'} } + Gem.configuration[:s3_source] = { 'my-bucket' => { :secret => 'testpass' } } url = 's3://my-bucket/gems/specs.4.8.gz' refute_fetch_s3 url, 's3_source for my-bucket missing id or secret' @@ -913,7 +913,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== end def test_fetch_s3_no_secret - Gem.configuration[:s3_source] = { 'my-bucket' => {:id => 'testuser'} } + Gem.configuration[:s3_source] = { 'my-bucket' => { :id => 'testuser' } } url = 's3://my-bucket/gems/specs.4.8.gz' refute_fetch_s3 url, 's3_source for my-bucket missing id or secret' @@ -973,7 +973,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_ssl_client_cert_auth_connection ssl_server = start_ssl_server({ :SSLVerifyClient => - OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT}) + OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT }) temp_ca_cert = File.join(__dir__, 'ca_cert.pem') temp_client_cert = File.join(__dir__, 'client.pem') @@ -988,7 +988,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_do_not_allow_invalid_client_cert_auth_connection ssl_server = start_ssl_server({ :SSLVerifyClient => - OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT}) + OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT }) temp_ca_cert = File.join(__dir__, 'ca_cert.pem') temp_client_cert = File.join(__dir__, 'invalid_client.pem') diff --git a/test/rubygems/test_gem_resolver.rb b/test/rubygems/test_gem_resolver.rb index ea9f9049ce..ab0cdaddb9 100644 --- a/test/rubygems/test_gem_resolver.rb +++ b/test/rubygems/test_gem_resolver.rb @@ -191,7 +191,7 @@ class TestGemResolver < Gem::TestCase # With the following gems already installed: # a-1, b-1, c-1, e-1 - res.skip_gems = {'a' => [a1_spec], 'b' => [b1_spec], 'c' => [c1_spec], 'e' => [e1_spec]} + res.skip_gems = { 'a' => [a1_spec], 'b' => [b1_spec], 'c' => [c1_spec], 'e' => [e1_spec] } # Make sure the following gems end up getting used/installed/upgraded: # a-2 (upgraded) diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index ccb81caf37..3f88fd1910 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -158,7 +158,7 @@ end util_spec "pkg#{pkgi}", pkg_version.to_s, deps end end - base = util_spec "pkg_base", "1", {"pkg0" => ">= 0"} + base = util_spec "pkg_base", "1", { "pkg0" => ">= 0" } Gem::Specification.reset install_specs(*packages.flatten.reverse) @@ -305,10 +305,10 @@ end def test_require_should_not_conflict base = util_spec "0", "1", "A" => ">= 1" - a1 = util_spec "A", "1", {"c" => ">= 2", "b" => "> 0"}, "lib/a.rb" - a2 = util_spec "A", "2", {"c" => ">= 2", "b" => "> 0"}, "lib/a.rb" - b1 = util_spec "b", "1", {"c" => "= 1"}, "lib/d#{$$}.rb" - b2 = util_spec "b", "2", {"c" => "= 2"}, "lib/d#{$$}.rb" + a1 = util_spec "A", "1", { "c" => ">= 2", "b" => "> 0" }, "lib/a.rb" + a2 = util_spec "A", "2", { "c" => ">= 2", "b" => "> 0" }, "lib/a.rb" + b1 = util_spec "b", "1", { "c" => "= 1" }, "lib/d#{$$}.rb" + b2 = util_spec "b", "2", { "c" => "= 2" }, "lib/d#{$$}.rb" c1 = util_spec "c", "1", {}, "lib/c.rb" c2 = util_spec "c", "2", {}, "lib/c.rb" c3 = util_spec "c", "3", {}, "lib/c.rb" @@ -1068,7 +1068,15 @@ dependencies: [] end def test_handles_private_null_type - path = File.expand_path 'data/null-type.gemspec.rz', __dir__ + path = File.expand_path 'data/pry-0.4.7.gemspec.rz', __dir__ + + data = Marshal.load Gem::Util.inflate(Gem.read_binary(path)) + + assert_instance_of Gem::Specification, data + end + + def test_handles_dependencies_with_syck_requirements_bug + path = File.expand_path 'data/excon-0.7.7.gemspec.rz', __dir__ data = Marshal.load Gem::Util.inflate(Gem.read_binary(path)) diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb index 9aa057442a..3e393a4df3 100644 --- a/test/rubygems/test_require.rb +++ b/test/rubygems/test_require.rb @@ -63,8 +63,8 @@ class TestGemRequire < Gem::TestCase # Providing -I on the commandline should always beat gems def test_dash_i_beats_gems - a1 = util_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb" - b1 = util_spec "b", "1", {"c" => "> 0"}, "lib/b/c.rb" + a1 = util_spec "a", "1", { "b" => "= 1" }, "lib/test_gem_require_a.rb" + b1 = util_spec "b", "1", { "c" => "> 0" }, "lib/b/c.rb" c1 = util_spec "c", "1", nil, "lib/c/c.rb" c2 = util_spec "c", "2", nil, "lib/c/c.rb" @@ -102,8 +102,8 @@ class TestGemRequire < Gem::TestCase # Providing -I on the commandline should always beat gems def test_dash_i_beats_default_gems - a1 = new_default_spec "a", "1", {"b" => "= 1"}, "test_gem_require_a.rb" - b1 = new_default_spec "b", "1", {"c" => "> 0"}, "b/c.rb" + a1 = new_default_spec "a", "1", { "b" => "= 1" }, "test_gem_require_a.rb" + b1 = new_default_spec "b", "1", { "c" => "> 0" }, "b/c.rb" c1 = new_default_spec "c", "1", nil, "c/c.rb" c2 = new_default_spec "c", "2", nil, "c/c.rb" @@ -169,7 +169,7 @@ class TestGemRequire < Gem::TestCase end def test_require_is_not_lazy_with_exact_req - a1 = util_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb" + a1 = util_spec "a", "1", { "b" => "= 1" }, "lib/test_gem_require_a.rb" b1 = util_spec "b", "1", nil, "lib/b/c.rb" b2 = util_spec "b", "2", nil, "lib/b/c.rb" @@ -184,7 +184,7 @@ class TestGemRequire < Gem::TestCase end def test_require_is_lazy_with_inexact_req - a1 = util_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb" + a1 = util_spec "a", "1", { "b" => ">= 1" }, "lib/test_gem_require_a.rb" b1 = util_spec "b", "1", nil, "lib/b/c.rb" b2 = util_spec "b", "2", nil, "lib/b/c.rb" @@ -199,7 +199,7 @@ class TestGemRequire < Gem::TestCase end def test_require_is_not_lazy_with_one_possible - a1 = util_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb" + a1 = util_spec "a", "1", { "b" => ">= 1" }, "lib/test_gem_require_a.rb" b1 = util_spec "b", "1", nil, "lib/b/c.rb" install_specs b1, a1 @@ -243,7 +243,7 @@ class TestGemRequire < Gem::TestCase require 'benchmark' # the stdlib - a1 = util_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb" + a1 = util_spec "a", "1", { "b" => ">= 1" }, "lib/test_gem_require_a.rb" b1 = util_spec "b", "1", nil, "lib/benchmark.rb" b2 = util_spec "b", "2", nil, "lib/benchmark.rb" @@ -444,7 +444,7 @@ class TestGemRequire < Gem::TestCase end def test_realworld_default_gem - omit "this test can't work under ruby-core setup" if testing_ruby_repo? + omit "this test can't work under ruby-core setup" if ruby_repo? cmd = <<-RUBY $stderr = $stdout @@ -457,7 +457,7 @@ class TestGemRequire < Gem::TestCase end def test_realworld_upgraded_default_gem - omit "this test can't work under ruby-core setup" if testing_ruby_repo? + omit "this test can't work under ruby-core setup" if ruby_repo? newer_json = util_spec("json", "999.99.9", nil, ["lib/json.rb"]) install_gem newer_json diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb index cc650ff343..739a9985b0 100644 --- a/test/rubygems/test_rubygems.rb +++ b/test/rubygems/test_rubygems.rb @@ -2,7 +2,7 @@ require_relative 'helper' class GemTest < Gem::TestCase def test_rubygems_normal_behaviour - _ = Gem::Util.popen(*ruby_with_rubygems_in_load_path, '-e', "'require \"rubygems\"'", {:err => [:child, :out]}).strip + _ = Gem::Util.popen(*ruby_with_rubygems_in_load_path, '-e', "'require \"rubygems\"'", { :err => [:child, :out] }).strip assert $?.success? end @@ -13,7 +13,7 @@ class GemTest < Gem::TestCase intentionally_not_implemented_method RUBY - output = Gem::Util.popen(*ruby_with_rubygems_and_fake_operating_system_in_load_path(path), '-e', "'require \"rubygems\"'", {:err => [:child, :out]}).strip + output = Gem::Util.popen(*ruby_with_rubygems_and_fake_operating_system_in_load_path(path), '-e', "'require \"rubygems\"'", { :err => [:child, :out] }).strip assert !$?.success? assert_includes output, "undefined local variable or method `intentionally_not_implemented_method'" assert_includes output, "Loading the rubygems/defaults/operating_system.rb file caused an error. " \ @@ -40,7 +40,7 @@ class GemTest < Gem::TestCase *ruby_with_rubygems_and_fake_operating_system_in_load_path(path), '-e', "require \"rubygems\"; puts Gem::Specification.stubs.map(&:full_name)", - {:err => [:child, :out]} + { :err => [:child, :out] } ).strip begin assert_empty output diff --git a/tool/bundler/dev_gems.rb b/tool/bundler/dev_gems.rb index 8a858c1e67..0e5e681f73 100644 --- a/tool/bundler/dev_gems.rb +++ b/tool/bundler/dev_gems.rb @@ -6,11 +6,6 @@ gem "rdoc", "6.2.0" # 6.2.1 is required > Ruby 2.3 gem "test-unit", "~> 3.0" gem "rake", "~> 13.0" -group :lint do - gem "rubocop", "~> 0.80.1" - gem "rubocop-performance", "~> 1.5.2" -end - gem "webrick", "~> 1.6" gem "parallel_tests", "~> 2.29" gem "parallel", "1.19.2" # 1.20+ is required > Ruby 2.3 diff --git a/tool/bundler/dev_gems.rb.lock b/tool/bundler/dev_gems.rb.lock index fc48d3e05f..f800741de8 100644 --- a/tool/bundler/dev_gems.rb.lock +++ b/tool/bundler/dev_gems.rb.lock @@ -1,23 +1,16 @@ GEM remote: https://rubygems.org/ specs: - ast (2.4.2) diff-lcs (1.5.0) hpricot (0.8.6) - jaro_winkler (1.5.4) - jaro_winkler (1.5.4-java) mustache (1.1.1) parallel (1.19.2) parallel_tests (2.32.0) parallel - parser (3.1.0.0) - ast (~> 2.4.1) power_assert (2.0.1) - rainbow (3.1.1) rake (13.0.6) rdiscount (2.2.0.2) rdoc (6.2.0) - rexml (3.2.5) ronn (0.7.3) hpricot (>= 0.8.2) mustache (>= 0.7.0) @@ -31,20 +24,8 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.11.0) rspec-support (3.11.0) - rubocop (0.80.1) - jaro_winkler (~> 1.5.1) - parallel (~> 1.10) - parser (>= 2.7.0.1) - rainbow (>= 2.2.2, < 4.0) - rexml - ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 1.7) - rubocop-performance (1.5.2) - rubocop (>= 0.71.0) - ruby-progressbar (1.11.0) test-unit (3.5.3) power_assert - unicode-display_width (1.6.1) uri (0.10.1) webrick (1.7.0) @@ -65,11 +46,9 @@ DEPENDENCIES rspec-core (~> 3.8) rspec-expectations (~> 3.8) rspec-mocks (~> 3.11.1) - rubocop (~> 0.80.1) - rubocop-performance (~> 1.5.2) test-unit (~> 3.0) uri (~> 0.10.1) webrick (~> 1.6) BUNDLED WITH - 2.3.15 + 2.3.16 diff --git a/tool/bundler/rubocop_gems.rb.lock b/tool/bundler/rubocop_gems.rb.lock index 4027570ebb..45e66a8b84 100644 --- a/tool/bundler/rubocop_gems.rb.lock +++ b/tool/bundler/rubocop_gems.rb.lock @@ -60,4 +60,4 @@ DEPENDENCIES test-unit BUNDLED WITH - 2.3.15 + 2.3.16 diff --git a/tool/bundler/standard_gems.rb.lock b/tool/bundler/standard_gems.rb.lock index b939fa05d6..99e7e2aff5 100644 --- a/tool/bundler/standard_gems.rb.lock +++ b/tool/bundler/standard_gems.rb.lock @@ -66,4 +66,4 @@ DEPENDENCIES test-unit BUNDLED WITH - 2.3.15 + 2.3.16 diff --git a/tool/bundler/test_gems.rb.lock b/tool/bundler/test_gems.rb.lock index dab017efc8..a79bc65e8d 100644 --- a/tool/bundler/test_gems.rb.lock +++ b/tool/bundler/test_gems.rb.lock @@ -41,4 +41,4 @@ DEPENDENCIES webrick (= 1.7.0) BUNDLED WITH - 2.3.15 + 2.3.16