Code Monkey home page Code Monkey logo

bootboot's Introduction

๐Ÿ‘ข๐Ÿ‘ข Bootboot - Build Status

Introduction

Bootboot is a Bundler plugin meant to help dual boot your ruby application.

What is "Dual booting"?

In this context, dual boot is the process of booting your application with a different set of dependencies. This technique has become very popular in the Ruby community to help applications safely upgrade dependencies. If you want to learn more about it, have a look at this conference talk by @rafaelfranca.

There are two schools on how to dual boot your app, each having advantages and disadvantages.

  1. Use three Gemfiles. One with current production dependencies, a second with an alternate "next" set of dependencies, and a third containing the dependencies that both Gemfiles have in common.
# Gemfile.common
gem "some_gem"

# Gemfile
gem "rails", "~> 5.1.0"
eval_gemfile "Gemfile.common"

# Gemfile.next
gem "rails", "~> 5.2.0"
eval_gemfile "Gemfile.common"
  1. Have a single Gemfile containing dependencies separated by environment sensitive if statements.
# Gemfile

if ENV['DEPENDENCIES_NEXT']
  gem "rails", "~> 5.2.0"
else
  gem "rails", "~> 5.1.0"
end

The former doesn't require any Bundler workaround but you need to deal with three Gemfiles and the confusion that comes with it. The latter is the approach we decided to take at Shopify and it worked very well for us for multiple years.

No matter what approach you decide to take, you'll need to create tooling to ensure that all the lockfiles are in sync whenever a developer updates a dependency.

Bootboot is only useful if you decide to follow the second approach. It creates the required tooling as well as the Bundler workaround needed to enable dual booting.

Installation

  1. In your Gemfile, add this
plugin 'bootboot', '~> 0.2.1'
  1. Run bundle install && bundle bootboot
  2. You're done. Commit the Gemfile and the Gemfile_next.lock

Note: You should only run bundle bootboot once to install the plugin, otherwise your Gemfile will get updated each time you run it.

Dual boot it!

If you want to boot using the dependencies from the Gemfile_next.lock, run any bundler command prefixed with the DEPENDENCIES_NEXT=1 ENV variable. I.e. DEPENDENCIES_NEXT=1 bundle exec irb.

Note: bootboot will use the gems and Ruby version specified per environment in your Gemfile to resolve dependencies and keep Gemfile.lock and Gemfile_next.lock in sync, but it does not do any magic to actually change the running Ruby version or install the gems in the environment you are not currently running, it simply tells Bundler which Ruby and gem versions to use in its resolution algorithm and keeps the lock files in sync. If you are a developer who is not involved in updating the dependency set, this should not affect you, simply use bundler normally. However, if you are involved in the dependency changes directly, you will often have to run DEPENDENCIES_NEXT=1 bundle install after making changes to the dependencies.

# This will update Gemfile.lock and Gemfile_next.lock and install the gems
# specified in Gemfile.lock:
$ bundle update some_gem
# This will actually install the gems specified in Gemfile_next.lock
$ DEPENDENCIES_NEXT=1 bundle install

Dual boot different Ruby versions

While dual booting is often used for framework upgrades, it is also possible to use bootboot to dual boot two Ruby versions, each with its own set of gems.

# Gemfile

if ENV['DEPENDENCIES_NEXT']
  ruby '2.6.5'
else
  ruby '2.5.7'
end

Dual booting Ruby versions does incur some additional complications however, see the examples following for more detail.

Example: updating a gem while dual booting Ruby versions

To dual boot an app while upgrading from Ruby 2.5.7 to Ruby 2.6.5, your Gemfile would look like this:

# Gemfile

if ENV['DEPENDENCIES_NEXT']
  ruby '2.6.5'
else
  ruby '2.5.7'
end

After running bundle install, Gemfile.lock will have:

RUBY VERSION
   ruby 2.5.7p206

and Gemfile_next.lock will have:

RUBY VERSION
   ruby 2.6.5p114

Assuming there's a gem some_gem with the following constraints in its gemspecs:

# some_gem-1.0.gemspec
spec.version = "1.0"
spec.required_ruby_version = '>= 2.5.7'
# some_gem-2.0.gemspec
spec.version = "2.0"
spec.required_ruby_version = '>= 2.6.5'

Running bundle update some_gem will use Ruby 2.5.7 to resolve some_gem for Gemfile.lock and Ruby 2.6.5 to resolve some_gem for Gemfile_next.lock with the following results:

Gemfile.lock:

specs:
  some_gem (1.0)

Gemfile_next.lock:

specs:
  some_gem (2.0)

Note: It is important to note that at this point, some_gem 2.0 will not be installed on your system, it will simply be specified in Gemfile_next.lock, since installing it on the system would require changing the running Ruby version. This is sufficient to keep Gemfile_next.lock in sync, but is a potential source of confusion. To install gems under both versions of Ruby, see the next section.

Vendoring both sets of gems

To vendor both sets of gems, make sure caching is enabled by checking bundle config or bundle gems using bundle pack.

bundle pack
DEPENDENCIES_NEXT=1 bundle pack

Example: running Ruby scripts while dual booting Ruby versions

When running Ruby scripts while dual booting two different Ruby versions, you have to remember to do two things simultaneously for every command:

  • Run the command with the correct version of Ruby
  • Add the DEPENDENCIES_NEXT environment variable to tell bundler to use Gemfile_next.lock

So to run a spec in both versions, the workflow would look like this (assuming chruby for version management):

$ chruby 2.5.7
$ bundle exec rspec spec/some_spec.rb
$ chruby 2.6.5
$ DEPENDENCIES_NEXT=1 bundle exec rspec spec/some_spec.rb

Perhaps more importantly, to update or install a gem, the workflow would look like this:

# This will update Gemfile.lock and Gemfile_next.lock and install the gems
# specified in Gemfile.lock:
$ chruby 2.5.7
$ bundle update some_gem
# This will actually install the gems specified in Gemfile_next.lock under the
# correct Ruby installation:
$ chruby 2.6.5
$ DEPENDENCIES_NEXT=1 bundle install

Configuration (Optional)

By default Bootboot will use the DEPENDENCIES_NEXT environment variable to update your Gemfile_next.lock. You can however configure it. For example, if you want the dualboot to happen when the SHOPIFY_NEXT env variable is present, you simply have to add this in your Gemfile:

# Gemfile
Bundler.settings.set_local('bootboot_env_prefix', 'SHOPIFY')

Keep the Gemfile_next.lock in sync

When a developer bumps or adds a dependency, Bootboot will ensure that the Gemfile_next.lock snapshot gets updated.

However, this feature is only available if you are on Bundler >= 1.17 Other versions will trigger a warning message telling them that Bootboot can't automatically keep the Gemfile_next.lock in sync.

If you use the deployment flag (bundle --deployment) this plugin won't work on Bundler <= 2.0.1. Consider using this workaround in your Gemfile for these versions of Bundler:

plugin 'bootboot', '~> 0.1.2' unless Bundler.settings[:frozen]

bootboot's People

Contributors

ashkulz avatar benjaminwood avatar bogdanvlviv avatar cursedcoder avatar deivid-rodriguez avatar ecbrodie avatar edouard-chin avatar eileencodes avatar gmcgibbon avatar janschill avatar jenshenny avatar larouxn avatar mriddle avatar nvasilevski avatar petergoldstein avatar rafaelfranca avatar rrundzans avatar shopify-rails[bot] avatar systemist avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bootboot's Issues

Can't autosync Gemfile_next.lock when using `bundle lock`

If the Gemfile.lock got updated by someone running bundle lock --update my_gem, bootboot isn't able to update the Gemfile_next.lock because the Bundler after-install-all hook is not triggered by Bundler.

Second problem is that bundle lock doesn't install any gems nor plugins, if a dev doesn't have the bootboot plugin already installed (through a prior bundle install call for example), bootboot won't even get installed.

First issue sounds like something we can fix upstream by triggering a more generic hook like after-gemfile-lock-update whenever a bundler command updates the lockfile.

I'm not too sure what to do about the second issue yet

Resolve dependencies locally instead of fetching them again remotely

When writing the Gemfile_next.lock snapshot, we resolve the dependencies remotely https://github.com/Shopify/bootboot/blob/master/lib/bootboot/gemfile_next_auto_sync.rb#L56
this is unnecessary as all the gems should already have been fetched.

Resolving the dependencies locally with Bundler::Definition#resolve_with_cache https://github.com/bundler/bundler/blob/a63a39d738865665f714f179fe42dd10006da26d/lib/bundler/definition.rb#L148 will speed up the install process

How to workaround bundle install --deployment?

There is a note in the README that bootboot won't work if bundle install --deployment is being used. This is indeed the case on the project I'm working on. I specify bootboot in the Gemfile so that I can upgrade the project from Rails 4 to Rails 5 in a dual-boot fashion, but we use bundle install --deployment in our Dockerfile when deploying our app's Docker image to our production servers.

The original note about bootboot not working with Bundler's deployment flag was originally added without any further context about why (@eileencodes do you have more information about that?). And the note says that it won't work with Bundler versions <= 2.0.1. As of writing, that still encompasses every version of Bundler that exists.

What workarounds exist to allow me to use bundle install --deployment on a project that also uses bootboot?

Unexpected behaviour when auto-syncing Gemfiles

While experimenting with this plugin I ran into a couple of cases that felt a bit unintuitive:

  • Suppose we had an already-existing barebones setup (i.e. Gemfile_next.lock is present) and then we added the following to the Gemfile:

    if ENV['DEPENDENCIES_NEXT']
      gem 'rspec'
    end

    Running bundle install alone won't update Gemfile_next.lock as Gemfile.lock never actually changes. Of course if several gems were added simultaneously and at least one was outside that conditional both files will get updated properly.

  • Running bundle install or bundle update with DEPENDENCIES_NEXT already set won't ever modify Gemfile.lock. There are a few cases where we might set that variable globally (e.g. through a .env file with Docker Compose, etc.) and updating Gemfile.lock would require something like:

    unset DEPENDENCIES_NEXT
    bundle install
    export DEPENDENCIES_NEXT=1

    Aside from the increase in cognitive load, I'm not sure if the intention was to be able to update each lockfile individually. If that's the case I don't think it's possible to update Gemfile.lock by itself as there's no way to skip the auto-sync process when the environment variable isn't set. One possible fix might be to compare the value of DEPENDENCIES_NEXT rather than checking for its presence.


I took a stab at addressing some of this in master...Illianthe:auto-sync but I figure it'd be worth bringing it up for discussion beforehand:

  • Added an env var to skip the auto-sync process (SKIP_BUNDLER_AUTOSYNC)
  • Dropped the nothing_changed? check so that Gemfile_next.lock will be updated even when Gemfile.lock hasn't changed (and vice-versa)
  • Modified the update! logic to preserve existing env vars, allowing calls like DEPENDENCIES_NEXT=1 bundle install to also update Gemfile.lock

This allows for the following combinations:

  • Assuming Gemfile.lock is the default (i.e. using DEPENDENCIES_NEXT)
    • SKIP_BUNDLER_AUTOSYNC=1 bundle install will update Gemfile.lock individually
    • SKIP_BUNDLER_AUTOSYNC=1 DEPENDENCIES_NEXT=1 bundle install will update Gemfile_next.lock individually
    • bundle install and DEPENDENCIES_NEXT=1 bundle install will update both Gemfile.lock and Gemfile_next.lock
  • Assuming Gemfile_next.lock is the default (i.e. using DEPENDENCIES_PREVIOUS)
    • SKIP_BUNDLER_AUTOSYNC=1 bundle install will update Gemfile_next.lock individually
    • SKIP_BUNDLER_AUTOSYNC=1 DEPENDENCIES_PREVIOUS=1 bundle install will update Gemfile.lock individually
    • bundle install and DEPENDENCIES_PREVIOUS=1 bundle install will update both Gemfile.lock and Gemfile_next.lock

allow lockfiles to receive a customized name

We tried to use bootboot for Rails version upgrades and found it limiting to be forced to use the names Gemfile.lock and Gemfile_next.lock.

In our case - we wanted to use something like:

Gemfile.rails61.lock
Gemfile.rails70.lock

so it was easier to understand which lockfile corresponded to which version, more useful git history, etc

Raise an error if Bundler < 1.17 based on Bundler flag

The current behavior is someone is on bundler < 1.17 is to output a warning message.
We could introduce a bundler flag bootboot.raise_on_incompatible_bundler_version which when set will raise an error. The user won't have the choice but to upgrade to bundler 1.17

Document `DEPENDENCIES_NEXT bundle install`

Apologies, I'm trying to work with bootboot for the first time and I'm flailing a bit.

Reading through the documentation and setting up an example repository, I got the impression bootboot would ensure gems were installed, but this seems to not happen. When running bundle install, bootboot indeed keep Gemfile_next.lock in sync, but when I try to run something with DEPENDENCIES_NEXT=1, the gems won't have been installed, necessitating that I run DEPENDENCIES_NEXT=1 bundle install, which seems a bit duplicative.

Do I have this right? Is this necessary? Should it be documented in the README?

Only Gemfile_next.lock Is Getting Updated After Installing BootBoot

After installing BootBoot, when I run bundle update (regardless of whether or not I have DEPENDENCIES_NEXT environment variable set), only the Gemfile_next.lock is being updated, Gemfile.lock is unchanged. This is causing issues on CI when running the current version as it is pulling the older version(s) of gems from the Gemfile.lock. I've noticed that running Bundler.default_lockfile always returns Gemfile_next.lock regardless of whether the DEPENDENCIES_NEXT environment variable is set.

Just wondering what the expected behaviour is - like from the docs, it sounds like bundle update should be updating both lock files. Is there something I'm missing in order to get BootBoot to update both lock files?

Issues with Heroku deployment

Hello, and thank you for this Bundler plugin.

I am trying to deploy a review app to Heroku with this plugin. It seems to install perfectly fine:

-----> Ruby app detected
-----> Installing bundler 2.0.2
-----> Removing BUNDLED WITH version in the Gemfile.lock
-----> Compiling Ruby/Rails
-----> Using Ruby version: ruby-2.6.5
-----> Installing dependencies using bundler 2.0.2
       Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
       Fetching gem metadata from http://rubygems.org/.
       Resolving dependencies...
       Fetching bootboot 0.1.2
       Installing bootboot 0.1.2
       Using bundler 2.0.2
       Installed plugin bootboot
...
       Bundle complete! 180 Gemfile dependencies, 312 gems now installed.
       Gems in the groups development and test were not installed.
       Bundled gems are installed into `./vendor/bundle`
       Post-install message from i18n:

However, my postdeploy script invokes a rake task and raises the following.

bundler: failed to load command: rake (/app/vendor/bundle/ruby/2.6.0/bin/rake)
Bundler::Dsl::DSLError: 
[!] There was an error parsing `Gemfile`: cannot load such file -- /tmp/build_716f2567b68141f1bd17fe9cd59ff266/.bundle/plugin/gems/bootboot-0.1.2/plugins.rb. Bundler cannot continue.
 #  from /app/Gemfile:275
 #  -------------------------------------------
 #  gem "sassc-rails", "2.1.1"
 >  Plugin.send(:load_plugin, "bootboot") if Plugin.installed?("bootboot")
 #  
 #  -------------------------------------------
  /app/vendor/bundle/ruby/2.6.0/gems/bundler-2.0.2/lib/bundler/plugin.rb:273:in `load'
  /app/vendor/bundle/ruby/2.6.0/gems/bundler-2.0.2/lib/bundler/plugin.rb:273:in `load_plugin'
  /app/Gemfile:275:in `eval_gemfile'
  /app/vendor/bundle/ruby/2.6.0/gems/bundler-2.0.2/lib/bundler/dsl.rb:47:in `instance_eval'
  /app/vendor/bundle/ruby/2.6.0/gems/bundler-2.0.2/lib/bundler/dsl.rb:47:in `eval_gemfile'
  /app/vendor/bundle/ruby/2.6.0/gems/bundler-2.0.2/lib/bundler/dsl.rb:12:in `evaluate'
  /app/vendor/bundle/ruby/2.6.0/gems/bundler-2.0.2/lib/bundler/definition.rb:34:in `build'
  /app/vendor/bundle/ruby/2.6.0/gems/bundler-2.0.2/lib/bundler.rb:135:in `definition'
  /app/vendor/bundle/ruby/2.6.0/gems/bundler-2.0.2/lib/bundler.rb:101:in `setup'
  /app/vendor/bundle/ruby/2.6.0/gems/bundler-2.0.2/lib/bundler/setup.rb:20:in `<top (required)>'
  /app/vendor/ruby-2.6.5/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
  /app/vendor/ruby-2.6.5/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'

I'm still researching a solution on my end but was hoping someone else has experienced this? Happy to provide any info necessary.

Thanks!

Bundler plugin index does not update when updating bootboot

Hello,

We recently were trying to update from Bundler v2.2.32 to v2.3.22 and ran into the following error:

NoMethodError: undefined method `to_gem_version_with_patchlevel' for #<Bundler::RubyVersion:0x00007fddb7072988>
  <path-to-project>/.bundle/plugin/gems/bootboot-0.2.0/lib/bootboot/ruby_source.rb:29:in `block in specs'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/index.rb:9:in `build'
  <path-to-project>/.bundle/plugin/gems/bootboot-0.2.0/lib/bootboot/ruby_source.rb:20:in `specs'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/resolver.rb:167:in `index_for'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/resolver.rb:175:in `results_for'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/resolver.rb:127:in `search_for'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/resolver.rb:268:in `block in verify_gemfile_dependencies_are_found!'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/resolver.rb:265:in `map!'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/resolver.rb:265:in `verify_gemfile_dependencies_are_found!'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/resolver.rb:48:in `start'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/definition.rb:290:in `resolve'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/definition.rb:187:in `resolve_remotely!'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/plugin/installer.rb:36:in `install_definition'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/plugin.rb:116:in `block in gemfile_install'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/settings.rb:131:in `temporary'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/plugin.rb:103:in `gemfile_install'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/cli/update.rb:18:in `run'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/cli.rb:305:in `block in update'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/settings.rb:131:in `temporary'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/cli.rb:304:in `update'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/cli.rb:31:in `dispatch'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/cli.rb:25:in `start'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/exe/bundle:48:in `block in <top (required)>'
  <path-to-rbenv>/.rbenv/versions/2.7.3/bin/bundle:23:in `<main>'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/lib/bundler/friendly_errors.rb:120:in `with_friendly_errors'
  <path-to-rbenv>/.rbenv/versions/2.7.3/lib/ruby/gems/2.7.0/gems/bundler-2.3.22/exe/bundle:36:in `<top (required)>'
  <path-to-rbenv>/.rbenv/versions/2.7.3/bin/bundle:23:in `load'

I understand that was related to a change in Bundler version 2.3.12 https://github.com/rubygems/rubygems/blob/master/bundler/CHANGELOG.md#2312-april-20-2022

And I understand this issue was addressed in #40 and fixed in version 0.2.1 of bootboot.

However we found after running cat .bundle/plugin/index and seeing the following

---
commands:
  bootboot: "bootboot"
hooks:
  before-install-all:
  - "bootboot"
  after-install-all:
  - "bootboot"
load_paths:
  bootboot:
  - "<path-to-project>/.bundle/plugin/gems/bootboot-0.2.0/lib"
plugin_paths:
  bootboot: "<path-to-project>/.bundle/plugin/gems/bootboot-0.2.0"
sources:

that it was still pointing to the older version of bootboot.

When we ran bundle plugin uninstall bootboot it was removed from the index, and then when we ran bundle plugin install bootboot it was pointing to the correct 0.2.1 version after that.

Is there anything that we can do in this repository to make sure that index gets updated when a new version is listed in the Gemfile?

plugin 'bootboot', '~> 0.2.1'

I would be happy to attempt the contribution if someone was willing to point me in the right direction.

Thanks for bootboot I think it's a great plugin!

Issues with bundler during vendoring

I am using bootboot to dual boot version of rails.

So bundle pack is installing only to vendor/cache-next only.

Bundle complete! 120 Gemfile dependencies, 623 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
Updating files in vendor/cache-next
# echo $DEPENDENCIES_NEXT
0

why is it not installing vendor/cache. This was my expected behavior. th

Ruby version issues

We have the following in our Gemfile:

ruby ">= 2.7.0", "< 3.1"

When running with bootboot on ruby 2.7.6, we get the following error:

Could not find gem 'Ruby (= 2.7.6)' in Bootboot plugin Ruby source.

The source contains the following gems matching 'Ruby':
  * Ruby-2.7.0

Is there a recommended way to vendor dependencies with bootboot?

I'm trying out bootboot for our next rails upgrade, and from what I can tell bundler is only vendoring one set of dependencies. My goal was to have both sets of dependencies available and managed by bootboot so that our CI and deployments could be toggled with DEPENDENCIES_NEXT and use vendored dependencies for either version.

Am I missing something and this is possible with bootboot? I'm curious if anyone is using bootboot and also vendoring gems.

I tested this out by cloning https://github.com/testdouble/bootboot-example and running

$ bundle install
$ bundle bootboot
$ RAILS_NEXT=1 bundle install
$ bundle pack
$ RAILS_NEXT=1 bundle pack

Thanks!

bootboot forces bundler to contact gem repos?

We package gems to vendor/cache, and check them into our git repository. On deploying to servers, bundle install can normally just use that cache rather than contacting a gem repository. Some of our gems are in a private repository, and the servers don't have credentials for downloading gems directly from them - they can just rely on offline installs from vendor/cache.

It seems like if bootboot is present in the Gemfile, bundle install always tries to re-resolve the lockfile & contacts all gem sources (which then fails due to not having the credentials for our private gem repo).

Here's a tiny sample Gemfile:

source "https://rubygems.org"
gem "thor"
$ bundle config set --local cache_all true; bundle config set --local path vendor/bundle; bundle config set --local cache_path vendor/cache

$ bundle package
Fetching gem metadata from https://rubygems.org/.
Using bundler 2.4.6
Fetching thor 1.2.1
Installing thor 1.2.1
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Bundled gems are installed into `./vendor/bundle`
Updating files in vendor/cache
  * thor-1.2.1.gem

$ bundle install --local --verbose
Running `bundle install --local --verbose` with bundler 2.4.6
Found no changes, using resolution from the lockfile
Using bundler 2.4.6
0:  bundler (2.4.6) from /Users/jon/.gem/ruby/3.1.0/gems/bundler-2.4.6/lib/bundler/source
Using thor 1.2.1
0:  thor (1.2.1) from /Users/jon/Developer/bootboot-test/vendor/bundle/ruby/3.1.0/specifications/thor-1.2.1.gemspec
Updating files in vendor/cache
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Bundled gems are installed into `./vendor/bundle`

The last bundle install mimics what would happen on a deploy, and doesn't make any connection to the internet.


Now if we add bootboot to the Gemfile:

source "https://rubygems.org"
plugin "bootboot", "~> 0.2.1"
gem "thor"
Plugin.send(:load_plugin, 'bootboot') if Plugin.installed?('bootboot')
bash-5.1$ bundle config set --local cache_all true; bundle config set --local path vendor/bundle; bundle config set --local cache_path vendor/cache

bash-5.1$ bundle package
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Using bootboot 0.2.2
Using bundler 2.4.6
Installed plugin bootboot
Fetching gem metadata from https://rubygems.org/.
Using bundler 2.4.6
Fetching thor 1.2.1
Installing thor 1.2.1
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Bundled gems are installed into `./vendor/bundle`
Updating files in vendor/cache
  * thor-1.2.1.gem

bash-5.1$ bundle install --local --verbose
Running `bundle install --local --verbose` with bundler 2.4.6
Found changes from the lockfile, re-resolving dependencies because bundler is unlocking HTTP GET https://index.rubygems.org/versions
HTTP 304 Not Modified https://index.rubygems.org/versions
Fetching gem metadata from https://rubygems.org/
Looking up gems ["bootboot"]
Resolving dependencies...
Using bootboot 0.2.2
Using bundler 2.4.6
Found no changes, using resolution from the lockfile
Using bundler 2.4.6
0:  bundler (2.4.6) from /Users/jon/.gem/ruby/3.1.0/gems/bundler-2.4.6/lib/bundler/source
Using thor 1.2.1
0:  thor (1.2.1) from /Users/jon/Developer/bootboot-test/vendor/bundle/ruby/3.1.0/specifications/thor-1.2.1.gemspec
Updating files in vendor/cache
Bundle complete! 1 Gemfile dependency, 2 gems now installed.
Bundled gems are installed into `./vendor/bundle`

It always reports "Found changes from the lockfile" and tries to contact all gem sources listed in the Gemfile. That's not so bad here where it only needs to contact rubygems.org, but doesn't work so well for us where we're trying to avoid having our private gem repo credentials on the servers.

Is this expected behaviour? Any workarounds I might try, short of just adding our gem credentials to our deployment servers?

Dependabot yml config

I haven't figured it out yet and if someone has, here may be a reasonable place for it to exist.. how someone might manage or configure a .github/dependabot.yml to handle both Gemfile.lock and Gemfile_next.lock?

- package-ecosystem: bundler
  directory: "/"
  schedule:
    interval: daily
    time: "11:00"

xref dependabot/dependabot-core#3266

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.