diff --git a/README.md b/README.md index a61acef4..60583abd 100644 --- a/README.md +++ b/README.md @@ -358,6 +358,16 @@ end If you want to register multiple callbacks you can simply call `Spring.after_fork` multiple times with different blocks. +If you accept an argument, it will contain an object with information about the +Spring client request and server state. You can use it to detect environment +variable mismatch between the invocation and the spring instance startup: + +```ruby +Spring.after_fork do |cb| + raise "error" if cb.env['MASTER'].present? && cb.env['MASTER'] != ENV['MASTER'] +end +``` + ### Watching files and directories Spring will automatically detect file changes to any file loaded when the server @@ -386,6 +396,23 @@ a command runs: Spring.quiet = true ``` +### Environment variable overrides + +When the spring server starts up a new instance of the application, it does not +set all environment variables by default. Only the environment variables that +were set when the spring server started and were not changed by the application +are propagated. + +This can be customized with `Spring.env_override`: + +- `Spring.env_override = false` : default behavior noted above + +- `Spring.env_override = true` : all variables are applied, regardless of if + they were changed by the application or not. + +- `Spring.env_override = []` (array of strings) : in addition to the usual + behavior, the variable listed here will be propagated + ### Environment variables The following environment variables are used by Spring: diff --git a/lib/spring/application.rb b/lib/spring/application.rb index fe640043..6027c448 100644 --- a/lib/spring/application.rb +++ b/lib/spring/application.rb @@ -187,13 +187,27 @@ def serve(client) # Delete all env vars which are unchanged from before Spring started original_env.each { |k, v| ENV.delete k if ENV[k] == v } + # if env_override is an array, delete the variables listed + if Spring.env_override.is_a? Array + Spring.env_override.each { |k| ENV.delete k } + end + # Load in the current env vars, except those which *were* changed when Spring started - env.each { |k, v| ENV[k] ||= v } + # if env_override is true, load in *all* the current vars + env.each do |k, v| + if Spring.env_override == true + ENV[k] = v + else + ENV[k] ||= v + end + end connect_database srand - invoke_after_fork_callbacks + invoke_after_fork_callbacks(OpenStruct.new( + env: env, + original_env: original_env)) shush_backtraces command.call @@ -256,9 +270,13 @@ def setup(command) end end - def invoke_after_fork_callbacks + def invoke_after_fork_callbacks(arg) Spring.after_fork_callbacks.each do |callback| - callback.call + if callback.arity == 1 + callback.call(arg) + else + callback.call + end end end diff --git a/lib/spring/configuration.rb b/lib/spring/configuration.rb index eba8e9a7..45926d80 100644 --- a/lib/spring/configuration.rb +++ b/lib/spring/configuration.rb @@ -2,7 +2,7 @@ module Spring class << self - attr_accessor :application_root, :quiet + attr_accessor :application_root, :quiet, :env_override def gemfile if /\s1.9.[0-9]/ === Bundler.ruby_scope.gsub(/[\/\s]+/,'') @@ -55,4 +55,5 @@ def find_project_root(current_dir) end self.quiet = false + self.env_override = false end