diff --git a/History.md b/History.md index 91d737993f..991a053014 100644 --- a/History.md +++ b/History.md @@ -10,6 +10,7 @@ * Bugfixes * Your bugfix goes here (#Github Number) * Windows update extconf.rb for use with ssp and varied Ruby/MSYS2 combinations (#2069) + * Preserve `BUNDLE_GEMFILE` env var when using `prune_bundler` (#1893) * Refactor * Remove unused loader argument from Plugin initializer (#2095) diff --git a/lib/puma/launcher.rb b/lib/puma/launcher.rb index 4b96588a57..f45e035edc 100644 --- a/lib/puma/launcher.rb +++ b/lib/puma/launcher.rb @@ -297,8 +297,10 @@ def prune_bundler log '* Pruning Bundler environment' home = ENV['GEM_HOME'] + bundle_gemfile = ENV['BUNDLE_GEMFILE'] Bundler.with_clean_env do ENV['GEM_HOME'] = home + ENV['BUNDLE_GEMFILE'] = bundle_gemfile ENV['PUMA_BUNDLER_PRUNED'] = '1' args = [Gem.ruby, puma_wild_location, '-I', dirs.join(':'), deps.join(',')] + @original_argv # Ruby 2.0+ defaults to true which breaks socket activation diff --git a/test/bundle_preservation_test/.gitignore b/test/bundle_preservation_test/.gitignore new file mode 100644 index 0000000000..53c6471352 --- /dev/null +++ b/test/bundle_preservation_test/.gitignore @@ -0,0 +1 @@ +Gemfile.bundle_env_preservation_test.lock diff --git a/test/bundle_preservation_test/Gemfile.bundle_env_preservation_test b/test/bundle_preservation_test/Gemfile.bundle_env_preservation_test new file mode 100644 index 0000000000..e0695ee62c --- /dev/null +++ b/test/bundle_preservation_test/Gemfile.bundle_env_preservation_test @@ -0,0 +1 @@ +gem 'puma', path: '../..' diff --git a/test/bundle_preservation_test/config.ru b/test/bundle_preservation_test/config.ru new file mode 100644 index 0000000000..1f0f2cc619 --- /dev/null +++ b/test/bundle_preservation_test/config.ru @@ -0,0 +1 @@ +run lambda { |env| [200, {'Content-Type'=>'text/plain'}, [ENV['BUNDLE_GEMFILE'].inspect]] } diff --git a/test/helpers/integration.rb b/test/helpers/integration.rb index 7cd6b74e3d..173a5fc9a6 100644 --- a/test/helpers/integration.rb +++ b/test/helpers/integration.rb @@ -75,14 +75,24 @@ def restart_server_and_listen(argv) end # reuses an existing connection to make sure that works - def restart_server(connection) + def restart_server(connection, log: false) Process.kill :USR2, @pid connection.write "GET / HTTP/1.1\r\n\r\n" # trigger it to start by sending a new request - wait_for_server_to_boot + wait_for_server_to_boot(log: log) end - def wait_for_server_to_boot - true while @server.gets !~ /Ctrl-C/ # wait for server to say it booted + # wait for server to say it booted + def wait_for_server_to_boot(log: false) + if log + puts "Waiting for server to boot..." + begin + line = @server.gets + puts line if line && line.strip != '' + end while line !~ /Ctrl-C/ + puts "Server booted!" + else + true while @server.gets !~ /Ctrl-C/ + end end def connect(path = nil, unix: false) diff --git a/test/test_preserve_bundler_env.rb b/test/test_preserve_bundler_env.rb new file mode 100644 index 0000000000..1dd1b43447 --- /dev/null +++ b/test/test_preserve_bundler_env.rb @@ -0,0 +1,35 @@ +require_relative "helper" +require_relative "helpers/integration" + +class TestPreserveBundlerEnv < TestIntegration + def setup + skip NO_FORK_MSG unless HAS_FORK + super + end + + # It does not wipe out BUNDLE_GEMFILE et al + def test_usr2_restart_preserves_bundler_environment + skip_unless_signal_exist? :USR2 + + @tcp_port = UniquePort.call + env = { + # Intentionally set this to something we wish to keep intact on restarts + "BUNDLE_GEMFILE" => "Gemfile.bundle_env_preservation_test", + # Don't allow our (rake test's) original env to interfere with the child process + "BUNDLER_ORIG_BUNDLE_GEMFILE" => nil + } + # Must use `bundle exec puma` here, because otherwise Bundler may not be defined, which is required to trigger the bug + cmd = "bundle exec puma -q -w 1 --prune-bundler -b tcp://#{HOST}:#{@tcp_port}" + Dir.chdir(File.expand_path("bundle_preservation_test", __dir__)) do + @server = IO.popen(env, cmd.split, "r") + end + wait_for_server_to_boot + @pid = @server.pid + connection = connect + initial_reply = read_body(connection) + assert_match("Gemfile.bundle_env_preservation_test", initial_reply) + restart_server connection + new_reply = read_body(connection) + assert_match("Gemfile.bundle_env_preservation_test", new_reply) + end +end