Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support dual/multi-booting Rails apps with different Gemfiles #600

Open
eliotsykes opened this issue Sep 23, 2019 · 0 comments
Open

Support dual/multi-booting Rails apps with different Gemfiles #600

eliotsykes opened this issue Sep 23, 2019 · 0 comments

Comments

@eliotsykes
Copy link
Contributor

eliotsykes commented Sep 23, 2019

Out-of-the box, spring needs custom configuration of the SPRING_APPLICATION_ID env var to support dual-booting different Gemfiles. This is because the generated application_id only takes into account the RUBY_VERSION and the project_root path.

Would it be a welcome PR to change the current application_id generation to use the Gemfile lockfile path instead of the project_root path? This would allow Spring to support multiple gemfiles without custom config, as it will start a spring server for each Gemfile:

def application_id
- ENV["SPRING_APPLICATION_ID"] || Digest::MD5.hexdigest(RUBY_VERSION + project_root.to_s)
+ ENV["SPRING_APPLICATION_ID"] || Digest::MD5.hexdigest(RUBY_VERSION + Bundler.default_lockfile.to_s)
end

For developers wanting to support this today, you can set SPRING_APPLICATION_ID in bin/spring by adding the lines shown below.

File: bin/spring

#!/usr/bin/env ruby

# This file loads Spring without using Bundler, in order to be fast.
# It gets overwritten when you run the `spring binstub` command.

unless defined?(Spring)
  require 'rubygems'
  require 'bundler'

+ # The default application_id generated by Spring::Env#application_id
+ # does not support booting with different Gemfiles. The default
+ # value is `Digest::MD5.hexdigest(RUBY_VERSION + project_root.to_s)`
+ # Here, we set the SPRING_APPLICATION_ID env var to customize the
+ # application_id so it takes the current gemfile into account, to
+ # support booting with different Gemfiles.
+ def configure_spring_for_multiple_gemfiles
+   require 'digest/md5'
+   ENV["SPRING_APPLICATION_ID"] = Digest::MD5.hexdigest(RUBY_VERSION + Bundler.default_lockfile.to_s)
+ end
+ configure_spring_for_multiple_gemfiles
+
  lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
  spring = lockfile.specs.detect { |spec| spec.name == 'spring' }
  if spring
    Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
    gem 'spring', spring.version
    require 'spring/binstub'
  end
end

To check this is working, perform the following steps:

  1. Kill all current spring servers: Running bin/spring stop and pkill -9 spring should do it.
  2. Run a rails console using the default Gemfile: bin/rails c. Check the Rails.version is as expected for Gemfile.
  3. Run another rails console, using a non-default Gemfile: BUNDLE_GEMFILE=Gemfile_next bin/rails c. Check the Rails.version is as expected for Gemfile.
  4. Run bin/spring status. This should show a spring development env running. Note the process ids.
  5. Run BUNDLE_GEMFILE=Gemfile_next bin/spring status. This should show another spring development env running, but the process ids should be different to those noted in the previous step.

To ensure the above config isn't accidentally deleted from bin/spring (say when the binstub is regenerated), in config/spring.rb add the following:

Spring.after_fork do
  require 'digest/md5'
  expected_spring_application_id = Digest::MD5.hexdigest(RUBY_VERSION + Bundler.default_lockfile.to_s)
  if ENV["SPRING_APPLICATION_ID"] != expected_spring_application_id
    raise "Spring is misconfigured! Check bin/spring defines and calls `configure_spring_for_multiple_gemfiles`"
  end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant