diff --git a/lib/spring/application.rb b/lib/spring/application.rb index fe640043..d5a14459 100644 --- a/lib/spring/application.rb +++ b/lib/spring/application.rb @@ -152,7 +152,18 @@ def serve(client) _stdout, stderr, _stdin = streams = 3.times.map { client.recv_io } [STDOUT, STDERR, STDIN].zip(streams).each { |a, b| a.reopen(b) } - preload unless preloaded? + if preloaded? + client.puts(0) # preload success + else + begin + preload + client.puts(0) # preload success + rescue Exception + log "preload failed" + client.puts(1) # preload failure + raise + end + end args, env = JSON.load(client.read(client.gets.to_i)).values_at("args", "env") command = Spring.command(args.shift) diff --git a/lib/spring/client/run.rb b/lib/spring/client/run.rb index 3a60608a..c5fe1dd5 100644 --- a/lib/spring/client/run.rb +++ b/lib/spring/client/run.rb @@ -142,12 +142,17 @@ def connect_to_application(client) end def run_command(client, application) - log "sending command" - application.send_io STDOUT application.send_io STDERR application.send_io STDIN + log "waiting for the application to be preloaded" + preload_status = application.gets + preload_status = preload_status.chomp if preload_status + log "app preload status: #{preload_status}" + exit 1 if preload_status == "1" + + log "sending command" send_json application, "args" => args, "env" => ENV.to_hash pid = server.gets diff --git a/test/support/acceptance_test.rb b/test/support/acceptance_test.rb index 6225c6aa..4ef8cc2d 100644 --- a/test/support/acceptance_test.rb +++ b/test/support/acceptance_test.rb @@ -98,6 +98,15 @@ def without_gem(name) end end + test "crash on boot" do + app.run app.spring_test_command, env: { + "CRASH_ON_BOOT" => "1", + # If the command is small enough, it might fit in the socket buffer and writing the command won't block. + # So we send a big environment variable to better reproduce the problem. + "FOO" => "bar" * 4_000, + } + end + test "help message when called without arguments" do assert_success "bin/spring", stdout: 'Usage: spring COMMAND [ARGS]' assert spring_env.server_running? diff --git a/test/support/application.rb b/test/support/application.rb index fa2fc4a6..bd91e8a2 100644 --- a/test/support/application.rb +++ b/test/support/application.rb @@ -113,7 +113,7 @@ def run(command, opts = {}) Bundler.with_clean_env do Process.spawn( - env, + env.merge(opts[:env] || {}), command.to_s, out: stdout.last, err: stderr.last, diff --git a/test/support/application_generator.rb b/test/support/application_generator.rb index 1aac0fcb..2485385c 100644 --- a/test/support/application_generator.rb +++ b/test/support/application_generator.rb @@ -54,6 +54,8 @@ def generate_files append_to_file(application.gemfile, "gem 'spring', '#{Spring::VERSION}'") + append_to_file(application.path("config/boot.rb"), "raise 'BOOM' if ENV['CRASH_ON_BOOT']") + rewrite_file(application.gemfile) do |c| c.sub!("https://rubygems.org", "http://rubygems.org") c.gsub!(/(gem '(byebug|web-console|sdoc|jbuilder)')/, "# \\1")