diff options
author | David RodrÃguez <deivid.rodriguez@riseup.net> | 2019-09-18 10:06:10 +0200 |
---|---|---|
committer | David RodrÃguez <deivid.rodriguez@riseup.net> | 2019-09-19 16:02:47 +0200 |
commit | 6a7da1cc9a59cd7e1399f28b5398f1223b89c56a (patch) | |
tree | 860abee10c2fd84f974fbf3b2d5bc2bc5105e679 | |
parent | 71b96f25ca2970364be15496cd29bccf230b56f9 (diff) | |
download | bundler-6a7da1cc9a59cd7e1399f28b5398f1223b89c56a.tar.gz |
Replace `with_rubygems` script
Instead, use a better rubygems version manager that makes sure that
`ENV["RGV"]` usage is always applied, and its usage is centralized at a
single place.
This simplifies the rake task organization and makes it much simpler to
run locally exactly what's run in CI. For example, since it doesn't rely
on the `RGV` being deleted for subsequent subprocesses, it also running
`bin/rake spec:travis` task locally which previously would lead to
```
rake aborted!
RubyGems version is required on Travis!
```
It also reduces duplication making it so that we only need to change the
`.travis.yml` file when updating tested rubies, and not the `Rakefile`
as well.
-rw-r--r-- | Rakefile | 63 | ||||
-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 | 45 | ||||
-rw-r--r-- | spec/install/gemfile/git_spec.rb | 6 | ||||
-rw-r--r-- | spec/install/gemfile/path_spec.rb | 6 | ||||
-rw-r--r-- | spec/support/helpers.rb | 3 | ||||
-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 | 110 |
14 files changed, 132 insertions, 121 deletions
@@ -85,80 +85,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 59365e40ce..0000000000 --- a/bin/with_rubygems +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -require "pathname" -require_relative "../spec/support/helpers" - -class RubygemsVersionManager - include Spec::Helpers -end - -rubygems_version_manager = RubygemsVersionManager.new - -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 - rubygems_version_manager.sys_exec!("git clone https://github.com/rubygems/rubygems.git #{rubygems_path}") - end - Dir.chdir(rubygems_path) do - rubygems_version_manager.sys_exec!("git remote update") - version = "v#{version}" if version =~ /\A\d/ - rubygems_version_manager.sys_exec!("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/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/support/helpers.rb b/spec/support/helpers.rb index 92444ddd2f..ffcde39df7 100644 --- a/spec/support/helpers.rb +++ b/spec/support/helpers.rb @@ -116,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 @@ -149,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..83d33da7c3 --- /dev/null +++ b/spec/support/rubygems_version_manager.rb @@ -0,0 +1,110 @@ +# 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 + + 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 + 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 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_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 |