diff options
author | Bundlerbot <bot@bundler.io> | 2019-09-22 12:18:12 +0000 |
---|---|---|
committer | Bundlerbot <bot@bundler.io> | 2019-09-22 12:18:12 +0000 |
commit | 3260d5994ec33bfaf81162c61d0d20bfff023375 (patch) | |
tree | 5611a0f4144c1022ad67d79510e45ae6b3f6c144 | |
parent | ebe0b853d8f2ac93f9c69768ee6af2c18fbc9d87 (diff) | |
parent | 390832fcd17f0bedb6198b9ee71a0a240e171670 (diff) | |
download | bundler-3260d5994ec33bfaf81162c61d0d20bfff023375.tar.gz |
Merge #7296
7296: Improve exec'ing to the proper rubygems version r=deivid-rodriguez a=deivid-rodriguez
### What was the end-user problem that led to this PR?
The problem was that the `with_rubygems` script is hard to work with, because it does complicated ARGV manipulation before exec'ing.
### What was your diagnosis of the problem?
My diagnosis was that we don't need it.
### What is your fix for the problem, implemented in this PR?
My fix is to implement the same thing in a simpler way.
### Why did you choose this fix out of the possible options?
I chose this fix because it simplifies things.
Co-authored-by: David RodrÃguez <deivid.rodriguez@riseup.net>
-rw-r--r-- | .travis.yml | 11 | ||||
-rw-r--r-- | Rakefile | 66 | ||||
-rwxr-xr-x | bin/parallel_rspec | 2 | ||||
-rwxr-xr-x | bin/rake | 2 | ||||
-rwxr-xr-x | bin/ronn | 2 | ||||
-rwxr-xr-x | bin/rspec | 2 | ||||
-rwxr-xr-x | bin/rubocop | 2 | ||||
-rwxr-xr-x | bin/with_rubygems | 43 | ||||
-rw-r--r-- | spec/bundler/plugin_spec.rb | 2 | ||||
-rw-r--r-- | spec/bundler/ui/shell_spec.rb | 2 | ||||
-rw-r--r-- | spec/install/gemfile/git_spec.rb | 6 | ||||
-rw-r--r-- | spec/install/gemfile/path_spec.rb | 6 | ||||
-rw-r--r-- | spec/realworld/dependency_api_spec.rb | 2 | ||||
-rw-r--r-- | spec/realworld/gemfile_source_header_spec.rb | 2 | ||||
-rw-r--r-- | spec/realworld/mirror_probe_spec.rb | 2 | ||||
-rw-r--r-- | spec/spec_helper.rb | 15 | ||||
-rw-r--r-- | spec/support/helpers.rb | 6 | ||||
-rw-r--r-- | spec/support/path.rb | 2 | ||||
-rw-r--r-- | spec/support/rubygems.rb | 7 | ||||
-rw-r--r-- | spec/support/rubygems_ext.rb | 1 | ||||
-rw-r--r-- | spec/support/rubygems_version_manager.rb | 123 |
21 files changed, 175 insertions, 131 deletions
diff --git a/.travis.yml b/.travis.yml index f2291c7f5c..e1b9bc738d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,11 @@ language: ruby dist: bionic -script: rake spec:travis +script: bin/rake spec:travis before_script: - - rake override_version - - travis_retry rake spec:travis:deps - - rake man:check + - gem install rake:"~> 12.0" + - bin/rake override_version + - travis_retry bin/rake spec:travis:deps + - bin/rake man:check branches: only: @@ -45,7 +46,7 @@ env: jobs: include: - rvm: 2.6.4 - script: rake rubocop + script: bin/rake rubocop stage: linting # Ruby 2.3 also tested in 2.x mode - rvm: 2.3.8 @@ -50,9 +50,6 @@ namespace :spec do # Install graphviz so that the viz specs can run sh "sudo apt-get install graphviz -y" - # Install the gems with a consistent version of RubyGems - sh "gem update --system 3.0.6" - # Install the other gem deps, etc Rake::Task["spec:deps"].invoke end @@ -85,80 +82,27 @@ namespace :spec do ENV["BUNDLER_SUDO_TESTS"] = "1" end - # RubyGems specs by version - namespace :rubygems do - # When editing this list, also edit .travis.yml! - branches = %w[master] - releases = %w[v2.5.2 v2.6.14 v2.7.10 v3.0.6] - (branches + releases).each do |rg| - desc "Run specs with RubyGems #{rg}" - task "parallel_#{rg}" do - sh("bin/parallel_rspec spec/") - end - - task rg do - sh("bin/rspec --format progress") - end - - # Create tasks like spec:rubygems:v1.8.3:sudo to run the sudo specs - namespace rg do - task :sudo => ["set_sudo", rg] - task :realworld => ["set_realworld", rg] - end - - task "set_#{rg}" do - ENV["RGV"] = rg - end - - task rg => ["set_#{rg}"] - task "rubygems:all" => rg - end - - desc "Run specs under a RubyGems checkout (set RGV=path)" - task "co" do - sh("bin/parallel_rspec spec/") - end - - namespace "co" do - task :sudo => ["set_sudo", "co"] - task :realworld => ["set_realworld", "co"] - end - - task "setup_co" do - ENV["RGV"] = if `git -C "#{File.expand_path("..")}" remote --verbose 2> #{IO::NULL}` =~ /rubygems/i - File.expand_path("..") - else - File.expand_path("tmp/rubygems") - end - end - - task "co" => "setup_co" - task "rubygems:all" => "co" - end - desc "Run the tests on Travis CI against a RubyGem version (using ENV['RGV'])" task :travis do rg = ENV["RGV"] || raise("RubyGems version is required on Travis!") - rg = "co" if File.directory?(File.expand_path(ENV["RGV"])) - # disallow making network requests on CI ENV["BUNDLER_SPEC_PRE_RECORDED"] = "TRUE" puts "\n\e[1;33m[Travis CI] Running bundler specs against RubyGems #{rg}\e[m\n\n" - specs = safe_task { Rake::Task["spec:rubygems:#{rg}"].invoke } + specs = safe_task { Rake::Task["spec"].invoke } - Rake::Task["spec:rubygems:#{rg}"].reenable + Rake::Task["spec"].reenable puts "\n\e[1;33m[Travis CI] Running bundler sudo specs against RubyGems #{rg}\e[m\n\n" - sudos = system("sudo -E rake spec:rubygems:#{rg}:sudo") + sudos = system("sudo -E rake spec:sudo") # clean up by chowning the newly root-owned tmp directory back to the travis user system("sudo chown -R #{ENV["USER"]} #{File.join(File.dirname(__FILE__), "tmp")}") - Rake::Task["spec:rubygems:#{rg}"].reenable + Rake::Task["spec"].reenable puts "\n\e[1;33m[Travis CI] Running bundler real world specs against RubyGems #{rg}\e[m\n\n" - realworld = safe_task { Rake::Task["spec:rubygems:#{rg}:realworld"].invoke } + realworld = safe_task { Rake::Task["spec:realworld"].invoke } { "specs" => specs, "sudo" => sudos, "realworld" => realworld }.each do |name, passed| if passed diff --git a/bin/parallel_rspec b/bin/parallel_rspec index 9783533198..c6fb33d583 100755 --- a/bin/parallel_rspec +++ b/bin/parallel_rspec @@ -1,8 +1,6 @@ #!/usr/bin/env ruby # frozen_string_literal: true -load File.expand_path("../with_rubygems", __FILE__) if ENV["RGV"] - require_relative "../spec/support/rubygems_ext" Spec::Rubygems.gem_load("parallel_tests", "parallel_rspec") @@ -1,8 +1,6 @@ #!/usr/bin/env ruby # frozen_string_literal: true -load File.expand_path("../with_rubygems", __FILE__) if ENV["RGV"] - require_relative "../spec/support/rubygems_ext" Spec::Rubygems.gem_load("rake", "rake") @@ -1,8 +1,6 @@ #!/usr/bin/env ruby # frozen_string_literal: true -load File.expand_path("../with_rubygems", __FILE__) if ENV["RGV"] - require_relative "../spec/support/rubygems_ext" Spec::Rubygems.gem_load("ronn", "ronn") @@ -1,8 +1,6 @@ #!/usr/bin/env ruby # frozen_string_literal: true -load File.expand_path("../with_rubygems", __FILE__) if ENV["RGV"] - require_relative "../spec/support/rubygems_ext" Spec::Rubygems.gem_load("rspec-core", "rspec") diff --git a/bin/rubocop b/bin/rubocop index 818aaf7a9d..3716bffe31 100755 --- a/bin/rubocop +++ b/bin/rubocop @@ -1,8 +1,6 @@ #!/usr/bin/env ruby # frozen_string_literal: true -load File.expand_path("../with_rubygems", __FILE__) if ENV["RGV"] - require_relative "../spec/support/rubygems_ext" Spec::Rubygems.gem_load("rubocop", "rubocop") diff --git a/bin/with_rubygems b/bin/with_rubygems deleted file mode 100755 index 96299669be..0000000000 --- a/bin/with_rubygems +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -require "pathname" - -def run(*cmd) - return if system(*cmd, :out => IO::NULL) - raise "Running `#{cmd.join(" ")}` failed" -end - -version = ENV.delete("RGV") -rubygems_path = Pathname.new(version).expand_path -unless rubygems_path.directory? - rubygems_path = Pathname.new("tmp/rubygems").expand_path - unless rubygems_path.directory? - rubygems_path.parent.mkpath unless rubygems_path.directory? - run("git", "clone", "https://github.com/rubygems/rubygems.git", rubygems_path.to_s) - end - Dir.chdir(rubygems_path) do - run("git remote update") - version = "v#{version}" if version =~ /\A\d/ - run("git", "checkout", version, "--quiet") - end -end - -rubygems_lib = rubygems_path + "lib" -ENV["RUBYOPT"] = %(-I#{rubygems_lib} #{ENV["RUBYOPT"]}) - -if $0 != __FILE__ - ARGV.unshift($0) -elsif cmd = ARGV.first - possible_dirs = [ - Pathname.new(__FILE__) + "..", - Pathname.new(__FILE__) + "../../exe", - rubygems_path + "bin", - ] - cmd = possible_dirs.map do |dir| - dir.join(cmd).expand_path - end.find(&:file?) - ARGV[0] = cmd.to_s if cmd -end - -exec(*ARGV) diff --git a/spec/bundler/plugin_spec.rb b/spec/bundler/plugin_spec.rb index eaa0b80905..e0e2e9afdf 100644 --- a/spec/bundler/plugin_spec.rb +++ b/spec/bundler/plugin_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require_relative "../support/streams" + RSpec.describe Bundler::Plugin do Plugin = Bundler::Plugin diff --git a/spec/bundler/ui/shell_spec.rb b/spec/bundler/ui/shell_spec.rb index 632477096e..536014c6aa 100644 --- a/spec/bundler/ui/shell_spec.rb +++ b/spec/bundler/ui/shell_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require_relative "../../support/streams" + RSpec.describe Bundler::UI::Shell do subject { described_class.new } diff --git a/spec/install/gemfile/git_spec.rb b/spec/install/gemfile/git_spec.rb index 7eb05a995c..014724a292 100644 --- a/spec/install/gemfile/git_spec.rb +++ b/spec/install/gemfile/git_spec.rb @@ -1056,7 +1056,7 @@ RSpec.describe "bundle install with git sources" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require 'rubygems' + require '#{spec_dir}/support/rubygems' Gem.pre_install_hooks << lambda do |inst| STDERR.puts "Ran pre-install hook: \#{inst.spec.full_name}" end @@ -1076,7 +1076,7 @@ RSpec.describe "bundle install with git sources" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require 'rubygems' + require '#{spec_dir}/support/rubygems' Gem.post_install_hooks << lambda do |inst| STDERR.puts "Ran post-install hook: \#{inst.spec.full_name}" end @@ -1096,7 +1096,7 @@ RSpec.describe "bundle install with git sources" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require 'rubygems' + require '#{spec_dir}/support/rubygems' Gem.pre_install_hooks << lambda do |inst| false end diff --git a/spec/install/gemfile/path_spec.rb b/spec/install/gemfile/path_spec.rb index 3f2e5bdfc3..5261e18bbe 100644 --- a/spec/install/gemfile/path_spec.rb +++ b/spec/install/gemfile/path_spec.rb @@ -672,7 +672,7 @@ RSpec.describe "bundle install with explicit source paths" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require 'rubygems' + require '#{spec_dir}/support/rubygems' Gem.pre_install_hooks << lambda do |inst| STDERR.puts "Ran pre-install hook: \#{inst.spec.full_name}" end @@ -692,7 +692,7 @@ RSpec.describe "bundle install with explicit source paths" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require 'rubygems' + require '#{spec_dir}/support/rubygems' Gem.post_install_hooks << lambda do |inst| STDERR.puts "Ran post-install hook: \#{inst.spec.full_name}" end @@ -712,7 +712,7 @@ RSpec.describe "bundle install with explicit source paths" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require 'rubygems' + require '#{spec_dir}/support/rubygems' Gem.pre_install_hooks << lambda do |inst| false end diff --git a/spec/realworld/dependency_api_spec.rb b/spec/realworld/dependency_api_spec.rb index e7d11419cd..c04003073e 100644 --- a/spec/realworld/dependency_api_spec.rb +++ b/spec/realworld/dependency_api_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require_relative "../support/silent_logger" + RSpec.describe "gemcutter's dependency API", :realworld => true do context "when Gemcutter API takes too long to respond" do before do diff --git a/spec/realworld/gemfile_source_header_spec.rb b/spec/realworld/gemfile_source_header_spec.rb index 382485b8fc..8658c836c3 100644 --- a/spec/realworld/gemfile_source_header_spec.rb +++ b/spec/realworld/gemfile_source_header_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require_relative "../support/silent_logger" + RSpec.describe "fetching dependencies with a mirrored source", :realworld => true do let(:mirror) { "https://server.example.org" } let(:original) { "http://127.0.0.1:#{@port}" } diff --git a/spec/realworld/mirror_probe_spec.rb b/spec/realworld/mirror_probe_spec.rb index 13d1afe124..a0db3cd9ec 100644 --- a/spec/realworld/mirror_probe_spec.rb +++ b/spec/realworld/mirror_probe_spec.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require_relative "../support/silent_logger" + RSpec.describe "fetching dependencies with a not available mirror", :realworld => true do let(:mirror) { @mirror_uri } let(:original) { @server_uri } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 970d350dca..f43dd7e44e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -15,10 +15,17 @@ end require "bundler" require "rspec" -Dir["#{File.expand_path("../support", __FILE__)}/*.rb"].each do |file| - file = file.gsub(%r{\A#{Regexp.escape File.expand_path("..", __FILE__)}/}, "") - require file unless file.end_with?("hax.rb") -end +require_relative "support/builders" +require_relative "support/filters" +require_relative "support/helpers" +require_relative "support/indexes" +require_relative "support/matchers" +require_relative "support/path" +require_relative "support/parallel" +require_relative "support/permissions" +require_relative "support/platforms" +require_relative "support/sometimes" +require_relative "support/sudo" $debug = false diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb index b5617d399f..ffcde39df7 100644 --- a/spec/support/helpers.rb +++ b/spec/support/helpers.rb @@ -2,6 +2,9 @@ require "open3" +require_relative "command_execution" +require_relative "the_bundle" + module Spec module Helpers def reset! @@ -113,6 +116,7 @@ module Spec env["PATH"].gsub!("#{Path.root}/exe", "") if env["PATH"] && system_bundler requires = options.delete(:requires) || [] + requires << "support/rubygems" requires << "support/hax" artifice = options.delete(:artifice) do @@ -146,7 +150,7 @@ module Spec end end.join - cmd = "#{sudo} #{Gem.ruby} #{load_path_str} #{requires_str} #{bundle_bin} #{cmd}#{args}" + cmd = "#{sudo} #{Gem.ruby} --disable-gems #{load_path_str} #{requires_str} #{bundle_bin} #{cmd}#{args}" sys_exec(cmd, env) {|i, o, thr| yield i, o, thr if block_given? } end bang :bundle diff --git a/spec/support/path.rb b/spec/support/path.rb index db28454792..79b55dd42a 100644 --- a/spec/support/path.rb +++ b/spec/support/path.rb @@ -22,7 +22,7 @@ module Spec end def gem_bin - @gem_bin ||= ruby_core? ? ENV["GEM_COMMAND"] : "#{Gem.ruby} -S gem --backtrace" + @gem_bin ||= ruby_core? ? ENV["GEM_COMMAND"] : "#{Gem.ruby} --disable-gems -r#{spec_dir}/support/rubygems -S gem --backtrace" end def spec_dir diff --git a/spec/support/rubygems.rb b/spec/support/rubygems.rb new file mode 100644 index 0000000000..e60f9a928e --- /dev/null +++ b/spec/support/rubygems.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require_relative "rubygems_version_manager" + +RubygemsVersionManager.new(ENV["RGV"]).switch + +require "rubygems" diff --git a/spec/support/rubygems_ext.rb b/spec/support/rubygems_ext.rb index 22374d9f39..aee1f85594 100644 --- a/spec/support/rubygems_ext.rb +++ b/spec/support/rubygems_ext.rb @@ -40,6 +40,7 @@ module Spec end def gem_load(gem_name, bin_container) + require_relative "rubygems" gem_load_and_activate(gem_name, bin_container) end diff --git a/spec/support/rubygems_version_manager.rb b/spec/support/rubygems_version_manager.rb new file mode 100644 index 0000000000..4be90f7679 --- /dev/null +++ b/spec/support/rubygems_version_manager.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +require "pathname" +require_relative "helpers" + +class RubygemsVersionManager + include Spec::Helpers + + def initialize(env_version) + @env_version = env_version + end + + def switch + return if use_system? + + unrequire_rubygems_if_needed + + switch_local_copy_if_needed + + prepare_environment + end + +private + + def use_system? + @env_version.nil? + end + + def unrequire_rubygems_if_needed + return unless rubygems_unrequire_needed? + + require "rbconfig" + + ruby = File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["ruby_install_name"]) + ruby << RbConfig::CONFIG["EXEEXT"] + + cmd = [ruby, $0, *ARGV].compact + cmd[1, 0] = "--disable-gems" + + exec(ENV, *cmd) + end + + def switch_local_copy_if_needed + return unless local_copy_switch_needed? + + Dir.chdir(local_copy_path) do + sys_exec!("git remote update") + sys_exec!("git checkout #{target_tag_version} --quiet") + end + end + + def prepare_environment + $:.unshift File.expand_path("lib", local_copy_path) + end + + def rubygems_unrequire_needed? + defined?(Gem) && Gem::VERSION != target_gem_version + end + + def local_copy_switch_needed? + !env_version_is_path? && target_gem_version != local_copy_version + end + + def target_gem_version + @target_gem_version ||= resolve_target_gem_version + end + + def target_tag_version + @target_tag_version ||= resolve_target_tag_version + end + + def local_copy_version + gemspec_contents = File.read(local_copy_path.join("lib/rubygems.rb")) + version_regexp = /VERSION = ["'](.*)["']/ + + version_regexp.match(gemspec_contents)[1] + end + + def local_copy_path + @local_copy_path ||= resolve_local_copy_path + end + + def resolve_local_copy_path + return expanded_env_version if env_version_is_path? + + rubygems_path = Pathname.new("../../tmp/rubygems").expand_path(__dir__) + + unless rubygems_path.directory? + rubygems_path.parent.mkpath + sys_exec!("git clone https://github.com/rubygems/rubygems.git #{rubygems_path}") + end + + rubygems_path + end + + def env_version_is_path? + expanded_env_version.directory? + end + + def expanded_env_version + @expanded_env_version ||= Pathname.new(@env_version).expand_path + end + + def resolve_target_tag_version + return "v#{@env_version}" if @env_version.match(/^\d/) + + return "master" if @env_version == master_gem_version + + @env_version + end + + def resolve_target_gem_version + return @env_version[1..-1] if @env_version.match(/^v/) + + return master_gem_version if @env_version == "master" + + @env_version + end + + def master_gem_version + "3.1.0.pre1" + end +end |