From d03e4228aaeb1bdd3432119e683aa259b028c5b2 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 17 Oct 2024 16:11:25 +0900 Subject: [PATCH] Merge RubyGems-3.5.21 and Bundler-2.5.21 --- lib/bundler.rb | 50 +++++++++++-------- lib/bundler/inline.rb | 16 ++++-- lib/bundler/source/git.rb | 2 +- lib/bundler/source/git/git_proxy.rb | 6 ++- lib/bundler/source/path.rb | 2 + lib/bundler/stub_specification.rb | 4 +- lib/bundler/version.rb | 2 +- lib/rubygems.rb | 2 +- lib/rubygems/command_manager.rb | 11 +--- lib/rubygems/commands/cleanup_command.rb | 12 +---- lib/rubygems/errors.rb | 3 +- lib/rubygems/installer.rb | 37 ++++++-------- lib/rubygems/resolver/api_set.rb | 19 ++++--- lib/rubygems/resolver/best_set.rb | 2 - lib/rubygems/spec_fetcher.rb | 15 ++---- lib/rubygems/specification.rb | 4 +- .../bundler/endpoint_specification_spec.rb | 2 +- .../bundler/stub_specification_spec.rb | 20 ++++++++ spec/bundler/cache/git_spec.rb | 2 - spec/bundler/install/deploy_spec.rb | 25 +++++++++- .../gemfile/force_ruby_platform_spec.rb | 2 + .../install/gems/compact_index_spec.rb | 2 +- .../realworld/fixtures/warbler/Gemfile | 2 +- .../realworld/fixtures/warbler/Gemfile.lock | 6 +-- ...undled_env_spec.rb => env_helpers_spec.rb} | 11 +++- spec/bundler/runtime/inline_spec.rb | 16 ++++++ test/rubygems/installer_test_case.rb | 6 --- .../rubygems/rubygems/commands/ins_command.rb | 7 +++ .../rubygems/commands/interrupt_command.rb | 11 ++++ test/rubygems/rubygems_plugin.rb | 19 ------- test/rubygems/test_gem.rb | 11 ---- test/rubygems/test_gem_command_manager.rb | 9 ++-- .../test_gem_commands_exec_command.rb | 5 +- .../test_gem_commands_help_command.rb | 2 - test/rubygems/test_gem_dependency.rb | 2 +- test/rubygems/test_gem_installer.rb | 13 +++-- test/rubygems/test_gem_resolver_api_set.rb | 19 +++++++ test/rubygems/test_gem_spec_fetcher.rb | 16 +++--- test/rubygems/test_gem_specification.rb | 34 +++++++++++++ test/rubygems/test_require.rb | 20 +++++++- 40 files changed, 276 insertions(+), 173 deletions(-) rename spec/bundler/runtime/{with_unbundled_env_spec.rb => env_helpers_spec.rb} (95%) create mode 100644 test/rubygems/rubygems/commands/ins_command.rb create mode 100644 test/rubygems/rubygems/commands/interrupt_command.rb diff --git a/lib/bundler.rb b/lib/bundler.rb index e1c7884d52c1db..85532f4ac267ca 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -383,28 +383,12 @@ def clean_env # @return [Hash] Environment with all bundler-related variables removed def unbundled_env - env = original_env - - if env.key?("BUNDLER_ORIG_MANPATH") - env["MANPATH"] = env["BUNDLER_ORIG_MANPATH"] - end - - env.delete_if {|k, _| k[0, 7] == "BUNDLE_" } - - if env.key?("RUBYOPT") - rubyopt = env["RUBYOPT"].split(" ") - rubyopt.delete("-r#{File.expand_path("bundler/setup", __dir__)}") - rubyopt.delete("-rbundler/setup") - env["RUBYOPT"] = rubyopt.join(" ") - end - - if env.key?("RUBYLIB") - rubylib = env["RUBYLIB"].split(File::PATH_SEPARATOR) - rubylib.delete(__dir__) - env["RUBYLIB"] = rubylib.join(File::PATH_SEPARATOR) - end + unbundle_env(original_env) + end - env + # Remove all bundler-related variables from ENV + def unbundle_env! + ENV.replace(unbundle_env(ENV)) end # Run block with environment present before Bundler was activated @@ -633,6 +617,30 @@ def self_manager private + def unbundle_env(env) + if env.key?("BUNDLER_ORIG_MANPATH") + env["MANPATH"] = env["BUNDLER_ORIG_MANPATH"] + end + + env.delete_if {|k, _| k[0, 7] == "BUNDLE_" } + env.delete("BUNDLER_SETUP") + + if env.key?("RUBYOPT") + rubyopt = env["RUBYOPT"].split(" ") + rubyopt.delete("-r#{File.expand_path("bundler/setup", __dir__)}") + rubyopt.delete("-rbundler/setup") + env["RUBYOPT"] = rubyopt.join(" ") + end + + if env.key?("RUBYLIB") + rubylib = env["RUBYLIB"].split(File::PATH_SEPARATOR) + rubylib.delete(__dir__) + env["RUBYLIB"] = rubylib.join(File::PATH_SEPARATOR) + end + + env + end + def load_marshal(data, marshal_proc: nil) Marshal.load(data, marshal_proc) rescue TypeError => e diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb index 1b12de1d7c24a3..ca17d0233eaa9a 100644 --- a/lib/bundler/inline.rb +++ b/lib/bundler/inline.rb @@ -39,7 +39,11 @@ def gemfile(install = false, options = {}, &gemfile) Bundler.ui = ui raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty? - Bundler.with_unbundled_env do + old_gemfile = ENV["BUNDLE_GEMFILE"] + + Bundler.unbundle_env! + + begin Bundler.instance_variable_set(:@bundle_path, Pathname.new(Gem.dir)) Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", "Gemfile" @@ -80,9 +84,11 @@ def gemfile(install = false, options = {}, &gemfile) runtime.require end - end - - if ENV["BUNDLE_GEMFILE"].nil? - ENV["BUNDLE_GEMFILE"] = "" + ensure + if old_gemfile + ENV["BUNDLE_GEMFILE"] = old_gemfile + else + ENV["BUNDLE_GEMFILE"] = "" + end end end diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb index 91e1743961a466..267878f83b37ff 100644 --- a/lib/bundler/source/git.rb +++ b/lib/bundler/source/git.rb @@ -191,7 +191,7 @@ def specs(*) set_up_app_cache!(app_cache_path) if use_app_cache? if requires_checkout? && !@copied - FileUtils.rm_rf(app_cache_path) if use_app_cache? && git_proxy.not_a_bare_repository? + FileUtils.rm_rf(app_cache_path) if use_app_cache? && git_proxy.not_a_repository? fetch checkout diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb index 768d40392fcfc3..744235bc046d7e 100644 --- a/lib/bundler/source/git/git_proxy.rb +++ b/lib/bundler/source/git/git_proxy.rb @@ -84,8 +84,10 @@ def current_branch end end - def not_a_bare_repository? - git_local("rev-parse", "--is-bare-repository", dir: path).strip == "false" + def not_a_repository? + _, status = git_null("rev-parse", "--resolve-git-dir", path.to_s, dir: path) + + !status.success? end def contains?(commit) diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb index 754eaa39c46bda..4fd439d8779fe9 100644 --- a/lib/bundler/source/path.rb +++ b/lib/bundler/source/path.rb @@ -53,6 +53,8 @@ def to_s "source at `#{@path}`" end + alias_method :to_gemfile, :path + def hash [self.class, expanded_path, version].hash end diff --git a/lib/bundler/stub_specification.rb b/lib/bundler/stub_specification.rb index 1cbb506ef99f54..dc5d38580a8551 100644 --- a/lib/bundler/stub_specification.rb +++ b/lib/bundler/stub_specification.rb @@ -45,8 +45,8 @@ def missing_extensions? true end - def activated - stub.activated + def activated? + stub.activated? end def activated=(activated) diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb index c743f5ea29f284..6b66f726077332 100644 --- a/lib/bundler/version.rb +++ b/lib/bundler/version.rb @@ -1,7 +1,7 @@ # frozen_string_literal: false module Bundler - VERSION = "2.5.20".freeze + VERSION = "2.5.21".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 ef0ee714187b9d..467cdcefa1892a 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -9,7 +9,7 @@ require "rbconfig" module Gem - VERSION = "3.5.20" + VERSION = "3.5.21" end # Must be first since it unloads the prelude from 1.9.2 diff --git a/lib/rubygems/command_manager.rb b/lib/rubygems/command_manager.rb index 8e578dc1966172..4d54d1d49d5633 100644 --- a/lib/rubygems/command_manager.rb +++ b/lib/rubygems/command_manager.rb @@ -230,18 +230,11 @@ def find_command_possibilities(cmd_name) def load_and_instantiate(command_name) command_name = command_name.to_s const_name = command_name.capitalize.gsub(/_(.)/) { $1.upcase } << "Command" - load_error = nil begin - begin - require "rubygems/commands/#{command_name}_command" - rescue LoadError => e - load_error = e - end + require "rubygems/commands/#{command_name}_command" Gem::Commands.const_get(const_name).new - rescue StandardError => e - e = load_error if load_error - + rescue StandardError, LoadError => e alert_error clean_text("Loading command: #{command_name} (#{e.class})\n\t#{e}") ui.backtrace e end diff --git a/lib/rubygems/commands/cleanup_command.rb b/lib/rubygems/commands/cleanup_command.rb index 08fb598cea54f1..bc24aaf753bf09 100644 --- a/lib/rubygems/commands/cleanup_command.rb +++ b/lib/rubygems/commands/cleanup_command.rb @@ -38,8 +38,6 @@ def initialize @default_gems = [] @full = nil @gems_to_cleanup = nil - @original_home = nil - @original_path = nil @primary_gems = nil end @@ -95,9 +93,6 @@ def execute end def clean_gems - @original_home = Gem.dir - @original_path = Gem.path - get_primary_gems get_candidate_gems get_gems_to_cleanup @@ -112,8 +107,6 @@ def clean_gems deps.reverse_each do |spec| uninstall_dep spec end - - Gem::Specification.reset end def get_candidate_gems @@ -133,7 +126,7 @@ def get_gems_to_cleanup default_gems, gems_to_cleanup = gems_to_cleanup.partition(&:default_gem?) - uninstall_from = options[:user_install] ? Gem.user_dir : @original_home + uninstall_from = options[:user_install] ? Gem.user_dir : Gem.dir gems_to_cleanup = gems_to_cleanup.select do |spec| spec.base_dir == uninstall_from @@ -181,8 +174,5 @@ def uninstall_dep(spec) say "Unable to uninstall #{spec.full_name}:" say "\t#{e.class}: #{e.message}" end - ensure - # Restore path Gem::Uninstaller may have changed - Gem.use_paths @original_home, *@original_path end end diff --git a/lib/rubygems/errors.rb b/lib/rubygems/errors.rb index be6c34dc8520b3..57fb3eb12008a1 100644 --- a/lib/rubygems/errors.rb +++ b/lib/rubygems/errors.rb @@ -30,6 +30,7 @@ def initialize(name, requirement, extra_message=nil) @name = name @requirement = requirement @extra_message = extra_message + super(message) end def message # :nodoc: @@ -53,8 +54,8 @@ class MissingSpecVersionError < MissingSpecError attr_reader :specs def initialize(name, requirement, specs) - super(name, requirement) @specs = specs + super(name, requirement) end private diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index 84dcf1b33fc707..b374824b2a06a9 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -66,8 +66,6 @@ class Gem::Installer attr_reader :package - @path_warning = false - class << self # # Changes in rubygems to lazily loading `rubygems/command` (in order to @@ -86,11 +84,6 @@ def inherited(klass) super(klass) end - ## - # True if we've warned about PATH not including Gem.bindir - - attr_accessor :path_warning - ## # Overrides the executable format. # @@ -188,15 +181,6 @@ def initialize(package, options={}) @package.dir_mode = options[:dir_mode] @package.prog_mode = options[:prog_mode] @package.data_mode = options[:data_mode] - - if @gem_home == Gem.user_dir - # If we get here, then one of the following likely happened: - # - `--user-install` was specified - # - `Gem::PathSupport#home` fell back to `Gem.user_dir` - # - GEM_HOME was manually set to `Gem.user_dir` - - check_that_user_bin_dir_is_in_path - end end ## @@ -488,11 +472,21 @@ def generate_windows_script(filename, bindir) end def generate_bin # :nodoc: - return if spec.executables.nil? || spec.executables.empty? + executables = spec.executables + return if executables.nil? || executables.empty? + + if @gem_home == Gem.user_dir + # If we get here, then one of the following likely happened: + # - `--user-install` was specified + # - `Gem::PathSupport#home` fell back to `Gem.user_dir` + # - GEM_HOME was manually set to `Gem.user_dir` + + check_that_user_bin_dir_is_in_path(executables) + end ensure_writable_dir @bin_dir - spec.executables.each do |filename| + executables.each do |filename| bin_path = File.join gem_dir, spec.bindir, filename next unless File.exist? bin_path @@ -694,9 +688,7 @@ def process_options # :nodoc: end end - def check_that_user_bin_dir_is_in_path # :nodoc: - return if self.class.path_warning - + def check_that_user_bin_dir_is_in_path(executables) # :nodoc: user_bin_dir = @bin_dir || Gem.bindir(gem_home) user_bin_dir = user_bin_dir.tr(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR @@ -712,8 +704,7 @@ def check_that_user_bin_dir_is_in_path # :nodoc: unless path.include? user_bin_dir unless !Gem.win_platform? && (path.include? user_bin_dir.sub(ENV["HOME"], "~")) - alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables will not run." - self.class.path_warning = true + alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables (#{executables.join(", ")}) will not run." end end end diff --git a/lib/rubygems/resolver/api_set.rb b/lib/rubygems/resolver/api_set.rb index 3e4dadc40f489e..9f6695a6a97455 100644 --- a/lib/rubygems/resolver/api_set.rb +++ b/lib/rubygems/resolver/api_set.rb @@ -104,16 +104,21 @@ def versions(name) # :nodoc: end uri = @dep_uri + name - str = Gem::RemoteFetcher.fetcher.fetch_path uri - lines(str).each do |ver| - number, platform, dependencies, requirements = parse_gem(ver) + begin + str = Gem::RemoteFetcher.fetcher.fetch_path uri + rescue Gem::RemoteFetcher::FetchError + @data[name] = [] + else + lines(str).each do |ver| + number, platform, dependencies, requirements = parse_gem(ver) - platform ||= "ruby" - dependencies = dependencies.map {|dep_name, reqs| [dep_name, reqs.join(", ")] } - requirements = requirements.map {|req_name, reqs| [req_name.to_sym, reqs] }.to_h + platform ||= "ruby" + dependencies = dependencies.map {|dep_name, reqs| [dep_name, reqs.join(", ")] } + requirements = requirements.map {|req_name, reqs| [req_name.to_sym, reqs] }.to_h - @data[name] << { name: name, number: number, platform: platform, dependencies: dependencies, requirements: requirements } + @data[name] << { name: name, number: number, platform: platform, dependencies: dependencies, requirements: requirements } + end end @data[name] diff --git a/lib/rubygems/resolver/best_set.rb b/lib/rubygems/resolver/best_set.rb index 57d0d0037576d5..e2307f6e026bde 100644 --- a/lib/rubygems/resolver/best_set.rb +++ b/lib/rubygems/resolver/best_set.rb @@ -29,8 +29,6 @@ def find_all(req) # :nodoc: pick_sets if @remote && @sets.empty? super - rescue Gem::RemoteFetcher::FetchError - [] end def prefetch(reqs) # :nodoc: diff --git a/lib/rubygems/spec_fetcher.rb b/lib/rubygems/spec_fetcher.rb index 610edf25c92155..9c0399f19653dc 100644 --- a/lib/rubygems/spec_fetcher.rb +++ b/lib/rubygems/spec_fetcher.rb @@ -176,19 +176,12 @@ def suggest_gems_from_name(gem_name, type = :latest, num_results = 5) matches = names.map do |n| next unless n.match_platform? - [n.name, 0] if n.name.downcase.tr("_-", "").include?(gem_name) + distance = levenshtein_distance gem_name, n.name.downcase.tr("_-", "") + next if distance >= max + return [n.name] if distance == 0 + [n.name, distance] end.compact - if matches.length < num_results - matches += names.map do |n| - next unless n.match_platform? - distance = levenshtein_distance gem_name, n.name.downcase.tr("_-", "") - next if distance >= max - return [n.name] if distance == 0 - [n.name, distance] - end.compact - end - matches = if matches.empty? && type != :prerelease suggest_gems_from_name gem_name, :prerelease else diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 63229b0ae20ed1..996c41825d48f3 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -1208,7 +1208,7 @@ def self.reset unresolved.values.each do |dep| warn " #{dep}" - versions = find_all_by_name(dep.name) + versions = find_all_by_name(dep.name).uniq(&:full_name) unless versions.empty? warn " Available/installed versions of this gem:" versions.each {|s| warn " - #{s.version}" } @@ -1412,7 +1412,7 @@ def activate_dependencies end begin - specs = spec_dep.to_specs + specs = spec_dep.to_specs.uniq(&:full_name) rescue Gem::MissingSpecError => e raise Gem::MissingSpecError.new(e.name, e.requirement, "at: #{spec_file}") end diff --git a/spec/bundler/bundler/endpoint_specification_spec.rb b/spec/bundler/bundler/endpoint_specification_spec.rb index e7e10730cfde10..6518f125ba5e52 100644 --- a/spec/bundler/bundler/endpoint_specification_spec.rb +++ b/spec/bundler/bundler/endpoint_specification_spec.rb @@ -42,7 +42,7 @@ expect { subject }.to raise_error( Bundler::GemspecError, a_string_including("There was an error parsing the metadata for the gem foo (1.0.0)"). - and(a_string_including('The metadata was {"rubygems"=>">\n"}')) + and(a_string_including("The metadata was #{{ "rubygems" => ">\n" }.inspect}")) ) end end diff --git a/spec/bundler/bundler/stub_specification_spec.rb b/spec/bundler/bundler/stub_specification_spec.rb index dae9f3cfba9f40..beb966b3ce8b56 100644 --- a/spec/bundler/bundler/stub_specification_spec.rb +++ b/spec/bundler/bundler/stub_specification_spec.rb @@ -55,4 +55,24 @@ expect(stub.missing_extensions?).to be true end end + + describe "#activated?" do + it "returns true after activation" do + stub = described_class.from_stub(with_bundler_stub_spec) + + expect(stub.activated?).to be_falsey + stub.activated = true + expect(stub.activated?).to be true + end + + it "returns true after activation if the underlying stub is a `Gem::StubSpecification`" do + spec_path = File.join(File.dirname(__FILE__), "specifications", "foo.gemspec") + gem_stub = Gem::StubSpecification.new(spec_path, File.dirname(__FILE__),"","") + stub = described_class.from_stub(gem_stub) + + expect(stub.activated?).to be_falsey + stub.activated = true + expect(stub.activated?).to be true + end + end end diff --git a/spec/bundler/cache/git_spec.rb b/spec/bundler/cache/git_spec.rb index 88436c79aade08..ea91829003320c 100644 --- a/spec/bundler/cache/git_spec.rb +++ b/spec/bundler/cache/git_spec.rb @@ -323,8 +323,6 @@ FileUtils.mkdir_p bundled_app("vendor/cache") FileUtils.cp_r git_path, bundled_app("vendor/cache/foo-1.0-#{path_revision}") FileUtils.rm_rf bundled_app("vendor/cache/foo-1.0-#{path_revision}/.git") - # bundle install with git repo needs to be run under the git environment. - Dir.chdir(bundled_app) { system(*%W[git init --quiet]) } bundle :install, env: { "BUNDLE_DEPLOYMENT" => "true", "BUNDLE_CACHE_ALL" => "true" } end diff --git a/spec/bundler/install/deploy_spec.rb b/spec/bundler/install/deploy_spec.rb index 7b6e775b4cd6b8..bd39ac5cc1d4ae 100644 --- a/spec/bundler/install/deploy_spec.rb +++ b/spec/bundler/install/deploy_spec.rb @@ -438,7 +438,7 @@ expect(err).to include("You have changed in the Gemfile:\n* myrack from `no specified source` to `git://hubz.com`") end - it "explodes if you change a source" do + it "explodes if you change a source from git to the default" do build_git "myrack" install_gemfile <<-G @@ -459,7 +459,7 @@ expect(err).to include("You have changed in the Gemfile:\n* myrack from `#{lib_path("myrack-1.0")}` to `no specified source`") end - it "explodes if you change a source" do + it "explodes if you change a source from git to the default, in presence of other git sources" do build_lib "foo", path: lib_path("myrack/foo") build_git "myrack", path: lib_path("myrack") @@ -483,6 +483,27 @@ expect(err).not_to include("You have deleted from the Gemfile") end + it "explodes if you change a source from path to git" do + build_git "myrack", path: lib_path("myrack") + + install_gemfile <<-G + source "https://gem.repo1" + gem "myrack", :path => "#{lib_path("myrack")}" + G + + gemfile <<-G + source "https://gem.repo1" + gem "myrack", :git => "https:/my-git-repo-for-myrack" + G + + bundle "config set --local frozen true" + bundle :install, raise_on_error: false + expect(err).to include("frozen mode") + expect(err).to include("You have changed in the Gemfile:\n* myrack from `#{lib_path("myrack")}` to `https:/my-git-repo-for-myrack`") + expect(err).not_to include("You have added to the Gemfile") + expect(err).not_to include("You have deleted from the Gemfile") + end + it "remembers that the bundle is frozen at runtime" do bundle :lock diff --git a/spec/bundler/install/gemfile/force_ruby_platform_spec.rb b/spec/bundler/install/gemfile/force_ruby_platform_spec.rb index f5d993adacaf1e..926e7527e667ef 100644 --- a/spec/bundler/install/gemfile/force_ruby_platform_spec.rb +++ b/spec/bundler/install/gemfile/force_ruby_platform_spec.rb @@ -102,6 +102,8 @@ end it "reinstalls the ruby variant when a platform specific variant is already installed, the lockile has only ruby platform, and :force_ruby_platform is used in the Gemfile" do + skip "Can't simulate platform reliably on JRuby, installing a platform specific gem fails to activate io-wait because only the -java version is present, and we're simulating a different platform" if RUBY_ENGINE == "jruby" + lockfile <<-L GEM remote: https://gem.repo4 diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb index 39064e3b80b219..4653ce6d871726 100644 --- a/spec/bundler/install/gems/compact_index_spec.rb +++ b/spec/bundler/install/gems/compact_index_spec.rb @@ -173,7 +173,7 @@ bundle :install, verbose: true, artifice: "compact_index_checksum_mismatch" expect(out).to include("Fetching gem metadata from #{source_uri}") expect(out).to include("The checksum of /versions does not match the checksum provided by the server!") - expect(out).to include('Calculated checksums {"sha-256"=>"8KfZiM/fszVkqhP/m5s9lvE6M9xKu4I1bU4Izddp5Ms="} did not match expected {"sha-256"=>"ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0="}') + expect(out).to include("Calculated checksums #{{ "sha-256" => "8KfZiM/fszVkqhP/m5s9lvE6M9xKu4I1bU4Izddp5Ms=" }.inspect} did not match expected #{{ "sha-256" => "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=" }.inspect}") expect(the_bundle).to include_gems "myrack 1.0.0" end diff --git a/spec/bundler/realworld/fixtures/warbler/Gemfile b/spec/bundler/realworld/fixtures/warbler/Gemfile index a8dbb4911cf2f6..e4d3e8ea963cf7 100644 --- a/spec/bundler/realworld/fixtures/warbler/Gemfile +++ b/spec/bundler/realworld/fixtures/warbler/Gemfile @@ -3,5 +3,5 @@ source "https://rubygems.org" gem "demo", path: "./demo" -gem "jruby-jars", "~> 9.2" +gem "jruby-jars", "~> 9.4" gem "warbler", "~> 2.0" diff --git a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock index 5b476f8df27e8a..b8171d28cef528 100644 --- a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock +++ b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock @@ -6,7 +6,7 @@ PATH GEM remote: https://rubygems.org/ specs: - jruby-jars (9.2.16.0) + jruby-jars (9.4.8.0) jruby-rack (1.1.21) rake (13.0.1) rubyzip (1.3.0) @@ -23,8 +23,8 @@ PLATFORMS DEPENDENCIES demo! - jruby-jars (~> 9.2) + jruby-jars (~> 9.4) warbler (~> 2.0) BUNDLED WITH - 2.5.0.dev + 2.6.0.dev diff --git a/spec/bundler/runtime/with_unbundled_env_spec.rb b/spec/bundler/runtime/env_helpers_spec.rb similarity index 95% rename from spec/bundler/runtime/with_unbundled_env_spec.rb rename to spec/bundler/runtime/env_helpers_spec.rb index 8c3582f7acb156..a1607cd057a751 100644 --- a/spec/bundler/runtime/with_unbundled_env_spec.rb +++ b/spec/bundler/runtime/env_helpers_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe "Bundler.with_env helpers" do +RSpec.describe "env helpers" do def bundle_exec_ruby(args, options = {}) build_bundler_context options.dup bundle "exec '#{Gem.ruby}' #{args}", options @@ -103,6 +103,15 @@ def run_bundler_script(env, script) expect(last_command.stdboth).not_to include("-rbundler/setup") end + it "should delete BUNDLER_SETUP even if it was present in original env" do + create_file("source.rb", <<-RUBY) + print #{modified_env}.has_key?('BUNDLER_SETUP') + RUBY + ENV["BUNDLER_ORIG_BUNDLER_SETUP"] = system_gem_path("gems/bundler-#{Bundler::VERSION}/lib/bundler/setup").to_s + bundle_exec_ruby bundled_app("source.rb") + expect(last_command.stdboth).to include "false" + end + it "should restore RUBYLIB", :ruby_repo do create_file("source.rb", <<-RUBY) print #{modified_env}['RUBYLIB'] diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb index 5ff555ab0ddcca..5be6eef7bd8801 100644 --- a/spec/bundler/runtime/inline_spec.rb +++ b/spec/bundler/runtime/inline_spec.rb @@ -670,6 +670,22 @@ def confirm(msg, newline = nil) expect(out).to be_empty end + it "does not reset ENV" do + script <<-RUBY + require 'bundler/inline' + + gemfile do + source "https://gem.repo1" + + ENV['FOO'] = 'bar' + end + + puts ENV['FOO'] + RUBY + + expect(out).to eq("bar") + end + it "does not load specified version of psych and stringio", :ruby_repo do build_repo4 do build_gem "psych", "999" diff --git a/test/rubygems/installer_test_case.rb b/test/rubygems/installer_test_case.rb index abddcbe8483917..8a34d28db86ec0 100644 --- a/test/rubygems/installer_test_case.rb +++ b/test/rubygems/installer_test_case.rb @@ -64,12 +64,6 @@ class Gem::Installer # A test case for Gem::Installer. class Gem::InstallerTestCase < Gem::TestCase - def setup - super - - Gem::Installer.path_warning = false - end - ## # The path where installed executables live diff --git a/test/rubygems/rubygems/commands/ins_command.rb b/test/rubygems/rubygems/commands/ins_command.rb new file mode 100644 index 00000000000000..8e2ac16f22e5a4 --- /dev/null +++ b/test/rubygems/rubygems/commands/ins_command.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class Gem::Commands::InsCommand < Gem::Command + def initialize + super("ins", "Does something different from install", {}) + end +end diff --git a/test/rubygems/rubygems/commands/interrupt_command.rb b/test/rubygems/rubygems/commands/interrupt_command.rb new file mode 100644 index 00000000000000..88d2ef22e73f5c --- /dev/null +++ b/test/rubygems/rubygems/commands/interrupt_command.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class Gem::Commands::InterruptCommand < Gem::Command + def initialize + super("interrupt", "Raises an Interrupt Exception", {}) + end + + def execute + raise Interrupt, "Interrupt exception" + end +end diff --git a/test/rubygems/rubygems_plugin.rb b/test/rubygems/rubygems_plugin.rb index 949580f9043faa..f9f2a7d91182b3 100644 --- a/test/rubygems/rubygems_plugin.rb +++ b/test/rubygems/rubygems_plugin.rb @@ -2,23 +2,4 @@ require "rubygems/command_manager" -## -# This is an example of exactly what NOT to do. -# -# DO NOT include code like this in your rubygems_plugin.rb - -module Gem::Commands - remove_const(:InterruptCommand) if defined?(InterruptCommand) -end - -class Gem::Commands::InterruptCommand < Gem::Command - def initialize - super("interrupt", "Raises an Interrupt Exception", {}) - end - - def execute - raise Interrupt, "Interrupt exception" - end -end - Gem::CommandManager.instance.register_command :interrupt diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index e8a294d65cfeef..0d048b08b7f01f 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -21,8 +21,6 @@ def setup common_installer_setup @additional = %w[a b].map {|d| File.join @tempdir, d } - - util_remove_interrupt_command end def test_self_finish_resolve @@ -1524,8 +1522,6 @@ def test_load_env_plugins nil end - util_remove_interrupt_command - # Should attempt to cause a StandardError with_plugin("standarderror") { Gem.load_env_plugins } begin @@ -1534,8 +1530,6 @@ def test_load_env_plugins nil end - util_remove_interrupt_command - # Should attempt to cause an Exception with_plugin("scripterror") { Gem.load_env_plugins } begin @@ -1791,11 +1785,6 @@ def util_exec_gem spec end - def util_remove_interrupt_command - Gem::Commands.send :remove_const, :InterruptCommand if - Gem::Commands.const_defined? :InterruptCommand - end - def util_cache_dir File.join Gem.dir, "cache" end diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index f04ec0cafafab4..f3848e498db8de 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -50,16 +50,17 @@ def test_find_logout_alias_comamnd end def test_find_command_ambiguous_exact - ins_command = Class.new - Gem::Commands.send :const_set, :InsCommand, ins_command + old_load_path = $:.dup + $: << File.expand_path("test/rubygems", PROJECT_DIR) @command_manager.register_command :ins command = @command_manager.find_command "ins" - assert_kind_of ins_command, command + assert_kind_of Gem::Commands::InsCommand, command ensure - Gem::Commands.send :remove_const, :InsCommand + $:.replace old_load_path + @command_manager.unregister_command :ins end def test_find_command_unknown diff --git a/test/rubygems/test_gem_commands_exec_command.rb b/test/rubygems/test_gem_commands_exec_command.rb index fd48ce73ca3365..c632ce62b2d524 100644 --- a/test/rubygems/test_gem_commands_exec_command.rb +++ b/test/rubygems/test_gem_commands_exec_command.rb @@ -493,7 +493,6 @@ def test_version_mismatch assert_equal 2, e.exit_code assert_equal <<~ERR, @ui.error ERROR: Could not find a valid gem 'a' (= 2) in any repository - ERROR: Possible alternatives: a ERR end end @@ -574,7 +573,6 @@ def test_conservative_missing_gem assert_include @ui.output, "a (= 2) not available locally" assert_equal <<~ERROR, @ui.error ERROR: Could not find a valid gem 'a' (= 2) in any repository - ERROR: Possible alternatives: a ERROR end end @@ -769,8 +767,7 @@ def test_only_prerelease_available assert_raise Gem::MockGemUi::TermError do invoke "a" end - assert_equal "ERROR: Could not find a valid gem 'a' (>= 0) in any repository\n" \ - "ERROR: Possible alternatives: a\n", @ui.error + assert_equal "ERROR: Could not find a valid gem 'a' (>= 0) in any repository\n", @ui.error assert_empty @ui.output assert_empty @installed_specs end diff --git a/test/rubygems/test_gem_commands_help_command.rb b/test/rubygems/test_gem_commands_help_command.rb index 359da0a6d01146..01ab4aab2fe46d 100644 --- a/test/rubygems/test_gem_commands_help_command.rb +++ b/test/rubygems/test_gem_commands_help_command.rb @@ -11,8 +11,6 @@ def setup super @cmd = Gem::Commands::HelpCommand.new - - load File.expand_path("rubygems_plugin.rb", __dir__) unless Gem::Commands.const_defined? :InterruptCommand end def test_gem_help_bad diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb index 2a989a55513b99..a0bfee023936cb 100644 --- a/test/rubygems/test_gem_dependency.rb +++ b/test/rubygems/test_gem_dependency.rb @@ -22,7 +22,7 @@ def test_initialize_type_bad Gem::Dependency.new "monkey" => "1.0" end - assert_equal 'dependency name must be a String, was {"monkey"=>"1.0"}', + assert_equal "dependency name must be a String, was #{{ "monkey" => "1.0" }.inspect}", e.message end diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index 6376f740326a2c..326aee147c4f88 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -208,7 +208,7 @@ def test_check_that_user_bin_dir_is_in_path ENV["PATH"] = [ENV["PATH"], bin_dir].join(File::PATH_SEPARATOR) use_ui @ui do - installer.check_that_user_bin_dir_is_in_path + installer.check_that_user_bin_dir_is_in_path(["executable"]) end assert_empty @ui.error @@ -218,7 +218,7 @@ def test_check_that_user_bin_dir_is_in_path ENV["PATH"] = [orig_path, bin_dir.tr(File::SEPARATOR, File::ALT_SEPARATOR)].join(File::PATH_SEPARATOR) use_ui @ui do - installer.check_that_user_bin_dir_is_in_path + installer.check_that_user_bin_dir_is_in_path(["executable"]) end assert_empty @ui.error @@ -236,7 +236,7 @@ def test_check_that_user_bin_dir_is_in_path_tilde installer.bin_dir.replace File.join @userhome, "bin" use_ui @ui do - installer.check_that_user_bin_dir_is_in_path + installer.check_that_user_bin_dir_is_in_path(["executable"]) end assert_empty @ui.error @@ -248,7 +248,7 @@ def test_check_that_user_bin_dir_is_in_path_not_in_path installer = setup_base_installer use_ui @ui do - installer.check_that_user_bin_dir_is_in_path + installer.check_that_user_bin_dir_is_in_path(["executable"]) end expected = installer.bin_dir @@ -258,6 +258,7 @@ def test_check_that_user_bin_dir_is_in_path_not_in_path end assert_match expected, @ui.error + assert_match "(executable)", @ui.error end def test_ensure_dependency @@ -358,10 +359,8 @@ def test_generate_bin_bindir_with_user_install_warning inst = Gem::Installer.at "", options - Gem::Installer.path_warning = false - use_ui @ui do - inst.check_that_user_bin_dir_is_in_path + inst.check_that_user_bin_dir_is_in_path(["executable"]) end assert_equal "", @ui.error diff --git a/test/rubygems/test_gem_resolver_api_set.rb b/test/rubygems/test_gem_resolver_api_set.rb index 5781cf37d26e13..b0b4943beafa97 100644 --- a/test/rubygems/test_gem_resolver_api_set.rb +++ b/test/rubygems/test_gem_resolver_api_set.rb @@ -136,6 +136,25 @@ def test_find_all_missing assert_empty set.find_all(a_dep) end + def test_find_all_not_found + spec_fetcher + + @fetcher.data["#{@dep_uri}/a"] = + proc do + raise Gem::RemoteFetcher::FetchError + end + + set = Gem::Resolver::APISet.new @dep_uri + + a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil + + assert_empty set.find_all(a_dep) + + @fetcher.data.delete "#{@dep_uri}a" + + assert_empty set.find_all(a_dep) + end + def test_prefetch spec_fetcher diff --git a/test/rubygems/test_gem_spec_fetcher.rb b/test/rubygems/test_gem_spec_fetcher.rb index cb4a4f7204778e..fac107b576bae8 100644 --- a/test/rubygems/test_gem_spec_fetcher.rb +++ b/test/rubygems/test_gem_spec_fetcher.rb @@ -168,20 +168,22 @@ def src.fetch_spec(name) def test_suggest_gems_from_name_latest spec_fetcher do|fetcher| fetcher.spec "example", 1 - fetcher.spec "other-example", 1 + fetcher.spec "an-example", 1 fetcher.spec "examp", 1 + fetcher.spec "other-example", 1 end suggestions = @sf.suggest_gems_from_name("examplw", :latest, 1) assert_equal ["example"], suggestions - suggestions = @sf.suggest_gems_from_name("other") - assert_equal ["other-example"], suggestions + suggestions = @sf.suggest_gems_from_name("anexample") + assert_equal ["an-example"], suggestions - suggestions = @sf.suggest_gems_from_name("exam") - assert suggestions.any? { ["examp"] } - assert suggestions.any? { ["example"] } - assert suggestions.any? { ["other-example"] } + suggestions = @sf.suggest_gems_from_name("xample") + assert_equal ["example"], suggestions + + suggestions = @sf.suggest_gems_from_name("other-apple") + assert_equal ["other-example"], suggestions end def test_suggest_gems_from_name_prerelease diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index 13acb001de4a78..fbe52aa3172486 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -3067,6 +3067,40 @@ def test_unresolved_specs_with_versions assert_equal(expected, actual_stderr) end + def test_unresolved_specs_with_duplicated_versions + specification = Gem::Specification.clone + + set_orig specification + + specification.define_singleton_method(:unresolved_deps) do + { b: Gem::Dependency.new("x","1") } + end + + specification.define_singleton_method(:find_all_by_name) do |_dep_name| + [ + specification.new {|s| s.name = "z", s.version = Gem::Version.new("1") }, # default copy + specification.new {|s| s.name = "z", s.version = Gem::Version.new("1") }, # regular copy + specification.new {|s| s.name = "z", s.version = Gem::Version.new("2") }, # regular copy + ] + end + + expected = <<-EXPECTED +WARN: Unresolved or ambiguous specs during Gem::Specification.reset: + x (= 1) + Available/installed versions of this gem: + - 1 + - 2 +WARN: Clearing out unresolved specs. Try 'gem cleanup ' +Please report a bug if this causes problems. + EXPECTED + + actual_stdout, actual_stderr = capture_output do + specification.reset + end + assert_empty actual_stdout + assert_equal(expected, actual_stderr) + end + def test_duplicate_runtime_dependency expected = "WARNING: duplicated b dependency [\"~> 3.0\", \"~> 3.0\"]\n" out, err = capture_output do diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb index b915a861970bf8..f15e9b624314d2 100644 --- a/test/rubygems/test_require.rb +++ b/test/rubygems/test_require.rb @@ -182,6 +182,22 @@ def test_require_is_not_lazy_with_exact_req assert_equal %w[a-1 b-1], loaded_spec_names end + def test_require_is_not_lazy_with_shadowed_default_gem + b1_default = new_default_spec("b", "1", nil, "foo.rb") + install_default_gems b1_default + + a1 = util_spec "a", "1", { "b" => ">= 1" }, "lib/test_gem_require_a.rb" + b1 = util_spec("b", "1", nil, "lib/foo.rb") + install_specs b1, a1 + + # Load default ruby gems fresh as if we've just started a ruby script. + Gem::Specification.reset + + assert_require "test_gem_require_a" + assert_equal %w[a-1 b-1], loaded_spec_names + assert_equal unresolved_names, [] + end + def test_require_is_lazy_with_inexact_req a1 = util_spec "a", "1", { "b" => ">= 1" }, "lib/test_gem_require_a.rb" b1 = util_spec "b", "1", nil, "lib/b/c.rb" @@ -705,11 +721,11 @@ def test_require_bundler _, err = capture_subprocess_io do system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "main.rb") end - assert_match(/{:x=>1}\n{:y=>2}\n$/, err) + assert_match(/#{{ x: 1 }.inspect}\n#{{ y: 2 }.inspect}\n$/, err) _, err = capture_subprocess_io do system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "main.rb") end - assert_match(/{:x=>1}\n{:y=>2}\n$/, err) + assert_match(/#{{ x: 1 }.inspect}\n#{{ y: 2 }.inspect}\n$/, err) end end end