For this PR I am introducing a new option: --latest. Similar yarn upgrade-interactive --latest, it relaxes Gemfile version requirements to allow gems to be updated to their latest versions. This feature was originally requested in #13.
Normally update-interactive only makes changes to your Gemfile.lock. It honors the version restrictions ("pins") in your Gemfile and will not update your Gemfile.lock to have versions that are not allowed. However with the --latest flag, update-interactive can update the version pins in your Gemfile as well. Consider the following Gemfile:
gem "rails", "~> 7.1.0"
Normally running bundle update-interactive will report that Rails is held back and therefore cannot be updated to the latest version. However, if you pass the --latest option like this:
bundle update-interactive --latest
Now Rails will be allowed to update. If you select to update Rails to the latest version (e.g. 7.2.0), update-interactive will modify the version requirement in your Gemfile to look like this:
Next, I created a Latest::Updater subclass of Updater that tweaks that logic for allowing latest versions. It does this by wrapping the core logic with a GemfileEditor that modifies the Gemfile to relax its version requirements prior to bundle lock --update and bundle update being called.
Once bundle update completes, I modify the Gemfile once more to "shift" the version requirements to match the updated versions. E.g. ~> 7.1.0 becomes ~> 7.2.0.
I put the latest logic, GemfileEditor, etc. code all into a Latest module, to prevent its complexity from leaking into other parts of the codebase. The only time this code is referenced outside the module is a 1-liner in the CLI based on the --latest flag:
Although there is a lot of code in this PR, most of it comes from the --update-gemfile feature that I previously built and tested in my bundleup project here: https://github.com/mattbrictson/bundleup/pull/87 .
For this PR I am introducing a new option:
--latest
. Similaryarn upgrade-interactive --latest
, it relaxes Gemfile version requirements to allow gems to be updated to their latest versions. This feature was originally requested in #13.Normally
update-interactive
only makes changes to your Gemfile.lock. It honors the version restrictions ("pins") in your Gemfile and will not update your Gemfile.lock to have versions that are not allowed. However with the--latest
flag, update-interactive can update the version pins in your Gemfile as well. Consider the following Gemfile:Normally running
bundle update-interactive
will report that Rails is held back and therefore cannot be updated to the latest version. However, if you pass the--latest
option like this:Now Rails will be allowed to update. If you select to update Rails to the latest version (e.g. 7.2.0),
update-interactive
will modify the version requirement in your Gemfile to look like this:In terms of implementation, this PR makes a refactor to introduce an
Updater
class. I consolidated the core of the reporting and bundle-updating logic in this single class. See https://github.com/mattbrictson/bundle_update_interactive/pull/42/commits/65197475517676917591bf91a81077a03966a643 for details.Next, I created a
Latest::Updater
subclass ofUpdater
that tweaks that logic for allowing latest versions. It does this by wrapping the core logic with aGemfileEditor
that modifies the Gemfile to relax its version requirements prior tobundle lock --update
andbundle update
being called.Once
bundle update
completes, I modify the Gemfile once more to "shift" the version requirements to match the updated versions. E.g.~> 7.1.0
becomes~> 7.2.0
.I put the latest logic,
GemfileEditor
, etc. code all into aLatest
module, to prevent its complexity from leaking into other parts of the codebase. The only time this code is referenced outside the module is a 1-liner in the CLI based on the--latest
flag:Although there is a lot of code in this PR, most of it comes from the
--update-gemfile
feature that I previously built and tested in mybundleup
project here: https://github.com/mattbrictson/bundleup/pull/87 .