summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Giddins <segiddins@segiddins.me>2017-07-06 18:07:15 -0400
committerSamuel Giddins <segiddins@segiddins.me>2017-07-06 18:07:15 -0400
commit357ba9d9012751d74c61228be430c4ea05369028 (patch)
treedd778f8c551bc86a65a28559600ec1f889154adb
parent93c48c751bb5c7d5fcb5fb0f4ba586a059008e0f (diff)
downloadbundler-seg-hot-mess-in-proc-specs.tar.gz
WIP in-process specsseg-hot-mess-in-proc-specs
-rwxr-xr-xexe/bundle_ruby4
-rw-r--r--lib/bundler.rb23
-rw-r--r--lib/bundler/cli.rb2
-rw-r--r--lib/bundler/definition.rb1
-rw-r--r--lib/bundler/friendly_errors.rb8
-rw-r--r--lib/bundler/rubygems_integration.rb2
-rw-r--r--spec/bundler/cli_spec.rb57
-rw-r--r--spec/commands/install_spec.rb29
-rw-r--r--spec/lock/git_spec.rb12
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--spec/support/hax.rb25
-rw-r--r--spec/support/helpers.rb78
-rw-r--r--spec/support/matchers.rb9
-rw-r--r--spec/support/path.rb4
14 files changed, 193 insertions, 62 deletions
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 b0f6869423..18443d468d 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -15,9 +15,14 @@ require "bundler/current_ruby"
require "bundler/build_metadata"
module Bundler
- environment_preserver = EnvironmentPreserver.new(ENV, EnvironmentPreserver::BUNDLER_KEYS)
- 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, EnvironmentPreserver::BUNDLER_KEYS)
+ ORIGINAL_ENV.replace environment_preserver.restore
+ ENV.replace(environment_preserver.backup)
+ end
+ preserve_env!
+
SUDO_MUTEX = Mutex.new
autoload :Definition, "bundler/definition"
@@ -38,6 +43,7 @@ module Bundler
autoload :Injector, "bundler/injector"
autoload :Installer, "bundler/installer"
autoload :LazySpecification, "bundler/lazy_specification"
+ autoload :LockfileGenerator, "bundler/lockfile_generator"
autoload :LockfileParser, "bundler/lockfile_parser"
autoload :MatchPlatform, "bundler/match_platform"
autoload :RemoteSpecification, "bundler/remote_specification"
@@ -451,14 +457,14 @@ EOF
end
def reset_paths!
- @root = nil
- @settings = nil
+ @bin_path = nil
+ @bundle_path = nil
@definition = nil
- @setup = nil
@load = nil
@locked_gems = nil
- @bundle_path = nil
- @bin_path = nil
+ @root = nil
+ @settings = nil
+ @setup = nil
@user_home = nil
end
@@ -466,6 +472,7 @@ EOF
return unless defined?(@rubygems) && @rubygems
rubygems.undo_replacements
rubygems.reset
+ rubygems.clear_paths
@rubygems = nil
end
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 786e24b2de..8304b5b89f 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -96,7 +96,7 @@ module Bundler
# Ensure `bundle help --no-color` is valid
all_commands["help"].disable_class_options = false
- def self.handle_no_command_error(command, has_namespace = $thor_runner)
+ def self.handle_no_command_error(command, has_namespace = false)
if Bundler.feature_flag.plugins? && Bundler::Plugin.command?(command)
return Bundler::Plugin.exec_command(command, ARGV[1..-1])
end
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index bf0316b8d8..bb173588b6 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -362,7 +362,6 @@ module Bundler
end
def to_lock
- require "bundler/lockfile_generator"
LockfileGenerator.generate(self)
end
diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb
index 9caeeee1a5..a073301b5d 100644
--- a/lib/bundler/friendly_errors.rb
+++ b/lib/bundler/friendly_errors.rb
@@ -115,12 +115,16 @@ module Bundler
"https://github.com/bundler/bundler/search?q=" \
"#{CGI.escape(message)}&type=Issues"
end
+
+ def handle_error(error)
+ log_error(error)
+ exit exit_status(error)
+ end
end
def self.with_friendly_errors
yield
rescue Exception => e
- FriendlyErrors.log_error(e)
- exit FriendlyErrors.exit_status(e)
+ FriendlyErrors.handle_error(e)
end
end
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
index edc931e79f..b70110ffe6 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -505,7 +505,7 @@ module Bundler
replace_bin_path(specs, specs_by_name)
replace_refresh
- Gem.clear_paths
+ clear_paths
end
# This backports the correct segment generation code from RubyGems 1.4+
diff --git a/spec/bundler/cli_spec.rb b/spec/bundler/cli_spec.rb
index 5df50c94ec..9bf30b30ac 100644
--- a/spec/bundler/cli_spec.rb
+++ b/spec/bundler/cli_spec.rb
@@ -1,15 +1,18 @@
# frozen_string_literal: true
require "bundler/cli"
+require "bundler/friendly_errors"
RSpec.describe "bundle executable" do
it "returns non-zero exit status when passed unrecognized options" do
- bundle "--invalid_argument"
- expect(exitstatus).to_not be_zero if exitstatus
+ bundle_command "--invalid_argument"
+ expect(last_command).to be_failure
+ expect(last_command.bundler_err).to eq "Unknown switches '--invalid_argument'"
end
it "returns non-zero exit status when passed unrecognized task" do
- bundle "unrecognized-task"
- expect(exitstatus).to_not be_zero if exitstatus
+ bundle_command "unrecognized-task"
+ expect(last_command).to be_failure
+ expect(last_command.bundler_err).to eq 'Could not find command "unrecognized-task".'
end
it "looks for a binary and executes it if it's named bundler-<task>" do
@@ -17,51 +20,21 @@ RSpec.describe "bundle executable" do
f.puts "#!/usr/bin/env ruby\nputs 'Hello, world'\n"
end
+ expect(Kernel).to receive(:exec).with(tmp("bundler-testtasks").to_s)
with_path_added(tmp) do
- bundle "testtasks"
- end
-
- expect(exitstatus).to be_zero if exitstatus
- expect(out).to eq("Hello, world")
- end
-
- context "when ENV['BUNDLE_GEMFILE'] is set to an empty string" do
- it "ignores it" do
- gemfile bundled_app("Gemfile"), <<-G
- source "file://#{gem_repo1}"
- gem 'rack'
- G
-
- bundle :install, :env => { "BUNDLE_GEMFILE" => "" }
-
- expect(the_bundle).to include_gems "rack 1.0.0"
- end
- end
-
- context "when ENV['RUBYGEMS_GEMDEPS'] is set" do
- it "displays a warning" do
- gemfile bundled_app("Gemfile"), <<-G
- source "file://#{gem_repo1}"
- gem 'rack'
- G
-
- bundle :install, :env => { "RUBYGEMS_GEMDEPS" => "foo" }
- expect(out).to include("RUBYGEMS_GEMDEPS")
- expect(out).to include("conflict with Bundler")
-
- bundle :install, :env => { "RUBYGEMS_GEMDEPS" => "" }
- expect(out).not_to include("RUBYGEMS_GEMDEPS")
+ bundle_command! "testtasks"
end
end
context "with --verbose" do
it "prints the running command" do
- bundle! "config", :verbose => true
+ bundle_command! :config, :verbose => true
expect(last_command.stdout).to start_with("Running `bundle config --verbose` with bundler #{Bundler::VERSION}")
end
it "doesn't print defaults" do
- install_gemfile! "", :verbose => true
+ gemfile ""
+ bundle_command! :install, :verbose => true, :retry => 0, :"no-color" => true
expect(last_command.stdout).to start_with("Running `bundle install --no-color --retry 0 --verbose` with bundler #{Bundler::VERSION}")
end
end
@@ -69,7 +42,7 @@ RSpec.describe "bundle executable" do
describe "printing the outdated warning" do
shared_examples_for "no warning" do
it "prints no warning" do
- bundle "fail"
+ bundle_command "fail"
expect(last_command.stdboth).to eq("Could not find command \"fail\".")
end
end
@@ -102,7 +75,7 @@ RSpec.describe "bundle executable" do
context "when the latest version is greater than the current version" do
let(:latest_version) { "2.0" }
it "prints the version warning" do
- bundle "fail"
+ bundle_command "fail"
expect(last_command.stdout).to start_with(<<-EOS.strip)
The latest bundler is #{latest_version}, but you are currently running #{bundler_version}.
To update, run `gem install bundler`
@@ -130,7 +103,7 @@ end
RSpec.describe "bundler executable" do
it "shows the bundler version just as the `bundle` executable does" do
- bundler "--version"
+ bundle_command "--version", :exe => bundle_exe("bundler")
expect(out).to eq("Bundler version #{Bundler::VERSION}")
end
end
diff --git a/spec/commands/install_spec.rb b/spec/commands/install_spec.rb
index a21b735f8e..e1d00dd4df 100644
--- a/spec/commands/install_spec.rb
+++ b/spec/commands/install_spec.rb
@@ -507,4 +507,33 @@ RSpec.describe "bundle install with gem sources" do
"setting them for authentication.")
end
end
+
+ context "when ENV['BUNDLE_GEMFILE'] is set to an empty string" do
+ it "ignores it" do
+ gemfile bundled_app("Gemfile"), <<-G
+ source "file://#{gem_repo1}"
+ gem 'rack'
+ G
+
+ bundle :install, :env => { "BUNDLE_GEMFILE" => "" }
+
+ expect(the_bundle).to include_gems "rack 1.0.0"
+ end
+ end
+
+ context "when ENV['RUBYGEMS_GEMDEPS'] is set" do
+ it "displays a warning" do
+ gemfile bundled_app("Gemfile"), <<-G
+ source "file://#{gem_repo1}"
+ gem 'rack'
+ G
+
+ bundle :install, :env => { "RUBYGEMS_GEMDEPS" => "foo" }
+ expect(out).to include("RUBYGEMS_GEMDEPS")
+ expect(out).to include("conflict with Bundler")
+
+ bundle :install, :env => { "RUBYGEMS_GEMDEPS" => "" }
+ expect(out).not_to include("RUBYGEMS_GEMDEPS")
+ end
+ end
end
diff --git a/spec/lock/git_spec.rb b/spec/lock/git_spec.rb
index 4179a0218a..b622328fb4 100644
--- a/spec/lock/git_spec.rb
+++ b/spec/lock/git_spec.rb
@@ -4,20 +4,21 @@ RSpec.describe "bundle lock with git gems" do
before :each do
build_git "foo"
- install_gemfile <<-G
+ gemfile <<-G
gem 'foo', :git => "#{lib_path("foo-1.0")}"
G
+ bundle_command! :install
end
it "doesn't break right after running lock" do
- expect(the_bundle).to include_gems "foo 1.0.0"
+ expect(the_bundle).to include_gems "foo 1.0.0", :as_if => true
end
it "locks a git source to the current ref" do
update_git "foo"
- bundle :install
+ bundle_command! :install
- run <<-RUBY
+ run_as_if <<-RUBY
require 'foo'
puts "WIN" unless defined?(FOO_PREV_REF)
RUBY
@@ -26,9 +27,10 @@ RSpec.describe "bundle lock with git gems" do
end
it "provides correct #full_gem_path" do
- run <<-RUBY
+ run_as_if <<-RUBY
puts Bundler.rubygems.find_name('foo').first.full_gem_path
RUBY
+
expect(out).to eq(bundle("show foo"))
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 5c7fcbffa5..a5a3eca081 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -23,6 +23,7 @@ if File.expand_path(__FILE__) =~ %r{([^\w/\.])}
end
require "bundler"
+require "bundler/cli"
# Require the correct version of popen for the current platform
if RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
diff --git a/spec/support/hax.rb b/spec/support/hax.rb
index 663d3527c5..8f5fc8aaec 100644
--- a/spec/support/hax.rb
+++ b/spec/support/hax.rb
@@ -1,6 +1,31 @@
# frozen_string_literal: true
require "rubygems"
+module BundlerSpecOriginal
+ UNSET = Module.new
+ GEM_PLATFORM_LOCAL = Gem::Platform.local
+ CONSTANTS = Hash[
+ %w[Bundler::VERSION Bundler::WINDOWS Object::RUBY_ENGINE Object::RUBY_ENGINE_VERSION].map do |const|
+ value = const.split("::").reduce(Module) {|ns, c| ns.const_defined?(c) ? ns.const_get(c) : UNSET }
+ [const, value]
+ end
+ ]
+
+ def self.reset!
+ Gem.module_exec { @platforms = nil }
+ Gem::Platform.module_exec { @local = BundlerSpecOriginal::GEM_PLATFORM_LOCAL }
+
+ CONSTANTS.each do |name, value|
+ parts = name.split("::")
+ sym = parts.pop
+ namespace = parts.reduce(Module) {|ns, c| ns.const_get(c) }
+ namespace.send(:remove_const, sym) if namespace.const_defined?(sym)
+ namespace.const_set(sym, value) unless UNSET == value
+ end
+ Object.send :remove_const, :BundlerSpecOriginal
+ end
+end
+
module Gem
class Platform
@local = new(ENV["BUNDLER_SPEC_PLATFORM"]) if ENV["BUNDLER_SPEC_PLATFORM"]
diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb
index 03d9711878..4f49de3cb5 100644
--- a/spec/support/helpers.rb
+++ b/spec/support/helpers.rb
@@ -12,6 +12,7 @@ module Spec
end
FileUtils.mkdir_p(home)
FileUtils.mkdir_p(tmpdir)
+ Bundler.rubygems
Bundler.reset!
Bundler.ui = nil
Bundler.ui # force it to initialize
@@ -141,6 +142,83 @@ module Spec
end
bang :bundle
+ def bundle_command(*args)
+ options = args.last.is_a?(Hash) ? args.pop : {}
+ exe = options.delete(:exe) { bundle_exe }
+ env = options.delete(:env) { {} }
+ args += options.map do |k, v|
+ v == true ? ["--#{k}"] : ["--#{k}", v.to_s] if v
+ end.compact.flatten(1)
+ args = args.flatten.map(&:to_s)
+
+ as_if_running("#{exe} #{args.join(" ")}") do
+ ENV.update(env)
+
+ ARGV.replace args.flatten.map(&:to_s)
+ load exe.to_s
+ end
+ end
+ bang :bundle_command
+
+ def as_if
+ argv = ARGV.dup
+ env = ENV.to_h.dup
+ load_path = $LOAD_PATH.map(&:dup)
+ loaded_features = $LOADED_FEATURES.map(&:dup)
+ object_constants = ::Object.constants.to_set
+
+ yield
+ ensure
+ ARGV.replace argv
+ ENV.clear
+ ENV.update env
+ $LOAD_PATH.replace load_path
+ bundler_loaded_features = $LOADED_FEATURES.select {|lf| lf.start_with? bundler_path.to_s }
+ $LOADED_FEATURES.replace loaded_features.concat(bundler_loaded_features)
+ ::Object.constants.each do |const|
+ next if object_constants.include?(const)
+ ::Object.send(:remove_const, const)
+ end
+ end
+
+ def as_if_running(cmd)
+ as_if do
+ command_execution = Spec::CommandExecution.new(cmd.to_s, Dir.pwd)
+ command_execution.stdout = capture(:stdout) do
+ command_execution.stderr = capture(:stderr) do
+ begin
+ load root.join("spec", "support", "hax.rb")
+ Bundler.preserve_env!
+
+ yield
+ rescue SystemExit => exception
+ command_execution.exitstatus = exception.status
+ rescue
+ raise
+ else
+ command_execution.exitstatus = 0
+ ensure
+ BundlerSpecOriginal.reset!
+ Bundler.reset!
+ end
+ end.strip
+ end.strip
+
+ (@command_executions ||= []) << command_execution
+
+ command_execution.stdout
+ end
+ end
+
+ def run_as_if(cmd, *args)
+ cmd = strip_whitespace(cmd)
+ as_if_running("ruby -e #{cmd.inspect}") do
+ _opts = args.last.is_a?(Hash) ? args.pop : {}
+ Bundler.setup(*args.map(&:to_s))
+ eval(cmd)
+ end
+ end
+
def bundler(cmd, options = {})
options["bundle_bin"] = File.expand_path("../../../exe/bundler", __FILE__)
bundle(cmd, options)
diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb
index 7316e43684..5748ff7f3b 100644
--- a/spec/support/matchers.rb
+++ b/spec/support/matchers.rb
@@ -141,6 +141,15 @@ module Spec
end
define_compound_matcher :include_gems, [be_an_instance_of(Spec::TheBundle)] do |*names|
+ define_method :run do |*args|
+ opts = names.last.is_a?(Hash) ? names.pop : {}
+ if opts.delete(:as_if) { false }
+ run_as_if!(*args)
+ else
+ run!(*args)
+ end
+ end
+
match do
opts = names.last.is_a?(Hash) ? names.pop : {}
source = opts.delete(:source)
diff --git a/spec/support/path.rb b/spec/support/path.rb
index 2b929003fb..ceb060ac81 100644
--- a/spec/support/path.rb
+++ b/spec/support/path.rb
@@ -93,6 +93,10 @@ module Spec
tmp "tmpdir", *args
end
+ def bundle_exe(exe = "bundle")
+ root.join("exe", exe)
+ end
+
extend self
end
end