From 3f91c3572abee43ff50c6ba37af70dfe3a91994d Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Mon, 18 Jul 2016 19:50:47 -0500 Subject: YOU get a side effect, and YOU get a side effect, and YOU get a side effect --- .rubocop_todo.yml | 1 - exe/bundle_ruby | 4 +- lib/bundler.rb | 43 ++++-- lib/bundler/cli.rb | 8 +- lib/bundler/cli/exec.rb | 2 +- lib/bundler/index.rb | 8 +- lib/bundler/inline.rb | 6 +- lib/bundler/resolver.rb | 4 +- lib/bundler/rubygems_gem_installer.rb | 6 + lib/bundler/source/rubygems.rb | 2 +- .../lib/compact_index_client.rb | 1 + spec/bundler/gem_helper_spec.rb | 1 + spec/commands/console_spec.rb | 4 + spec/commands/exec_spec.rb | 12 +- spec/commands/update_spec.rb | 2 +- spec/install/gemfile/platform_spec.rb | 2 +- spec/install/gems/compact_index_spec.rb | 50 +++---- spec/install/gems/dependency_api_spec.rb | 4 +- spec/install/gems/resolving_spec.rb | 2 +- spec/other/trampoline_spec.rb | 20 +-- spec/runtime/inline_spec.rb | 12 +- spec/runtime/setup_spec.rb | 10 +- spec/spec_helper.rb | 7 +- spec/support/artifice/compact_index.rb | 114 ---------------- spec/support/artifice/compact_index_api.rb | 114 ++++++++++++++++ spec/support/artifice/compact_index_api_missing.rb | 7 +- .../artifice/compact_index_basic_authentication.rb | 6 +- .../artifice/compact_index_checksum_mismatch.rb | 6 +- .../artifice/compact_index_concurrent_download.rb | 6 +- .../artifice/compact_index_creds_diff_host.rb | 6 +- spec/support/artifice/compact_index_extra.rb | 6 +- spec/support/artifice/compact_index_extra_api.rb | 6 +- .../artifice/compact_index_extra_missing.rb | 4 +- spec/support/artifice/compact_index_forbidden.rb | 6 +- .../artifice/compact_index_host_redirect.rb | 6 +- spec/support/artifice/compact_index_redirects.rb | 6 +- .../compact_index_strict_basic_authentication.rb | 6 +- .../endopint_marshal_fail_basic_authentication.rb | 4 +- spec/support/artifice/endpoint.rb | 23 ++-- spec/support/artifice/endpoint_500.rb | 7 +- spec/support/artifice/endpoint_api_forbidden.rb | 4 +- spec/support/artifice/endpoint_api_missing.rb | 4 +- .../artifice/endpoint_basic_authentication.rb | 4 +- spec/support/artifice/endpoint_creds_diff_host.rb | 4 +- spec/support/artifice/endpoint_extra.rb | 4 +- spec/support/artifice/endpoint_extra_api.rb | 4 +- spec/support/artifice/endpoint_extra_missing.rb | 4 +- spec/support/artifice/endpoint_fallback.rb | 4 +- spec/support/artifice/endpoint_host_redirect.rb | 4 +- spec/support/artifice/endpoint_marshal_fail.rb | 4 +- spec/support/artifice/endpoint_mirror_source.rb | 4 +- spec/support/artifice/endpoint_redirect.rb | 4 +- .../endpoint_strict_basic_authentication.rb | 4 +- spec/support/artifice/endpoint_timeout.rb | 4 +- spec/support/artifice/windows.rb | 48 +++++++ spec/support/builders.rb | 4 +- spec/support/fakeweb/rack-1.0.0.marshal | 2 - spec/support/fakeweb/windows.rb | 27 ---- spec/support/hax.rb | 58 ++++---- spec/support/helpers.rb | 152 +++++++++++++++++---- spec/support/rubygems_ext.rb | 4 +- spec/support/unhax.rb | 20 +++ 62 files changed, 549 insertions(+), 366 deletions(-) delete mode 100644 spec/support/artifice/compact_index.rb create mode 100644 spec/support/artifice/compact_index_api.rb create mode 100644 spec/support/artifice/windows.rb delete mode 100644 spec/support/fakeweb/rack-1.0.0.marshal delete mode 100644 spec/support/fakeweb/windows.rb create mode 100644 spec/support/unhax.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 686c189839..4fbea7b8a3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -245,4 +245,3 @@ Style/UnneededInterpolation: - 'spec/commands/exec_spec.rb' - 'spec/support/artifice/endpoint.rb' - 'spec/support/artifice/endpoint_500.rb' - - 'spec/support/fakeweb/windows.rb' diff --git a/exe/bundle_ruby b/exe/bundle_ruby index 847708c3ea..fbbd7f83e5 100755 --- a/exe/bundle_ruby +++ b/exe/bundle_ruby @@ -9,7 +9,7 @@ require "bundler/ruby_dsl" require "bundler/shared_helpers" module Bundler - class Dsl + class BundleRubyDsl include RubyDsl attr_accessor :ruby_version @@ -44,7 +44,7 @@ end Bundler::SharedHelpers.major_deprecation("the bundle_ruby executable has been removed in favor of `bundle platform --ruby`") -dsl = Bundler::Dsl.new +dsl = Bundler::BundleRubyDsl.new begin dsl.eval_gemfile(Bundler::SharedHelpers.default_gemfile) ruby_version = dsl.ruby_version diff --git a/lib/bundler.rb b/lib/bundler.rb index 6d64a2eb28..b9609e324c 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -2,6 +2,7 @@ require "fileutils" require "pathname" require "rbconfig" +require "set" require "thread" require "bundler/errors" require "bundler/environment_preserver" @@ -14,9 +15,14 @@ require "bundler/constants" require "bundler/current_ruby" module Bundler - environment_preserver = EnvironmentPreserver.new(ENV, %w(PATH GEM_PATH)) - ORIGINAL_ENV = environment_preserver.restore - ENV.replace(environment_preserver.backup) + ORIGINAL_ENV = {} # rubocop:disable Style/MutableConstant + def self.preserve_env! + environment_preserver = EnvironmentPreserver.new(ENV, %w(PATH GEM_PATH)) + ORIGINAL_ENV.replace environment_preserver.restore + ENV.replace(environment_preserver.backup) + end + preserve_env! + SUDO_MUTEX = Mutex.new autoload :Definition, "bundler/definition" @@ -245,7 +251,7 @@ module Bundler end def clean_exec(*args) - with_clean_env { Kernel.exec(*args) } + with_clean_env { kernel_exec(*args) } end def default_gemfile @@ -381,20 +387,39 @@ module Bundler end def reset! - @root = nil - @settings = nil + @bin_path = nil + @bundle_path = nil + @configured = nil @definition = nil - @setup = nil @load = nil @locked_gems = nil - @bundle_path = nil - @bin_path = nil + @root = nil + @settings = nil + @setup = nil + Plugin.module_eval do + instance_variables.each do |ivar| + if (val = instance_variable_get(ivar)) && val.respond_to?(:clear) + val.clear + else + remove_instance_variable(ivar) + end + end + end + + Installer.ambiguous_gems.clear + Installer.post_install_messages.clear + + clear_gemspec_cache return unless defined?(@rubygems) && @rubygems rubygems.undo_replacements rubygems.reset @rubygems = nil end + def kernel_exec(*args) + Kernel.exec(*args) + end + private def eval_yaml_gemspec(path, contents) diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index ed81ffbf35..587ed949fe 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -74,25 +74,25 @@ module Bundler root = File.expand_path("../man", __FILE__) if Bundler.which("man") && root !~ %r{^file:/.+!/META-INF/jruby.home/.+} - Kernel.exec "man #{root}/#{command}" + Bundler.kernel_exec "man #{root}/#{command}" else puts File.read("#{root}/#{command}.txt") end elsif command_path = Bundler.which("bundler-#{cli}") - Kernel.exec(command_path, "--help") + Bundler.kernel_exec(command_path, "--help") else super end end - def self.handle_no_command_error(command, has_namespace = $thor_runner) + def self.handle_no_command_error(command, has_namespace = defined?($thor_runner) && $thor_runner) if Bundler.settings[:plugins] && Bundler::Plugin.command?(command) return Bundler::Plugin.exec_command(command, ARGV[1..-1]) end return super unless command_path = Bundler.which("bundler-#{command}") - Kernel.exec(command_path, *ARGV[1..-1]) + Bundler.kernel_exec(command_path, *ARGV[1..-1]) end desc "init [OPTIONS]", "Generates a Gemfile into the current working directory" diff --git a/lib/bundler/cli/exec.rb b/lib/bundler/cli/exec.rb index 4371887f2a..376a914c49 100644 --- a/lib/bundler/cli/exec.rb +++ b/lib/bundler/cli/exec.rb @@ -43,7 +43,7 @@ module Bundler def kernel_exec(*args) ui = Bundler.ui Bundler.ui = nil - Kernel.exec(*args) + Bundler.kernel_exec(*args) rescue Errno::EACCES, Errno::ENOEXEC Bundler.ui = ui Bundler.ui.error "bundler: not executable: #{cmd}" diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index f0ee411df8..870315e0e0 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -163,11 +163,9 @@ module Bundler specs += base if base found = specs.select do |spec| next true if spec.source.is_a?(Source::Gemspec) - if base # allow all platforms when searching from a lockfile - dependency.matches_spec?(spec) - else - dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform) - end + next false unless dependency.matches_spec?(spec) + next true if base # allow all platforms when searching from a lockfile + Gem::Platform.match(spec.platform) # otherwise, the platform must also match end wants_prerelease = dependency.requirement.prerelease? diff --git a/lib/bundler/inline.rb b/lib/bundler/inline.rb index 6f3cd6c132..4617e1c152 100644 --- a/lib/bundler/inline.rb +++ b/lib/bundler/inline.rb @@ -36,6 +36,7 @@ def gemfile(install = false, options = {}, &gemfile) raise ArgumentError, "Unknown options: #{opts.keys.join(", ")}" unless opts.empty? old_root = Bundler.method(:root) + (class << Bundler; self; end).send(:remove_method, :root) def Bundler.root Bundler::SharedHelpers.pwd.expand_path end @@ -70,5 +71,8 @@ def gemfile(install = false, options = {}, &gemfile) runtime.setup.require ensure bundler_module = class << Bundler; self; end - bundler_module.send(:define_method, :root, old_root) if old_root + if old_root + bundler_module.send(:remove_method, :root) + bundler_module.send(:define_method, :root, old_root) + end end diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 9d947cc9f9..c9df6e533e 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -81,7 +81,9 @@ module Bundler @specs = {} ALL.each do |p| - @specs[p] = reverse.find {|s| s.match_platform(p) } + if match = reverse.find {|s| s.match_platform(p) } + @specs[p] = match + end end end diff --git a/lib/bundler/rubygems_gem_installer.rb b/lib/bundler/rubygems_gem_installer.rb index 43637e1e60..13efa574ed 100644 --- a/lib/bundler/rubygems_gem_installer.rb +++ b/lib/bundler/rubygems_gem_installer.rb @@ -3,6 +3,12 @@ require "rubygems/installer" module Bundler class RubyGemsGemInstaller < Gem::Installer + def self.at(path, options = {}) + security_policy = options[:security_policy] + package = Gem::Package.new path, security_policy + new package, options + end + def check_executable_overwrite(filename) # Bundler needs to install gems regardless of binstub overwriting end diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index d9606e7087..aedad7086d 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -134,7 +134,7 @@ module Bundler installed_spec = nil Bundler.rubygems.preserve_paths do - installed_spec = Bundler::RubyGemsGemInstaller.new( + installed_spec = Bundler::RubyGemsGemInstaller.at( path, :install_dir => install_path.to_s, :bin_dir => bin_path.to_s, diff --git a/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb b/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb index 1679c17c8a..cf1ce7a8b5 100644 --- a/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb +++ b/lib/bundler/vendor/compact_index_client/lib/compact_index_client.rb @@ -22,6 +22,7 @@ class Bundler::CompactIndexClient @cache = Cache.new(@directory) @endpoints = Set.new @info_checksums_by_name = {} + @parsed_checksums = false @in_parallel = lambda do |inputs, &blk| inputs.map(&blk) end diff --git a/spec/bundler/gem_helper_spec.rb b/spec/bundler/gem_helper_spec.rb index def926e364..585af1162e 100644 --- a/spec/bundler/gem_helper_spec.rb +++ b/spec/bundler/gem_helper_spec.rb @@ -10,6 +10,7 @@ describe Bundler::GemHelper do before(:each) do global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false" + Object.send(:remove_const, :LoremIpsum) if defined?(::LoremIpsum) bundle "gem #{app_name}" end diff --git a/spec/commands/console_spec.rb b/spec/commands/console_spec.rb index b60ac2c9f6..633f193b4c 100644 --- a/spec/commands/console_spec.rb +++ b/spec/commands/console_spec.rb @@ -2,6 +2,10 @@ require "spec_helper" describe "bundle console" do + before :all do + require "irb" + end + before :each do install_gemfile <<-G source "file://#{gem_repo1}" diff --git a/spec/commands/exec_spec.rb b/spec/commands/exec_spec.rb index cf10521fac..ca461618aa 100644 --- a/spec/commands/exec_spec.rb +++ b/spec/commands/exec_spec.rb @@ -429,22 +429,20 @@ describe "bundle exec" do gem "foo", :path => "#{lib_path("foo-1.0")}" G - bundle "exec irb", :expect_err => true + bundle "exec ruby -e 'puts \"loaded!\"'", :expect_err => true expect(err).to match("The gemspec at #{lib_path("foo-1.0").join("foo.gemspec")} is not valid") expect(err).to match('"TODO" is not a summary') + expect(out).to_not include("loaded!") end end describe "with gems bundled for deployment" do it "works when calling bundler from another script" do gemfile <<-G - module Monkey - def bin_path(a,b,c) - raise Gem::GemNotFoundException.new('Fail') - end + Bundler.rubygems.redefine_method(Bundler.rubygems.class, :bin_path) do |*args| + raise Gem::GemNotFoundException.new('Fail') end - Bundler.rubygems.extend(Monkey) G bundle "install --deployment" bundle "exec ruby -e '`../../exe/bundler -v`; puts $?.success?'" @@ -552,7 +550,7 @@ describe "bundle exec" do begin Thread.new do puts 'Started' # For process sync - STDOUT.flush + $stdout.flush sleep 1 # ignore quality_spec raise "Didn't receive INT at all" end.join diff --git a/spec/commands/update_spec.rb b/spec/commands/update_spec.rb index 5207278794..fd141d6932 100644 --- a/spec/commands/update_spec.rb +++ b/spec/commands/update_spec.rb @@ -28,7 +28,7 @@ describe "bundle update" do source "file://#{gem_repo2}" gem "activesupport" gem "rack-obama" - exit! + abort 'ouch' G bundle "update" expect(bundled_app("Gemfile.lock")).to exist diff --git a/spec/install/gemfile/platform_spec.rb b/spec/install/gemfile/platform_spec.rb index a562a3bc11..59028ed8a7 100644 --- a/spec/install/gemfile/platform_spec.rb +++ b/spec/install/gemfile/platform_spec.rb @@ -216,7 +216,7 @@ describe "when a gem has no architecture" do gem "rcov" G - bundle :install, :fakeweb => "windows" + bundle :install, :artifice => "windows" should_be_installed "rcov 1.0.0" end end diff --git a/spec/install/gems/compact_index_spec.rb b/spec/install/gems/compact_index_spec.rb index e96936f01d..4aac9d4d08 100644 --- a/spec/install/gems/compact_index_spec.rb +++ b/spec/install/gems/compact_index_spec.rb @@ -11,7 +11,7 @@ describe "compact index api" do gem "rack" G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" expect(out).to include("Fetching gem metadata from #{source_uri}") should_be_installed "rack 1.0.0" end @@ -22,7 +22,7 @@ describe "compact index api" do gem " sinatra" G - bundle :install, :artifice => "compact_index" + bundle :install, :artifice => "compact_index_api" expect(out).to include("' sinatra' is not a valid gem name because it contains whitespace.") end @@ -32,7 +32,7 @@ describe "compact index api" do gem "rails" G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" expect(out).to include("Fetching gem metadata from #{source_uri}") should_be_installed( "rails 2.3.2", @@ -49,7 +49,7 @@ describe "compact index api" do gem "net-sftp" G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" should_be_installed "net-sftp 1.1.1" end @@ -58,9 +58,9 @@ describe "compact index api" do source "#{source_uri}" gem "rack" G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" - bundle "install --deployment", :artifice => "compact_index" + bundle "install --deployment", :artifice => "compact_index_api" expect(out).to include("Fetching gem metadata from #{source_uri}") should_be_installed "rack 1.0.0" end @@ -78,7 +78,7 @@ describe "compact index api" do end G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" should_be_installed("rails 2.3.2") end @@ -94,9 +94,9 @@ describe "compact index api" do gem 'foo', :git => "file:///#{lib_path("foo-1.0")}" G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" - bundle "install --deployment", :artifice => "compact_index" + bundle "install --deployment", :artifice => "compact_index_api" should_be_installed("rails 2.3.2") end @@ -108,8 +108,8 @@ describe "compact index api" do gem 'foo', :git => "file:///#{lib_path("foo-1.0")}" G - bundle "install", :artifice => "compact_index" - bundle "install --deployment", :artifice => "compact_index" + bundle "install", :artifice => "compact_index_api" + bundle "install --deployment", :artifice => "compact_index_api" expect(exitstatus).to eq(0) if exitstatus should_be_installed("foo 1.0") @@ -123,7 +123,7 @@ describe "compact index api" do gem "rcov" G - bundle! :install, :fakeweb => "windows" + bundle! :install, :artifice => "windows" expect(out).to include("Fetching source index from #{source_uri}") should_be_installed "rcov 1.0.0" end @@ -161,7 +161,7 @@ The checksum of /versions does not match the checksum provided by the server! So gem "rack" G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" expect(out).to include("Fetching gem metadata from #{source_uri}") should_be_installed "rack 1.0.0" end @@ -195,7 +195,7 @@ The checksum of /versions does not match the checksum provided by the server! So H end - bundle! :install, :artifice => "compact_index_host_redirect", :requires => [lib_path("disable_net_http_persistent.rb")] + bundle! :install, :artifice => "compact_index_host_redirect", :requires => [lib_path("disable_net_http_persistent.rb")], :in_process_exec => false expect(out).to_not match(/Too many redirects/) should_be_installed "rack 1.0.0" end @@ -217,7 +217,7 @@ The checksum of /versions does not match the checksum provided by the server! So gem "rack" G - bundle "install --full-index", :artifice => "compact_index" + bundle "install --full-index", :artifice => "compact_index_api" expect(out).to include("Fetching source index from #{source_uri}") should_be_installed "rack 1.0.0" end @@ -228,7 +228,7 @@ The checksum of /versions does not match the checksum provided by the server! So gem "rack" G - bundle "update --full-index", :artifice => "compact_index" + bundle "update --full-index", :artifice => "compact_index_api" expect(out).to include("Fetching source index from #{source_uri}") should_be_installed "rack 1.0.0" end @@ -266,6 +266,8 @@ The checksum of /versions does not match the checksum provided by the server! So end end + run! "true" + gemfile <<-G source "#{source_uri}" do; end source "#{source_uri}/extra" @@ -381,7 +383,7 @@ The checksum of /versions does not match the checksum provided by the server! So gem "bundler_dep" G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" expect(out).to include("Fetching gem metadata from #{source_uri}") end @@ -393,7 +395,7 @@ The checksum of /versions does not match the checksum provided by the server! So source "#{source_uri}" gem "rails" G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" should_be_installed "rails 2.3.2" end @@ -403,7 +405,7 @@ The checksum of /versions does not match the checksum provided by the server! So gem "rack" G - bundle "install --binstubs", :artifice => "compact_index" + bundle "install --binstubs", :artifice => "compact_index_api" gembin "rackup" expect(out).to eq("1.0.0") @@ -415,7 +417,7 @@ The checksum of /versions does not match the checksum provided by the server! So gem "rack" G - bundle "install --path vendor/bundle", :artifice => "compact_index" + bundle "install --path vendor/bundle", :artifice => "compact_index_api" expect(vendored_gems("bin/rackup")).to exist end @@ -426,7 +428,7 @@ The checksum of /versions does not match the checksum provided by the server! So gem "rack" G - bundle "install --path vendor/bundle --no-clean", :artifice => "compact_index" + bundle "install --path vendor/bundle --no-clean", :artifice => "compact_index_api" expect(vendored_gems("bin/rackup")).to exist end @@ -437,7 +439,7 @@ The checksum of /versions does not match the checksum provided by the server! So gem 'rack-obama' G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" expect(out).to include("Post-install message from rack:") end @@ -447,7 +449,7 @@ The checksum of /versions does not match the checksum provided by the server! So gem 'rack_middleware' G - bundle! :install, :artifice => "compact_index" + bundle! :install, :artifice => "compact_index_api" expect(out).to include("Post-install message from rack:") expect(out).to include("Rack's post install message") end @@ -664,7 +666,7 @@ The checksum of /versions does not match the checksum provided by the server! So G # Create an empty file to trigger a partial download - versions = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index", + versions = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index_api", "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions") FileUtils.mkdir_p(File.dirname(versions)) FileUtils.touch(versions) diff --git a/spec/install/gems/dependency_api_spec.rb b/spec/install/gems/dependency_api_spec.rb index 70190dd01b..28ac75261a 100644 --- a/spec/install/gems/dependency_api_spec.rb +++ b/spec/install/gems/dependency_api_spec.rb @@ -123,7 +123,7 @@ describe "gemcutter's dependency API" do gem "rcov" G - bundle :install, :fakeweb => "windows" + bundle :install, :artifice => "windows" expect(out).to include("Fetching source index from #{source_uri}") should_be_installed "rcov 1.0.0" end @@ -204,7 +204,7 @@ describe "gemcutter's dependency API" do H end - bundle :install, :artifice => "endpoint_host_redirect", :requires => [lib_path("disable_net_http_persistent.rb")] + bundle :install, :artifice => "endpoint_host_redirect", :requires => [lib_path("disable_net_http_persistent.rb")], :in_process_exec => false expect(out).to_not match(/Too many redirects/) should_be_installed "rack 1.0.0" end diff --git a/spec/install/gems/resolving_spec.rb b/spec/install/gems/resolving_spec.rb index a3ff7394d5..1c6e88c306 100644 --- a/spec/install/gems/resolving_spec.rb +++ b/spec/install/gems/resolving_spec.rb @@ -111,7 +111,7 @@ describe "bundle install with install-time dependencies" do end end - install_gemfile <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2 } + install_gemfile <<-G, :artifice => "compact_index_api", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2 } ruby "#{RUBY_VERSION}" source "http://localgemserver.test/" gem 'rack' diff --git a/spec/other/trampoline_spec.rb b/spec/other/trampoline_spec.rb index 2be0c9c3e9..69bfa9eae1 100644 --- a/spec/other/trampoline_spec.rb +++ b/spec/other/trampoline_spec.rb @@ -11,11 +11,11 @@ describe "bundler version trampolining" do context "version guessing" do shared_examples_for "guesses" do |version| it "guesses the correct bundler version" do - bundle! "--version" + bundle! "--version", :in_process_exec => false expect(out).to eq("Bundler version #{version}") if bundled_app("Gemfile").file? - bundle! "exec ruby -e 'puts Bundler::VERSION'" + bundle! "exec ruby -e 'puts Bundler::VERSION'", :in_process_exec => false expect(out).to eq(version) end end @@ -74,14 +74,14 @@ describe "bundler version trampolining" do it "guesses & installs the correct bundler version" do expect(system_gem_path.join("gems", "bundler-1.12.3")).not_to exist - bundle! "--version" + bundle! "--version", :in_process_exec => false expect(out).to eq("Bundler version 1.12.3") expect(system_gem_path.join("gems", "bundler-1.12.3")).to exist end it "fails gracefully when installing the bundler fails" do ENV["BUNDLER_VERSION"] = "9999" - bundle "--version", :expect_err => true + bundle "--version", :expect_err => true, :in_process_exec => false expect(err).to start_with(<<-E.strip) Installing the inferred bundler version (= 9999) failed. If you'd like to update to the current bundler version (#{Bundler::VERSION}) in this project, run `bundle update --bundler`. @@ -99,21 +99,21 @@ The error was: it "updates to the specified version" do # HACK: since no released bundler version actually supports this feature! - bundle "update --bundler=1.12.0", :expect_err => true + bundle "update --bundler=1.12.0", :expect_err => true, :in_process_exec => false expect(out).to include("Unknown switches '--bundler=1.12.0'") end it "updates to the specified (running) version" do # HACK: since no released bundler version actually supports this feature! - bundle! "update --bundler=#{Bundler::VERSION}" - bundle! "--version" + bundle! "update --bundler=#{Bundler::VERSION}", :in_process_exec => false + bundle! "--version", :in_process_exec => false expect(out).to eq("Bundler version #{Bundler::VERSION}") end it "updates to the running version" do # HACK: since no released bundler version actually supports this feature! - bundle! "update --bundler" - bundle! "--version" + bundle! "update --bundler", :in_process_exec => false + bundle! "--version", :in_process_exec => false expect(out).to eq("Bundler version #{Bundler::VERSION}") end end @@ -126,7 +126,7 @@ The error was: end it "uses the locked version" do - ruby! <<-R + ruby! <<-R, :in_process_exec => false require "bundler/setup" puts Bundler::VERSION R diff --git a/spec/runtime/inline_spec.rb b/spec/runtime/inline_spec.rb index ccc2aed8be..19f4f7c212 100644 --- a/spec/runtime/inline_spec.rb +++ b/spec/runtime/inline_spec.rb @@ -3,10 +3,8 @@ require "spec_helper" describe "bundler/inline#gemfile" do def script(code, options = {}) - requires = ["bundler/inline"] - requires.unshift File.expand_path("../../support/artifice/" + options.delete(:artifice) + ".rb", __FILE__) if options.key?(:artifice) - requires = requires.map {|r| "require '#{r}'" }.join("\n") - @out = ruby("#{requires}\n\n" + code, options) + code = "require 'bundler/inline'\n\n" + strip_whitespace(code) + @out = ruby(code, options) end before :each do @@ -85,7 +83,7 @@ describe "bundler/inline#gemfile" do script <<-RUBY, :artifice => "endpoint" gemfile(true) do - source "https://rubygems.org" + source "http://localgemserver.test" gem "activesupport", :require => true end RUBY @@ -104,7 +102,7 @@ describe "bundler/inline#gemfile" do end end gemfile(true, :ui => MyBundlerUI.new) do - source "https://rubygems.org" + source "http://localgemserver.test" gem "activesupport", :require => true end RUBY @@ -151,8 +149,8 @@ describe "bundler/inline#gemfile" do puts RACK RUBY - expect(out).to eq("1.0.0") expect(err).to be_empty + expect(out).to eq("1.0.0") expect(exitstatus).to be_zero if exitstatus end diff --git a/spec/runtime/setup_spec.rb b/spec/runtime/setup_spec.rb index 18abf0549e..d8dcd49ecd 100644 --- a/spec/runtime/setup_spec.rb +++ b/spec/runtime/setup_spec.rb @@ -118,7 +118,7 @@ describe "Bundler.setup" do ENV["RUBYOPT"] = "-Idash_i_dir" ENV["RUBYLIB"] = "rubylib_dir" - ruby <<-RUBY + ruby <<-RUBY, :in_process_exec => false require 'rubygems' require 'bundler' Bundler.setup @@ -140,7 +140,7 @@ describe "Bundler.setup" do gem "rails" G - ruby <<-RUBY + ruby <<-RUBY, :in_process_exec => false require 'rubygems' require 'bundler' Bundler.setup @@ -714,7 +714,7 @@ describe "Bundler.setup" do source "file://#{gem_repo1}" G - ruby <<-R + ruby <<-R, :in_process_exec => false if Gem::Specification.method_defined? :extension_dir s = Gem::Specification.find_by_name '#{gem_name}' s.extension_dir = '#{ext_dir}' @@ -935,7 +935,7 @@ describe "Bundler.setup" do it "evals each gemspec with a binding from the top level" do bundle "install" - ruby <<-RUBY + ruby <<-RUBY, :in_process_exec => false require 'bundler' def Bundler.require(path) raise "LOSE" @@ -1080,7 +1080,7 @@ describe "Bundler.setup" do describe "when Psych is not in the Gemfile", :ruby => "~> 2.2" do it "does not load Psych" do gemfile "" - ruby <<-RUBY + ruby <<-RUBY, :in_process_exec => false require 'bundler/setup' puts defined?(Psych::VERSION) ? Psych::VERSION : "undefined" require 'psych' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d780a3f27b..33fb39196d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -31,7 +31,7 @@ else end Dir["#{File.expand_path("../support", __FILE__)}/*.rb"].each do |file| - require file unless file =~ %r{fakeweb/.*\.rb} + require file unless file =~ /hax.rb$/ end $debug = false @@ -104,7 +104,10 @@ RSpec.configure do |config| end config.after :each do |example| - puts @out if defined?(@out) && example.exception + if example.exception + puts @out if defined?(@out) && !@out.empty? + puts @err if defined?(@err) && !@err.empty? + end Dir.chdir(original_wd) ENV.replace(original_env) diff --git a/spec/support/artifice/compact_index.rb b/spec/support/artifice/compact_index.rb deleted file mode 100644 index 233c192a67..0000000000 --- a/spec/support/artifice/compact_index.rb +++ /dev/null @@ -1,114 +0,0 @@ -# frozen_string_literal: true -require File.expand_path("../endpoint", __FILE__) - -$LOAD_PATH.unshift Dir[base_system_gems.join("gems/compact_index*/lib")].first.to_s -require "compact_index" - -class CompactIndexAPI < Endpoint - helpers do - def load_spec(name, version, platform, gem_repo) - full_name = "#{name}-#{version}" - full_name += "-#{platform}" if platform != "ruby" - Marshal.load(Gem.inflate(File.open(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz")).read)) - end - - def etag_response - response_body = yield - checksum = Digest::MD5.hexdigest(response_body) - return if not_modified?(checksum) - headers "ETag" => quote(checksum) - headers "Surrogate-Control" => "max-age=2592000, stale-while-revalidate=60" - content_type "text/plain" - requested_range_for(response_body) - rescue => e - puts e - puts e.backtrace - raise - end - - def not_modified?(checksum) - etags = parse_etags(request.env["HTTP_IF_NONE_MATCH"]) - - return unless etags.include?(checksum) - headers "ETag" => quote(checksum) - status 304 - body "" - end - - def requested_range_for(response_body) - ranges = Rack::Utils.byte_ranges(env, response_body.bytesize) - - if ranges - status 206 - body ranges.map! {|range| slice_body(response_body, range) }.join - else - status 200 - body response_body - end - end - - def quote(string) - %("#{string}") - end - - def parse_etags(value) - value ? value.split(/, ?/).select {|s| s.sub!(/"(.*)"/, '\1') } : [] - end - - def slice_body(body, range) - if body.respond_to?(:byteslice) - body.byteslice(range) - else # pre-1.9.3 - body.unpack("@#{range.first}a#{range.end + 1}").first - end - end - - def gems(gem_repo = GEM_REPO) - @gems ||= {} - @gems[gem_repo] ||= begin - specs = Bundler::Deprecate.skip_during do - Marshal.load(File.open(gem_repo.join("specs.4.8")).read).map do |name, version, platform| - load_spec(name, version, platform, gem_repo) - end - end - - specs.group_by(&:name).map do |name, versions| - gem_versions = versions.map do |spec| - deps = spec.dependencies.select {|d| d.type == :runtime }.map do |d| - reqs = d.requirement.requirements.map {|r| r.join(" ") }.join(", ") - CompactIndex::Dependency.new(d.name, reqs) - end - CompactIndex::GemVersion.new(spec.version.version, spec.platform.to_s, nil, nil, - deps, spec.required_ruby_version, spec.required_rubygems_version) - end - CompactIndex::Gem.new(name, gem_versions) - end - end - end - end - - get "/names" do - etag_response do - CompactIndex.names(gems.map(&:name)) - end - end - - get "/versions" do - etag_response do - file = tmp("versions.list") - file.delete if file.file? - file = CompactIndex::VersionsFile.new(file.to_s) - file.update_with(gems) - CompactIndex.versions(file, nil, {}) - end - end - - get "/info/:name" do - etag_response do - gem = gems.find {|g| g.name == params[:name] } - CompactIndex.info(gem ? gem.versions : []) - end - end -end - -Artifice.activate_with(CompactIndexAPI) diff --git a/spec/support/artifice/compact_index_api.rb b/spec/support/artifice/compact_index_api.rb new file mode 100644 index 0000000000..124f3beec1 --- /dev/null +++ b/spec/support/artifice/compact_index_api.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: true +require File.expand_path("../endpoint", __FILE__) + +$LOAD_PATH.unshift Dir[base_system_gems.join("gems/compact_index*/lib")].first.to_s +require "compact_index" + +class Artifice::CompactIndexAPI < Artifice::Endpoint + helpers do + def load_spec(name, version, platform, gem_repo) + full_name = "#{name}-#{version}" + full_name += "-#{platform}" if platform != "ruby" + Marshal.load(Gem.inflate(File.open(gem_repo.join("quick/Marshal.4.8/#{full_name}.gemspec.rz")).read)) + end + + def etag_response + response_body = yield + checksum = Digest::MD5.hexdigest(response_body) + return if not_modified?(checksum) + headers "ETag" => quote(checksum) + headers "Surrogate-Control" => "max-age=2592000, stale-while-revalidate=60" + content_type "text/plain" + requested_range_for(response_body) + rescue => e + puts e + puts e.backtrace + raise + end + + def not_modified?(checksum) + etags = parse_etags(request.env["HTTP_IF_NONE_MATCH"]) + + return unless etags.include?(checksum) + headers "ETag" => quote(checksum) + status 304 + body "" + end + + def requested_range_for(response_body) + ranges = Rack::Utils.byte_ranges(env, response_body.bytesize) + + if ranges + status 206 + body ranges.map! {|range| slice_body(response_body, range) }.join + else + status 200 + body response_body + end + end + + def quote(string) + %("#{string}") + end + + def parse_etags(value) + value ? value.split(/, ?/).select {|s| s.sub!(/"(.*)"/, '\1') } : [] + end + + def slice_body(body, range) + if body.respond_to?(:byteslice) + body.byteslice(range) + else # pre-1.9.3 + body.unpack("@#{range.first}a#{range.end + 1}").first + end + end + + def gems(gem_repo = self.gem_repo) + @gems ||= {} + @gems[gem_repo] ||= begin + specs = Bundler::Deprecate.skip_during do + Marshal.load(File.open(gem_repo.join("specs.4.8")).read).map do |name, version, platform| + load_spec(name, version, platform, gem_repo) + end + end + + specs.group_by(&:name).map do |name, versions| + gem_versions = versions.map do |spec| + deps = spec.dependencies.select {|d| d.type == :runtime }.map do |d| + reqs = d.requirement.requirements.map {|r| r.join(" ") }.join(", ") + CompactIndex::Dependency.new(d.name, reqs) + end + CompactIndex::GemVersion.new(spec.version.version, spec.platform.to_s, nil, nil, + deps, spec.required_ruby_version, spec.required_rubygems_version) + end + CompactIndex::Gem.new(name, gem_versions) + end + end + end + end + + get "/names" do + etag_response do + CompactIndex.names(gems.map(&:name)) + end + end + + get "/versions" do + etag_response do + file = tmp("versions.list") + file.delete if file.file? + file = CompactIndex::VersionsFile.new(file.to_s) + file.update_with(gems) + CompactIndex.versions(file, nil, {}) + end + end + + get "/info/:name" do + etag_response do + gem = gems.find {|g| g.name == params[:name] } + CompactIndex.info(gem ? gem.versions : []) + end + end +end + +Artifice.activate_with(Artifice::CompactIndexAPI) diff --git a/spec/support/artifice/compact_index_api_missing.rb b/spec/support/artifice/compact_index_api_missing.rb index 6d15b54b85..0bc157c64d 100644 --- a/spec/support/artifice/compact_index_api_missing.rb +++ b/spec/support/artifice/compact_index_api_missing.rb @@ -1,11 +1,10 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexApiMissing < CompactIndexAPI +class Artifice::CompactIndexAPIMissing < Artifice::CompactIndexAPI get "/fetch/actual/gem/:id" do - $stderr.puts params[:id] if params[:id] == "rack-1.0.gemspec.rz" halt 404 else @@ -14,4 +13,4 @@ class CompactIndexApiMissing < CompactIndexAPI end end -Artifice.activate_with(CompactIndexApiMissing) +Artifice.activate_with(Artifice::CompactIndexAPIMissing) diff --git a/spec/support/artifice/compact_index_basic_authentication.rb b/spec/support/artifice/compact_index_basic_authentication.rb index bffb5b9e2b..42522b4c55 100644 --- a/spec/support/artifice/compact_index_basic_authentication.rb +++ b/spec/support/artifice/compact_index_basic_authentication.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexBasicAuthentication < CompactIndexAPI +class Artifice::CompactIndexBasicAuthentication < Artifice::CompactIndexAPI before do unless env["HTTP_AUTHORIZATION"] halt 401, "Authentication info not supplied" @@ -11,4 +11,4 @@ class CompactIndexBasicAuthentication < CompactIndexAPI end end -Artifice.activate_with(CompactIndexBasicAuthentication) +Artifice.activate_with(Artifice::CompactIndexBasicAuthentication) diff --git a/spec/support/artifice/compact_index_checksum_mismatch.rb b/spec/support/artifice/compact_index_checksum_mismatch.rb index 4ac328736c..38bc64b1c5 100644 --- a/spec/support/artifice/compact_index_checksum_mismatch.rb +++ b/spec/support/artifice/compact_index_checksum_mismatch.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexChecksumMismatch < CompactIndexAPI +class Artifice::CompactIndexChecksumMismatch < Artifice::CompactIndexAPI get "/versions" do headers "ETag" => quote("123") headers "Surrogate-Control" => "max-age=2592000, stale-while-revalidate=60" @@ -12,4 +12,4 @@ class CompactIndexChecksumMismatch < CompactIndexAPI end end -Artifice.activate_with(CompactIndexChecksumMismatch) +Artifice.activate_with(Artifice::CompactIndexChecksumMismatch) diff --git a/spec/support/artifice/compact_index_concurrent_download.rb b/spec/support/artifice/compact_index_concurrent_download.rb index 30a2171a30..d69c082a55 100644 --- a/spec/support/artifice/compact_index_concurrent_download.rb +++ b/spec/support/artifice/compact_index_concurrent_download.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexConcurrentDownload < CompactIndexAPI +class Artifice::CompactIndexConcurrentDownload < Artifice::CompactIndexAPI get "/versions" do versions = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index", "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "versions") @@ -28,4 +28,4 @@ class CompactIndexConcurrentDownload < CompactIndexAPI end end -Artifice.activate_with(CompactIndexConcurrentDownload) +Artifice.activate_with(Artifice::CompactIndexConcurrentDownload) diff --git a/spec/support/artifice/compact_index_creds_diff_host.rb b/spec/support/artifice/compact_index_creds_diff_host.rb index 0c417f0580..feec83d337 100644 --- a/spec/support/artifice/compact_index_creds_diff_host.rb +++ b/spec/support/artifice/compact_index_creds_diff_host.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexCredsDiffHost < CompactIndexAPI +class Artifice::CompactIndexCredsDiffHost < Artifice::CompactIndexAPI helpers do def auth @auth ||= Rack::Auth::Basic::Request.new(request.env) @@ -35,4 +35,4 @@ class CompactIndexCredsDiffHost < CompactIndexAPI end end -Artifice.activate_with(CompactIndexCredsDiffHost) +Artifice.activate_with(Artifice::CompactIndexCredsDiffHost) diff --git a/spec/support/artifice/compact_index_extra.rb b/spec/support/artifice/compact_index_extra.rb index 8a87fc4343..610353c4c7 100644 --- a/spec/support/artifice/compact_index_extra.rb +++ b/spec/support/artifice/compact_index_extra.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexExtra < CompactIndexAPI +class Artifice::CompactIndexExtra < Artifice::CompactIndexAPI get "/extra/versions" do halt 404 end @@ -33,4 +33,4 @@ class CompactIndexExtra < CompactIndexAPI end end -Artifice.activate_with(CompactIndexExtra) +Artifice.activate_with(Artifice::CompactIndexExtra) diff --git a/spec/support/artifice/compact_index_extra_api.rb b/spec/support/artifice/compact_index_extra_api.rb index 063e5589d4..532866623c 100644 --- a/spec/support/artifice/compact_index_extra_api.rb +++ b/spec/support/artifice/compact_index_extra_api.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexExtraApi < CompactIndexAPI +class Artifice::CompactIndexExtraAPI < Artifice::CompactIndexAPI get "/extra/names" do etag_response do CompactIndex.names(gems(gem_repo4).map(&:name)) @@ -48,4 +48,4 @@ class CompactIndexExtraApi < CompactIndexAPI end end -Artifice.activate_with(CompactIndexExtraApi) +Artifice.activate_with(Artifice::CompactIndexExtraAPI) diff --git a/spec/support/artifice/compact_index_extra_missing.rb b/spec/support/artifice/compact_index_extra_missing.rb index 2af5ce9c27..1abd8a19ae 100644 --- a/spec/support/artifice/compact_index_extra_missing.rb +++ b/spec/support/artifice/compact_index_extra_missing.rb @@ -3,7 +3,7 @@ require File.expand_path("../compact_index_extra", __FILE__) Artifice.deactivate -class CompactIndexExtraMissing < CompactIndexExtra +class Artifice::CompactIndexExtraMissing < Artifice::CompactIndexExtra get "/extra/fetch/actual/gem/:id" do if params[:id] == "missing-1.0.gemspec.rz" halt 404 @@ -13,4 +13,4 @@ class CompactIndexExtraMissing < CompactIndexExtra end end -Artifice.activate_with(CompactIndexExtraMissing) +Artifice.activate_with(Artifice::CompactIndexExtraMissing) diff --git a/spec/support/artifice/compact_index_forbidden.rb b/spec/support/artifice/compact_index_forbidden.rb index b25eea94e7..f27b28f992 100644 --- a/spec/support/artifice/compact_index_forbidden.rb +++ b/spec/support/artifice/compact_index_forbidden.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexForbidden < CompactIndexAPI +class Artifice::CompactIndexForbidden < Artifice::CompactIndexAPI get "/versions" do halt 403 end end -Artifice.activate_with(CompactIndexForbidden) +Artifice.activate_with(Artifice::CompactIndexForbidden) diff --git a/spec/support/artifice/compact_index_host_redirect.rb b/spec/support/artifice/compact_index_host_redirect.rb index 6c1ab2def6..61ac17ae32 100644 --- a/spec/support/artifice/compact_index_host_redirect.rb +++ b/spec/support/artifice/compact_index_host_redirect.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexHostRedirect < CompactIndexAPI +class Artifice::CompactIndexHostRedirect < Artifice::CompactIndexAPI get "/fetch/actual/gem/:id", :host_name => "localgemserver.test" do redirect "http://bundler.localgemserver.test#{request.path_info}" end @@ -17,4 +17,4 @@ class CompactIndexHostRedirect < CompactIndexAPI end end -Artifice.activate_with(CompactIndexHostRedirect) +Artifice.activate_with(Artifice::CompactIndexHostRedirect) diff --git a/spec/support/artifice/compact_index_redirects.rb b/spec/support/artifice/compact_index_redirects.rb index ff1d3e43bc..3346166914 100644 --- a/spec/support/artifice/compact_index_redirects.rb +++ b/spec/support/artifice/compact_index_redirects.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexRedirect < CompactIndexAPI +class Artifice::CompactIndexRedirects < Artifice::CompactIndexAPI get "/fetch/actual/gem/:id" do redirect "/fetch/actual/gem/#{params[:id]}" end @@ -17,4 +17,4 @@ class CompactIndexRedirect < CompactIndexAPI end end -Artifice.activate_with(CompactIndexRedirect) +Artifice.activate_with(Artifice::CompactIndexRedirects) diff --git a/spec/support/artifice/compact_index_strict_basic_authentication.rb b/spec/support/artifice/compact_index_strict_basic_authentication.rb index 49a072d2b9..fa209deba2 100644 --- a/spec/support/artifice/compact_index_strict_basic_authentication.rb +++ b/spec/support/artifice/compact_index_strict_basic_authentication.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true -require File.expand_path("../compact_index", __FILE__) +require File.expand_path("../compact_index_api", __FILE__) Artifice.deactivate -class CompactIndexStrictBasicAuthentication < CompactIndexAPI +class Artifice::CompactIndexStrictBasicAuthentication < Artifice::CompactIndexAPI before do unless env["HTTP_AUTHORIZATION"] halt 401, "Authentication info not supplied" @@ -16,4 +16,4 @@ class CompactIndexStrictBasicAuthentication < CompactIndexAPI end end -Artifice.activate_with(CompactIndexStrictBasicAuthentication) +Artifice.activate_with(Artifice::CompactIndexStrictBasicAuthentication) diff --git a/spec/support/artifice/endopint_marshal_fail_basic_authentication.rb b/spec/support/artifice/endopint_marshal_fail_basic_authentication.rb index f1f8dc5700..2ec1dbed80 100644 --- a/spec/support/artifice/endopint_marshal_fail_basic_authentication.rb +++ b/spec/support/artifice/endopint_marshal_fail_basic_authentication.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint_marshal_fail", __FILE__) Artifice.deactivate -class EndpointMarshalFailBasicAuthentication < EndpointMarshalFail +class Artifice::EndpointMarshalFailBasicAuthentication < Artifice::EndpointMarshalFail before do unless env["HTTP_AUTHORIZATION"] halt 401, "Authentication info not supplied" @@ -11,4 +11,4 @@ class EndpointMarshalFailBasicAuthentication < EndpointMarshalFail end end -Artifice.activate_with(EndpointMarshalFailBasicAuthentication) +Artifice.activate_with(Artifice::EndpointMarshalFailBasicAuthentication) diff --git a/spec/support/artifice/endpoint.rb b/spec/support/artifice/endpoint.rb index 2955889a86..566a5fdffe 100644 --- a/spec/support/artifice/endpoint.rb +++ b/spec/support/artifice/endpoint.rb @@ -3,22 +3,23 @@ require File.expand_path("../../path.rb", __FILE__) require File.expand_path("../../../../lib/bundler/deprecate", __FILE__) include Spec::Path -# Set up pretend http gem server with FakeWeb $LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/artifice*/lib")].first}" -$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/rack-*/lib")].first}" -$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/rack-*/lib")].last}" +$LOAD_PATH.unshift(*Dir[base_system_gems.join("gems/rack-*/lib")]) $LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/tilt*/lib")].first}" $LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/sinatra*/lib")].first}" require "artifice" require "sinatra/base" -class Endpoint < Sinatra::Base - GEM_REPO = Pathname.new(ENV["BUNDLER_SPEC_GEM_REPO"] || Spec::Path.gem_repo1) +class Artifice::Endpoint < Sinatra::Base set :raise_errors, true set :show_exceptions, false helpers do - def dependencies_for(gem_names, gem_repo = GEM_REPO) + def gem_repo + Pathname.new(ENV["BUNDLER_SPEC_GEM_REPO"] || Spec::Path.gem_repo1) + end + + def dependencies_for(gem_names) return [] if gem_names.nil? || gem_names.empty? require "rubygems" @@ -51,11 +52,11 @@ class Endpoint < Sinatra::Base end get "/fetch/actual/gem/:id" do - File.read("#{GEM_REPO}/quick/Marshal.4.8/#{params[:id]}") + File.read("#{gem_repo}/quick/Marshal.4.8/#{params[:id]}") end get "/gems/:id" do - File.read("#{GEM_REPO}/gems/#{params[:id]}") + File.read("#{gem_repo}/gems/#{params[:id]}") end get "/api/v1/dependencies" do @@ -63,12 +64,12 @@ class Endpoint < Sinatra::Base end get "/specs.4.8.gz" do - File.read("#{GEM_REPO}/specs.4.8.gz") + File.read("#{gem_repo}/specs.4.8.gz") end get "/prerelease_specs.4.8.gz" do - File.read("#{GEM_REPO}/prerelease_specs.4.8.gz") + File.read("#{gem_repo}/prerelease_specs.4.8.gz") end end -Artifice.activate_with(Endpoint) +Artifice.activate_with(Artifice::Endpoint) diff --git a/spec/support/artifice/endpoint_500.rb b/spec/support/artifice/endpoint_500.rb index 9bbbd1e2f2..75ea58c5e6 100644 --- a/spec/support/artifice/endpoint_500.rb +++ b/spec/support/artifice/endpoint_500.rb @@ -3,8 +3,7 @@ require File.expand_path("../../path.rb", __FILE__) include Spec::Path $LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/artifice*/lib")].first}" -$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/rack-*/lib")].first}" -$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/rack-*/lib")].last}" +$LOAD_PATH.unshift(Dir[base_system_gems.join("gems/rack-*/lib")]) $LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/tilt*/lib")].first}" $LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/sinatra*/lib")].first}" @@ -13,10 +12,10 @@ require "sinatra/base" Artifice.deactivate -class Endpoint500 < Sinatra::Base +class Artifice::Endpoint500 < Sinatra::Base before do halt 500 end end -Artifice.activate_with(Endpoint500) +Artifice.activate_with(Artifice::Endpoint500) diff --git a/spec/support/artifice/endpoint_api_forbidden.rb b/spec/support/artifice/endpoint_api_forbidden.rb index 21ad9117ed..0ef7284c36 100644 --- a/spec/support/artifice/endpoint_api_forbidden.rb +++ b/spec/support/artifice/endpoint_api_forbidden.rb @@ -3,10 +3,10 @@ require File.expand_path("../endpoint", __FILE__) Artifice.deactivate -class EndpointApiForbidden < Endpoint +class Artifice::EndpointApiForbidden < Artifice::Endpoint get "/api/v1/dependencies" do halt 403 end end -Artifice.activate_with(EndpointApiForbidden) +Artifice.activate_with(Artifice::EndpointApiForbidden) diff --git a/spec/support/artifice/endpoint_api_missing.rb b/spec/support/artifice/endpoint_api_missing.rb index 6f5b5f1323..254d8cfda7 100644 --- a/spec/support/artifice/endpoint_api_missing.rb +++ b/spec/support/artifice/endpoint_api_missing.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint", __FILE__) Artifice.deactivate -class EndpointApiMissing < Endpoint +class Artifice::EndpointApiMissing < Artifice::Endpoint get "/fetch/actual/gem/:id" do $stderr.puts params[:id] if params[:id] == "rack-1.0.gemspec.rz" @@ -14,4 +14,4 @@ class EndpointApiMissing < Endpoint end end -Artifice.activate_with(EndpointApiMissing) +Artifice.activate_with(Artifice::EndpointApiMissing) diff --git a/spec/support/artifice/endpoint_basic_authentication.rb b/spec/support/artifice/endpoint_basic_authentication.rb index 9fafd51a3d..042fa56de1 100644 --- a/spec/support/artifice/endpoint_basic_authentication.rb +++ b/spec/support/artifice/endpoint_basic_authentication.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint", __FILE__) Artifice.deactivate -class EndpointBasicAuthentication < Endpoint +class Artifice::EndpointBasicAuthentication < Artifice::Endpoint before do unless env["HTTP_AUTHORIZATION"] halt 401, "Authentication info not supplied" @@ -11,4 +11,4 @@ class EndpointBasicAuthentication < Endpoint end end -Artifice.activate_with(EndpointBasicAuthentication) +Artifice.activate_with(Artifice::EndpointBasicAuthentication) diff --git a/spec/support/artifice/endpoint_creds_diff_host.rb b/spec/support/artifice/endpoint_creds_diff_host.rb index cd152848fe..b7bb63479b 100644 --- a/spec/support/artifice/endpoint_creds_diff_host.rb +++ b/spec/support/artifice/endpoint_creds_diff_host.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint", __FILE__) Artifice.deactivate -class EndpointCredsDiffHost < Endpoint +class Artifice::EndpointCredsDiffHost < Artifice::Endpoint helpers do def auth @auth ||= Rack::Auth::Basic::Request.new(request.env) @@ -35,4 +35,4 @@ class EndpointCredsDiffHost < Endpoint end end -Artifice.activate_with(EndpointCredsDiffHost) +Artifice.activate_with(Artifice::EndpointCredsDiffHost) diff --git a/spec/support/artifice/endpoint_extra.rb b/spec/support/artifice/endpoint_extra.rb index ed4e87e65f..627b5bfd29 100644 --- a/spec/support/artifice/endpoint_extra.rb +++ b/spec/support/artifice/endpoint_extra.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint", __FILE__) Artifice.deactivate -class EndpointExtra < Endpoint +class Artifice::EndpointExtra < Artifice::Endpoint get "/extra/api/v1/dependencies" do halt 404 end @@ -29,4 +29,4 @@ class EndpointExtra < Endpoint end end -Artifice.activate_with(EndpointExtra) +Artifice.activate_with(Artifice::EndpointExtra) diff --git a/spec/support/artifice/endpoint_extra_api.rb b/spec/support/artifice/endpoint_extra_api.rb index 1e9e1dc60d..88fc004e5d 100644 --- a/spec/support/artifice/endpoint_extra_api.rb +++ b/spec/support/artifice/endpoint_extra_api.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint", __FILE__) Artifice.deactivate -class EndpointExtraApi < Endpoint +class Artifice::EndpointExtraApi < Artifice::Endpoint get "/extra/api/v1/dependencies" do deps = dependencies_for(params[:gems], gem_repo4) Marshal.dump(deps) @@ -30,4 +30,4 @@ class EndpointExtraApi < Endpoint end end -Artifice.activate_with(EndpointExtraApi) +Artifice.activate_with(Artifice::EndpointExtraApi) diff --git a/spec/support/artifice/endpoint_extra_missing.rb b/spec/support/artifice/endpoint_extra_missing.rb index dc79705a26..3898aa9d70 100644 --- a/spec/support/artifice/endpoint_extra_missing.rb +++ b/spec/support/artifice/endpoint_extra_missing.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint_extra", __FILE__) Artifice.deactivate -class EndpointExtraMissing < EndpointExtra +class Artifice::EndpointExtraMissing < Artifice::EndpointExtra get "/extra/fetch/actual/gem/:id" do if params[:id] == "missing-1.0.gemspec.rz" halt 404 @@ -13,4 +13,4 @@ class EndpointExtraMissing < EndpointExtra end end -Artifice.activate_with(EndpointExtraMissing) +Artifice.activate_with(Artifice::EndpointExtraMissing) diff --git a/spec/support/artifice/endpoint_fallback.rb b/spec/support/artifice/endpoint_fallback.rb index 8a85a41784..5612aba469 100644 --- a/spec/support/artifice/endpoint_fallback.rb +++ b/spec/support/artifice/endpoint_fallback.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint", __FILE__) Artifice.deactivate -class EndpointFallback < Endpoint +class Artifice::EndpointFallback < Artifice::Endpoint DEPENDENCY_LIMIT = 60 get "/api/v1/dependencies" do @@ -15,4 +15,4 @@ class EndpointFallback < Endpoint end end -Artifice.activate_with(EndpointFallback) +Artifice.activate_with(Artifice::EndpointFallback) diff --git a/spec/support/artifice/endpoint_host_redirect.rb b/spec/support/artifice/endpoint_host_redirect.rb index 250416d8cc..30ab27e49d 100644 --- a/spec/support/artifice/endpoint_host_redirect.rb +++ b/spec/support/artifice/endpoint_host_redirect.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint", __FILE__) Artifice.deactivate -class EndpointHostRedirect < Endpoint +class Artifice::EndpointHostRedirect < Artifice::Endpoint get "/fetch/actual/gem/:id", :host_name => "localgemserver.test" do redirect "http://bundler.localgemserver.test#{request.path_info}" end @@ -13,4 +13,4 @@ class EndpointHostRedirect < Endpoint end end -Artifice.activate_with(EndpointHostRedirect) +Artifice.activate_with(Artifice::EndpointHostRedirect) diff --git a/spec/support/artifice/endpoint_marshal_fail.rb b/spec/support/artifice/endpoint_marshal_fail.rb index 0fb75ebf31..1c9a66e406 100644 --- a/spec/support/artifice/endpoint_marshal_fail.rb +++ b/spec/support/artifice/endpoint_marshal_fail.rb @@ -3,10 +3,10 @@ require File.expand_path("../endpoint_fallback", __FILE__) Artifice.deactivate -class EndpointMarshalFail < EndpointFallback +class Artifice::EndpointMarshalFail < Artifice::EndpointFallback get "/api/v1/dependencies" do "f0283y01hasf" end end -Artifice.activate_with(EndpointMarshalFail) +Artifice.activate_with(Artifice::EndpointMarshalFail) diff --git a/spec/support/artifice/endpoint_mirror_source.rb b/spec/support/artifice/endpoint_mirror_source.rb index 9fb58ecb29..005cf02244 100644 --- a/spec/support/artifice/endpoint_mirror_source.rb +++ b/spec/support/artifice/endpoint_mirror_source.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require File.expand_path("../endpoint", __FILE__) -class EndpointMirrorSource < Endpoint +class Artifice::EndpointMirrorSource < Artifice::Endpoint get "/gems/:id" do if request.env["HTTP_X_GEMFILE_SOURCE"] == "https://server.example.org/" File.read("#{gem_repo1}/gems/#{params[:id]}") @@ -11,4 +11,4 @@ class EndpointMirrorSource < Endpoint end end -Artifice.activate_with(EndpointMirrorSource) +Artifice.activate_with(Artifice::EndpointMirrorSource) diff --git a/spec/support/artifice/endpoint_redirect.rb b/spec/support/artifice/endpoint_redirect.rb index f80d7600c2..297d22dae1 100644 --- a/spec/support/artifice/endpoint_redirect.rb +++ b/spec/support/artifice/endpoint_redirect.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint", __FILE__) Artifice.deactivate -class EndpointRedirect < Endpoint +class Artifice::EndpointRedirect < Artifice::Endpoint get "/fetch/actual/gem/:id" do redirect "/fetch/actual/gem/#{params[:id]}" end @@ -13,4 +13,4 @@ class EndpointRedirect < Endpoint end end -Artifice.activate_with(EndpointRedirect) +Artifice.activate_with(Artifice::EndpointRedirect) diff --git a/spec/support/artifice/endpoint_strict_basic_authentication.rb b/spec/support/artifice/endpoint_strict_basic_authentication.rb index 4b32cbbf5b..5263956b22 100644 --- a/spec/support/artifice/endpoint_strict_basic_authentication.rb +++ b/spec/support/artifice/endpoint_strict_basic_authentication.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint", __FILE__) Artifice.deactivate -class EndpointStrictBasicAuthentication < Endpoint +class Artifice::EndpointStrictBasicAuthentication < Artifice::Endpoint before do unless env["HTTP_AUTHORIZATION"] halt 401, "Authentication info not supplied" @@ -16,4 +16,4 @@ class EndpointStrictBasicAuthentication < Endpoint end end -Artifice.activate_with(EndpointStrictBasicAuthentication) +Artifice.activate_with(Artifice::EndpointStrictBasicAuthentication) diff --git a/spec/support/artifice/endpoint_timeout.rb b/spec/support/artifice/endpoint_timeout.rb index b15650f226..4bc6eb9650 100644 --- a/spec/support/artifice/endpoint_timeout.rb +++ b/spec/support/artifice/endpoint_timeout.rb @@ -3,7 +3,7 @@ require File.expand_path("../endpoint_fallback", __FILE__) Artifice.deactivate -class EndpointTimeout < EndpointFallback +class Artifice::EndpointTimeout < Artifice::EndpointFallback SLEEP_TIMEOUT = 15 get "/api/v1/dependencies" do @@ -11,4 +11,4 @@ class EndpointTimeout < EndpointFallback end end -Artifice.activate_with(EndpointTimeout) +Artifice.activate_with(Artifice::EndpointTimeout) diff --git a/spec/support/artifice/windows.rb b/spec/support/artifice/windows.rb new file mode 100644 index 0000000000..ce49db5f99 --- /dev/null +++ b/spec/support/artifice/windows.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true +require File.expand_path("../../path.rb", __FILE__) +include Spec::Path + +$LOAD_PATH.unshift Dir[base_system_gems.join("gems/artifice*/lib")].first.to_s +$LOAD_PATH.unshift(*Dir[base_system_gems.join("gems/rack-*/lib")]) +$LOAD_PATH.unshift Dir[base_system_gems.join("gems/tilt*/lib")].first.to_s +$LOAD_PATH.unshift Dir[base_system_gems.join("gems/sinatra*/lib")].first.to_s +require "artifice" +require "sinatra/base" + +Artifice.deactivate + +class Artifice::Windows < Sinatra::Base + set :raise_errors, true + set :show_exceptions, false + + helpers do + def gem_repo + Pathname.new(ENV["BUNDLER_SPEC_GEM_REPO"] || Spec::Path.gem_repo1) + end + end + + files = ["specs.4.8.gz", + "prerelease_specs.4.8.gz", + "quick/Marshal.4.8/rcov-1.0-mswin32.gemspec.rz", + "gems/rcov-1.0-mswin32.gem"] + + files.each do |file| + get "/#{file}" do + File.read gem_repo.join(file) + end + end + + get "/gems/rcov-1.0-x86-mswin32.gem" do + halt 404 + end + + get "/api/v1/dependencies" do + halt 404 + end + + get "/versions" do + halt 500 + end +end + +Artifice.activate_with(Artifice::Windows) diff --git a/spec/support/builders.rb b/spec/support/builders.rb index 00024db7cf..d3e132cc8e 100644 --- a/spec/support/builders.rb +++ b/spec/support/builders.rb @@ -697,9 +697,9 @@ module Spec Bundler.rubygems.build(@spec, opts[:skip_validation]) if opts[:to_system] - `gem install --ignore-dependencies --no-ri --no-rdoc #{@spec.full_name}.gem` + gem_command :install, "--ignore-dependencies --no-ri --no-rdoc #{@spec.full_name}.gem" else - FileUtils.mv("#{@spec.full_name}.gem", opts[:path] || _default_path) + FileUtils.mv("#{@spec.full_name}.gem", destination) end end end diff --git a/spec/support/fakeweb/rack-1.0.0.marshal b/spec/support/fakeweb/rack-1.0.0.marshal deleted file mode 100644 index 383ce407f9..0000000000 --- a/spec/support/fakeweb/rack-1.0.0.marshal +++ /dev/null @@ -1,2 +0,0 @@ -[{ :dependencies[ [" thin" >= 0["ruby-openid" ~> 2.0.0[" mongrel" >= 0["memcache-client" >= 0[" fcgi" >= 0[" camping" >= 0["test-spec" >= 0: platform" ruby: name" rack: number" -1.0.0 \ No newline at end of file diff --git a/spec/support/fakeweb/windows.rb b/spec/support/fakeweb/windows.rb deleted file mode 100644 index f1f21eed3f..0000000000 --- a/spec/support/fakeweb/windows.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true -require File.expand_path("../../path.rb", __FILE__) -include Spec::Path - -files = ["specs.4.8.gz", - "prerelease_specs.4.8.gz", - "quick/Marshal.4.8/rcov-1.0-mswin32.gemspec.rz", - "gems/rcov-1.0-mswin32.gem"] - -# Set up pretend http gem server with FakeWeb -$LOAD_PATH.unshift "#{Dir[base_system_gems.join("gems/fakeweb*/lib")].first}" -require "fakeweb" - -FakeWeb.allow_net_connect = false - -files.each do |file| - FakeWeb.register_uri(:get, "http://localgemserver.test/#{file}", - :body => File.read("#{gem_repo1}/#{file}")) -end -FakeWeb.register_uri(:get, "http://localgemserver.test/gems/rcov-1.0-x86-mswin32.gem", - :status => ["404", "Not Found"]) - -FakeWeb.register_uri(:get, "http://localgemserver.test/api/v1/dependencies", - :status => ["404", "Not Found"]) - -FakeWeb.register_uri(:get, "http://localgemserver.test/versions", - :status => ["500", "Internal Server Error"]) diff --git a/spec/support/hax.rb b/spec/support/hax.rb index 2cca22c6ab..2cf2560c47 100644 --- a/spec/support/hax.rb +++ b/spec/support/hax.rb @@ -4,40 +4,50 @@ require "rubygems" class Gem::Platform @local = new(ENV["BUNDLER_SPEC_PLATFORM"]) if ENV["BUNDLER_SPEC_PLATFORM"] end +Gem.platforms.clear + +stub_const = proc do |mod, const, val| + $bundler_spec_stubbed_constants ||= {} # rubocop:disable Style/GlobalVars + orig_val = mod.send(:remove_const, const) if mod.const_defined?(const) + $bundler_spec_stubbed_constants[[mod, const]] = orig_val # rubocop:disable Style/GlobalVars + mod.send(:const_set, const, val) +end if ENV["BUNDLER_SPEC_VERSION"] - module Bundler - VERSION = ENV["BUNDLER_SPEC_VERSION"].dup - end + module Bundler; end + stub_const.call(Bundler, :VERSION, ENV["BUNDLER_SPEC_VERSION"].dup) end if ENV["BUNDLER_SPEC_WINDOWS"] == "true" require "bundler/constants" - - module Bundler - remove_const :WINDOWS if defined?(WINDOWS) - WINDOWS = true - end + stub_const.call(Bundler, :WINDOWS, true) end -class Object - if ENV["BUNDLER_SPEC_RUBY_ENGINE"] - if defined?(RUBY_ENGINE) && RUBY_ENGINE != "jruby" && ENV["BUNDLER_SPEC_RUBY_ENGINE"] == "jruby" - begin - # this has to be done up front because psych will try to load a .jar - # if it thinks its on jruby - require "psych" - rescue LoadError - nil - end +if ENV["BUNDLER_SPEC_RUBY_ENGINE"] + if defined?(RUBY_ENGINE) && RUBY_ENGINE != "jruby" && ENV["BUNDLER_SPEC_RUBY_ENGINE"] == "jruby" + begin + # this has to be done up front because psych will try to load a .jar + # if it thinks its on jruby + require "psych" + rescue LoadError + nil end + end - remove_const :RUBY_ENGINE if defined?(RUBY_ENGINE) - RUBY_ENGINE = ENV["BUNDLER_SPEC_RUBY_ENGINE"] + stub_const.call(Object, :RUBY_ENGINE, ENV["BUNDLER_SPEC_RUBY_ENGINE"]) - if RUBY_ENGINE == "jruby" - remove_const :JRUBY_VERSION if defined?(JRUBY_VERSION) - JRUBY_VERSION = ENV["BUNDLER_SPEC_RUBY_ENGINE_VERSION"] - end + if RUBY_ENGINE == "jruby" + stub_const.call(Object, :JRUBY_VERSION, ENV["BUNDLER_SPEC_RUBY_ENGINE_VERSION"]) + end +end + +if artifice = ENV["BUNDLER_SPEC_ARTIFICE_ENDPOINT"] + require File.expand_path("../artifice/#{artifice}", __FILE__) + name = artifice.to_s.gsub(/((?:^|_).)/) {|s| s.delete("_").upcase }.gsub("Api", "API") + Artifice.activate_with(Artifice.const_get(name, false)) + require "rubygems/request" + Gem::Request::ConnectionPools.client = ::Net::HTTP if defined?(Gem::Request::ConnectionPools) + class Gem::RemoteFetcher + @fetcher = nil end end diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb index bd88fdac68..b615bb9db5 100644 --- a/spec/support/helpers.rb +++ b/spec/support/helpers.rb @@ -16,16 +16,24 @@ module Spec Bundler.reset! Bundler.ui = nil Bundler.ui # force it to initialize + + allow(Bundler).to receive(:kernel_exec) do |*args| + out, err, exitstatus = Open3.capture3(*args) + puts out unless out.empty? + warn err unless err.empty? + exit(exitstatus.exitstatus) + end end def self.bang(method) define_method("#{method}!") do |*args, &blk| + invocation = "#{method}!(#{args.map(&:inspect).join(", ")})" send(method, *args, &blk).tap do if exitstatus && exitstatus != 0 error = out + "\n" + err error.strip! raise RuntimeError, - "Invoking #{method}!(#{args.map(&:inspect).join(", ")}) failed:\n#{error}", + "Invoking #{invocation} failed:\n#{error}", caller.drop_while {|bt| bt.start_with?(__FILE__) } end end @@ -78,7 +86,7 @@ module Spec File.expand_path("../../../spec", __FILE__) end - def bundle(cmd, options = {}) + def bundle(cmd, options = {}, &blk) expect_err = options.delete(:expect_err) with_sudo = options.delete(:sudo) sudo = with_sudo == :preserve_env ? "sudo -E" : "sudo" if with_sudo @@ -88,18 +96,25 @@ module Spec bundle_bin = options.delete("bundle_bin") || File.expand_path("../../../exe/bundle", __FILE__) requires = options.delete(:requires) || [] - requires << File.expand_path("../fakeweb/" + options.delete(:fakeweb) + ".rb", __FILE__) if options.key?(:fakeweb) - requires << File.expand_path("../artifice/" + options.delete(:artifice) + ".rb", __FILE__) if options.key?(:artifice) - requires << "support/hax" requires_str = requires.map {|r| "-r#{r}" }.join(" ") + ENV["BUNDLER_SPEC_ARTIFICE_ENDPOINT"] = options.delete(:artifice) - env = (options.delete(:env) || {}).map {|k, v| "#{k}='#{v}'" }.join(" ") + env = options.delete(:env) || {} + in_process_exec = options.delete(:in_process_exec) { true } args = options.map do |k, v| v == true ? " --#{k}" : " --#{k} #{v}" if v end.join - cmd = "#{env} #{sudo} #{Gem.ruby} -I#{lib}:#{spec} #{requires_str} #{bundle_bin} #{cmd}#{args}" - sys_exec(cmd, expect_err) {|i, o, thr| yield i, o, thr if block_given? } + if !in_process_exec || sudo + env = env.map {|k, v| "#{k}='#{v}'" }.join(" ") + cmd = "#{env} #{sudo} #{Gem.ruby} -I#{lib}:#{spec} #{requires_str} #{bundle_bin} #{cmd}#{args}" + sys_exec(cmd, expect_err) {|i, o, thr| yield i, o, thr if block_given? } + else + exec_in_process("#{cmd}#{args}".shellsplit, env, blk) do + requires.each {|r| require r } + Kernel.load(bundle_bin) + end + end end bang :bundle @@ -109,28 +124,24 @@ module Spec end def bundle_ruby(options = {}) - expect_err = options.delete(:expect_err) - options["no-color"] = true unless options.key?("no-color") - - bundle_bin = File.expand_path("../../../exe/bundle_ruby", __FILE__) - - requires = options.delete(:requires) || [] - requires << File.expand_path("../fakeweb/" + options.delete(:fakeweb) + ".rb", __FILE__) if options.key?(:fakeweb) - requires << File.expand_path("../artifice/" + options.delete(:artifice) + ".rb", __FILE__) if options.key?(:artifice) - requires_str = requires.map {|r| "-r#{r}" }.join(" ") - - env = (options.delete(:env) || {}).map {|k, v| "#{k}='#{v}' " }.join - cmd = "#{env}#{Gem.ruby} -I#{lib} #{requires_str} #{bundle_bin}" - - sys_exec(cmd, expect_err) {|i, o, thr| yield i, o, thr if block_given? } + options["bundle_bin"] = File.expand_path("../../../exe/bundle_ruby", __FILE__) + bundle("", options) end - def ruby(ruby, options = {}) + def ruby(ruby, options = {}, &blk) + in_process_exec = options.delete(:in_process_exec) { true } expect_err = options.delete(:expect_err) - env = (options.delete(:env) || {}).map {|k, v| "#{k}='#{v}' " }.join - ruby = ruby.gsub(/["`\$]/) {|m| "\\#{m}" } - lib_option = options[:no_lib] ? "" : " -I#{lib}" - sys_exec(%(#{env}#{Gem.ruby}#{lib_option} -e "#{ruby}"), expect_err) + ENV["BUNDLER_SPEC_ARTIFICE_ENDPOINT"] = options.delete(:artifice) + if !in_process_exec || options[:no_lib] + env = (options.delete(:env) || {}).map {|k, v| "#{k}='#{v}' " }.join + ruby = ruby.gsub(/["`\$]/) {|m| "\\#{m}" } + lib_option = options[:no_lib] ? "" : " -I#{lib}" + sys_exec(%(#{env}#{Gem.ruby}#{lib_option} -e "#{ruby}"), expect_err) + else + exec_in_process([], options.delete(:env) || {}, blk) do + Kernel.eval(ruby, TOPLEVEL_BINDING, "") + end + end end bang :ruby @@ -160,9 +171,11 @@ module Spec yield stdin, stdout, wait_thr if block_given? stdin.close - @out = Thread.new { stdout.read }.value.strip - @err = Thread.new { stderr.read }.value.strip + @out = Thread.new { stdout.read } + @err = Thread.new { stderr.read } @exitstatus = wait_thr && wait_thr.value.exitstatus + @out = @out.value.strip + @err = @err.value.strip end puts @err unless expect_err || @err.empty? || !$show_err @@ -170,6 +183,87 @@ module Spec end bang :sys_exec + def exec_in_process(argv, env, user_blk) + orig_argv = ARGV.clone + load_path = $LOAD_PATH.clone + loaded_features = $LOADED_FEATURES.clone + loaded_specs = Gem.loaded_specs.clone + orig_env = ENV.to_h + ui = Bundler.ui + constants = Object.constants + [ + :Artifice, + :CompactIndex, + :Forwardable, + :IRB, + :Rack, + :Sinatra, + :Tilt, + ] + debug = $debug + + ARGV.replace(argv) + ENV.update(Hash[env.map {|k, v| [k.to_s, v.to_s] }]) + Bundler.reset! + Bundler.ui = nil + Bundler.preserve_env! + Gem.loaded_specs.clear + $debug = !env.fetch("DEBUG") { "" }.empty? + + @out = capture(:stdout) do + @err = capture(:stderr) do + begin + Kernel.load File.join(spec, "support/hax.rb") + if user_blk + reader, writer = IO.pipe + STDIN.reopen(reader) + Thread.new do + begin + yield + nil + rescue Object => e + e + end + end.tap do |wait_thr| + user_blk.call(writer, $stdout, wait_thr) + writer.close + raise wait_thr.value if wait_thr.value + reader.close + end + else + yield + end + @exitstatus = 0 + rescue SystemExit => e + @exitstatus = e.status + rescue Exception => e # rubocop:disable Lint/RescueException + first = e.backtrace.shift + warn "#{first}: #{e} (#{e.class})" + e.backtrace.each do |bt| + break if bt.start_with?(__FILE__) + warn "\tfrom #{bt}" + end + @exitstatus = 1 + end + end.strip + end.strip + ensure + Kernel.load File.join(spec, "support/unhax.rb") + ARGV.replace(orig_argv) + ENV.replace(orig_env) + $LOAD_PATH.replace(load_path) + load_path.map! {|path| File.join(File.expand_path(path), "/") } + ($LOADED_FEATURES - loaded_features).each do |feat| + unless load_path.any? {|path| feat.start_with?(path) } + $LOADED_FEATURES.delete(feat) + end + end + Gem.loaded_specs.replace(loaded_specs) + Bundler.ui = ui + Bundler.reset! + $debug = debug + (Object.constants - constants).each {|c| Object.send(:remove_const, c) } + end + def config(config = nil, path = bundled_app(".bundle/config")) return YAML.load_file(path) unless config FileUtils.mkdir_p(File.dirname(path)) diff --git a/spec/support/rubygems_ext.rb b/spec/support/rubygems_ext.rb index e436503157..fc1dcfd024 100644 --- a/spec/support/rubygems_ext.rb +++ b/spec/support/rubygems_ext.rb @@ -9,8 +9,8 @@ module Spec # rack 2.x requires Ruby version >= 2.2.2. # artifice doesn't support rack 2.x now. "rack" => "< 2", - "fakeweb artifice compact_index" => nil, - "sinatra" => "1.2.7", + "artifice compact_index" => nil, + "sinatra" => "1.4.7", # Rake version has to be consistent for tests to pass "rake" => "10.0.2", # 3.0.0 breaks 1.9.2 specs diff --git a/spec/support/unhax.rb b/spec/support/unhax.rb new file mode 100644 index 0000000000..e856a05b0d --- /dev/null +++ b/spec/support/unhax.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true +Artifice.deactivate if defined?(Artifice) +Gem::Request::ConnectionPools.client = ::Net::HTTP if defined?(Gem::Request::ConnectionPools) +class Gem::RemoteFetcher + @fetcher = nil +end + +class Gem::Platform + @local = nil +end +Gem.platforms.clear + +$bundler_spec_stubbed_constants ||= {} # rubocop:disable Style/GlobalVars +$bundler_spec_stubbed_constants.each do |(mod, const), val| # rubocop:disable Style/GlobalVars + mod.send(:remove_const, const) if mod.send(:const_defined?, const) + mod.send(:const_set, const, val) if val +end +$bundler_spec_stubbed_constants.clear # rubocop:disable Style/GlobalVars + +ENV.delete("BUNDLER_SPEC_ARTIFICE_ENDPOINT") -- cgit v1.2.1