Skip to content

Commit

Permalink
Add Bundler 2.4 to documentation
Browse files Browse the repository at this point in the history
Including release blog post and What's new page.
  • Loading branch information
deivid-rodriguez committed Dec 25, 2022
1 parent 039f8c3 commit 711ea77
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 2 deletions.
4 changes: 2 additions & 2 deletions helpers/config_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ def versions_grouped_by_status
private

def status(version)
if version == "v2.3"
if version == "v2.4"
"Current release"
elsif %w[v2.2 v2.1].include?(version)
elsif %w[v2.3 v2.2 v2.1].include?(version)
"Legacy release"
else
"Deprecated release"
Expand Down
170 changes: 170 additions & 0 deletions source/blog/2022-12-25-bundler-v2-4.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
---
title: "Bundler v2.4: new resolver, gems with Rust extensions, and more"
date: 2022-12-25 15:10 UTC
tags:
author: David Rodríguez
author_url: https://github.com/deivid-rodriguez
category: release
---

2022 has been a busy year for the Bundler team, and we're glad to present
several improvements that we hope will make our users happy :)

## A better, PubGrub based, resolver

Bundler now uses the most advanced algorithm to resolve versions, PubGrub.
Kudos to Natalie Weizenbaum for [inventing
it](https://nex3.medium.com/pubgrub-2fb6470504f) and to John Hawthorn for
[porting it to Ruby](https://github.com/jhawthorn/pub_grub)!

Our previous resolver, [Molinillo](https://github.com/CocoaPods/Molinillo), worked pretty well, but it really got in the
middle when it didn't.

This may sound familiar for some:

~~~
$ bundle
Fetching gem metadata from https://rubygems.org/............
Resolving dependencies....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................^C
$ # Ok, that was enough waiting
~~~

Our new resolver, PubGrub, is usually much faster, because it learns from the
resolution conflicts it finds during the resolution process to avoid redoing the
same work over and over again. You can find more about this "conflict-driven
clause learning" techniques in its [presentation blog
post](https://nex3.medium.com/pubgrub-2fb6470504f) back from 2018.

Molinillo sometimes took too long to resolve because it would try the same
things, backtrack, and run into the same conflicts over and over again, having
to traverse very inefficiently a huge search space. But that was a relatively
rare case in the real world.

What's probably more common is specifying version requirements in your Gemfile,
that can't be all satisfied at the same time. This is when the version solving
problem does not have a solution, and when it becomes crucial to explain to users
_why_, so that they can fix their set of version requirements to become
solvable.

Molinillo run into trouble here, and in cases with many moving parts, like
upgrading Rails for example, it could end up printing a lot of conflicts, not
easy to understand and solve. This is an old example from a public ticket:

~~~
Bundler could not find compatible versions for gem "actionpack":
In Gemfile:
inherited_resources (= 1.6.0) was resolved to 1.6.0, which depends on
actionpack (>= 3.2, < 5)
rails (= 4.2.0) was resolved to 4.2.0, which depends on
actionpack (= 4.2.0)
Bundler could not find compatible versions for gem "activesupport":
In Gemfile:
inherited_resources (= 1.6.0) was resolved to 1.6.0, which depends on
has_scope (~> 0.6.0.rc) was resolved to 0.6.0, which depends on
activesupport (>= 3.2, < 5)
rails (= 4.2.0) was resolved to 4.2.0, which depends on
activesupport (= 4.2.0)
Bundler could not find compatible versions for gem "railties":
In Gemfile:
inherited_resources (= 1.6.0) was resolved to 1.6.0, which depends on
railties (>= 3.2, < 5)
rails (= 4.2.0) was resolved to 4.2.0, which depends on
railties (= 4.2.0)
inherited_resources (= 1.6.0) was resolved to 1.6.0, which depends on
responders was resolved to 1.1.2, which depends on
railties (>= 3.2, < 4.2)
~~~

Not easy to know what to do about it.

With PubGrub, you should now get human-readable explanations of failures. The
most complex cases may are still, well... complex. But explanations should
always make sense and point to the root cause of resolution failures.

Here's an example from our test suite:

~~~
Because every version of c depends on a < 1
and every version of b depends on a >= 2,
every version of c is incompatible with b >= 0.
So, because Gemfile depends on b >= 0
and Gemfile depends on c >= 0,
version solving has failed.
~~~

We tried to make this migration as backwards-compatible as possible, but
there's a chance of experiencing some different solutions to the ones found by
Molinillo, since the version solving problem does not have unique solutions.
Please report any issues you find with the new resolver.


### Easily generate gems with Rust extensions using `bundle gem`

It's now easier than ever to get started using Rust inside your gems. Check out
[this blog post](rust-gem-skeleton.html) to learn how to generate a gem with all
the boilerplate necessary with just a few commands.

### Faster git sources

In the Bundler world, it's common to point to git repositories when there's
no version released to rubygems.org that includes the changes that you need.
This works fine, but it can get slow and use a lot of disk space when dealing
with very big repositories.

We have improved the way we clone these repositories to be faster and use less
disk space. For example, something like

```ruby
gem "rails", github: "rails/rails"
```

in your Gemfile could previously take ~30s and use up to 1Gb of disk space,
because we would clone the full Rails repository, which has a large history.

Now we just clone what's strictly necessary for Bundler to work, resulting in
big disk space savings, and much faster bundling.

### New CLI features

We added a few small CLI features, such as,

* `bundle lock --update --bundler`, to update your locked version of Bundler
without installing any gems.
* A new `--pre` flag to `bundle update` and `bundle lock` to explicitly opt-in
to prereleases of selected (of all) gems without having to explictly change
your Gemfile with pre-release requirements such as `>= 7.1.0.beta`.

### Some minor breaking changes

We took new year's release to move on and get rid of some stuff that was causing
maintenance burden for us:

* Ruby 2.3, 2.4, and 2.5 are no longer supported.
* RubyGems 2.5, 2.6, and 2.7 are no longer supported.

In general, this support drop should not break anything because RubyGems should
be able to choose the latest supported Bundler on the Ruby version that you're
using. But there are still some old RubyGems out there that don't have this
feature, and the `gem install bundler` command could break there. We have
warned using Bundler on those old rubies for a year now, so we believe it's time
to move on.

We also completely removed a controversial (mis-)feature from the Bundler code
base, where Bundler would automatically acquire sudo permissions when not having
the proper access rights. A great majority of users considered this feature harmful and
hardly useful, so we decided to get rid of it.

### And bug fixes

As always, we continue to smooth the experience of using Bundler, so that it
gets the job done and does not get in the middle other than that. And we're also
shipping a bunch of bug fixes to keep moving towards that goal.

That's all from the Bundler team. Have a happy new year, and enjoy using Bundler
2.4! 🎉
36 changes: 36 additions & 0 deletions source/v2.4/docs.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
- primary_commands = %w(bundle-install.1 bundle-update.1 bundle-cache.1 bundle-exec.1 bundle-config.1 bundle-help.1)

.bg-light-blue.header
= image_tag '/images/docs_header_transparent_bg.png',
srcset: '/images/docs_header_transparent_bg.png 1x, /images/[email protected] 2x, /images/[email protected] 3x',
class: 'img-fluid header-padding',
style: 'max-width: 400px;'

.container
.row.docs.my-5
.col-md-6.col-12
%h3
%b Guides
%p
Step-by-step tutorials that include useful explanations and and detailed instructions to help you get up and running.
%ul.ul-padding
- guides.each do |guide|
%li= link_to_guide guide
%li= link_to "Contributing to Bundler", "/doc/readme.html"

.col-md-5.offset-md-1.col-12
%h3
%b Reference Guides
%p
In-depth articles with information on each primary command and utility, and how to use them.
%h4
%b Primary Commands
%ul.ul-padding
- primary_commands.select{ |page| path_exist?(page) }.each do |page|
%li= link_to_documentation(page)

%h4
%b Utilities
%ul.ul-padding
- other_commands(primary_commands).each do |page|
%li= link_to_documentation(page)
64 changes: 64 additions & 0 deletions source/v2.4/whats_new.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.container.guide
%h1
What's New in
= current_visible_version

%p
The
= link_to 'Bundler 2.4 announcement', '/blog/2022/12/22/bundler-v2-4.html'
includes context and a more detailed explanation of the changes in this version. This is a summary of the biggest changes. As always, a detailed list of every change is provided in
#{link_to "the changelog", "https://github.com/rubygems/rubygems/blob/3.4/bundler/CHANGELOG.md"}.

%h3 A new PubGrub based resolver
.contents
.bullet
.description
%p
Bundler now uses
= link_to "pub_grub", "https://github.com/jhawthorn/pub_grub"
under the hood to resolve versions. The most advance algorithm to
approach the version solving problem! 💪

%h3 Generate gems with Rust extensions
.contents
.bullet
.description
%p
<code>bundle gem</code> now supports Rust! Pass the
<code>--ext=rust</code> flag to generate a gem with a Rust extension.

%h3 Faster git sources in Gemfile
.contents
.bullet
.description
%p
Git sources in Gemfile now work faster and use less disk space.

%h3 Old Ruby and RubyGems no longer supported
.contents
.bullet
.description
%p
Support for Ruby 2.3, 2.4, and 2.5, and RubyGems 2.5, 2.6, and 2.7 has
been dropped

%h3 No more auto-sudo
.contents
.bullet
.description
%p
Bundler no longer tries to use <code>sudo</code> to upgrade privileges
under any circumstances.

%h3 Other improvements
.contents
.bullet
.description
%p
Bundler 2.4 also includes other improvements like the <code>bundle
lock --update --bundler</code> command to update the locked version of
Bundler without having to install gems or the <code>--pre</code> flag
to <code>bundle lock</code> and <code>bundle update</code> to
explicitly opt-in to prereleases.

= link_to 'Full 2.4 changelog', 'https://github.com/rubygems/rubygems/blob/3.4/bundler/CHANGELOG.md', class: 'btn btn-primary'

0 comments on commit 711ea77

Please sign in to comment.