<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/lib/bundler/installer, branch master</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>[ruby/rubygems] Fix installing gems with native extensions + transitive dependencies</title>
<updated>2026-04-17T11:28:10+00:00</updated>
<author>
<name>Nick Dower</name>
<email>nicholasdower@gmail.com</email>
</author>
<published>2026-04-11T12:08:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=11e3c78b61da705c783dd12fb7f158c0d256ede0'/>
<id>11e3c78b61da705c783dd12fb7f158c0d256ede0</id>
<content type='text'>
I am seeing the following error during bundle install:

```
Gem::MissingSpecError: Could not find 'ffi' (&gt;= 1.15.5) among 48 total gem(s) (Gem::MissingSpecError)
```

This is reproducible with:

```ruby
source 'https://rubygems.org'

gem 'llhttp-ffi'
```

It seems only direct dependencies are checked when determining whether
a Gem with native extensions is ready to install. I believe this can
lead to a failure if a transitive dependency is not yet installed.

In the example above, llhttp-ffi depends on ffi-compiler, which depends
on ffi.  Since ffi-compiler has no extensions, it is installed
immediately without waiting for ffi. When llhttp-ffi then checks its
direct dependencies, ffi-compiler is already installed, so llhttp-ffi
starts building its native extension. The build requires ffi, which may
not have been installed yet.

https://github.com/ruby/rubygems/commit/a1f5751177
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
I am seeing the following error during bundle install:

```
Gem::MissingSpecError: Could not find 'ffi' (&gt;= 1.15.5) among 48 total gem(s) (Gem::MissingSpecError)
```

This is reproducible with:

```ruby
source 'https://rubygems.org'

gem 'llhttp-ffi'
```

It seems only direct dependencies are checked when determining whether
a Gem with native extensions is ready to install. I believe this can
lead to a failure if a transitive dependency is not yet installed.

In the example above, llhttp-ffi depends on ffi-compiler, which depends
on ffi.  Since ffi-compiler has no extensions, it is installed
immediately without waiting for ffi. When llhttp-ffi then checks its
direct dependencies, ffi-compiler is already installed, so llhttp-ffi
starts building its native extension. The build requires ffi, which may
not have been installed yet.

https://github.com/ruby/rubygems/commit/a1f5751177
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/rubygems] Introduce a priority queue:</title>
<updated>2026-03-16T17:45:29+00:00</updated>
<author>
<name>Edouard CHIN</name>
<email>chin.edouard@gmail.com</email>
</author>
<published>2026-03-12T00:31:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=cfe7565f629387499eb8d09074bed1c01094c6ed'/>
<id>cfe7565f629387499eb8d09074bed1c01094c6ed</id>
<content type='text'>
- ### Problem

  In https://github.com/ruby/rubygems/pull/9381, I explained the
  issue about the "tail latency".

  TL;DR When a gem with a native extensions is downloaded, the sooner
  we starts compiling, the sooner it gets installed.
  If a gem with a native extensions ends up at the end of the queue,
  the longer `bundle install` becomes.

  ### Solution

  I'd like to introduce a simple queue with priority. When a gem is
  downloaded, we check whether that gem has a native extension and
  if its dependencies are installed. If both conditions are met,
  we add the gem in the priority queue to be picked up as quickly
  as possible.

https://github.com/ruby/rubygems/commit/c271257444
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- ### Problem

  In https://github.com/ruby/rubygems/pull/9381, I explained the
  issue about the "tail latency".

  TL;DR When a gem with a native extensions is downloaded, the sooner
  we starts compiling, the sooner it gets installed.
  If a gem with a native extensions ends up at the end of the queue,
  the longer `bundle install` becomes.

  ### Solution

  I'd like to introduce a simple queue with priority. When a gem is
  downloaded, we check whether that gem has a native extension and
  if its dependencies are installed. If both conditions are met,
  we add the gem in the priority queue to be picked up as quickly
  as possible.

https://github.com/ruby/rubygems/commit/c271257444
</pre>
</div>
</content>
</entry>
<entry>
<title>[ruby/rubygems] Split the download and install process of a gem:</title>
<updated>2026-03-12T11:46:30+00:00</updated>
<author>
<name>Edouard CHIN</name>
<email>chin.edouard@gmail.com</email>
</author>
<published>2026-03-10T01:13:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ac3b23778297811cb58508268e1904d45ebbace4'/>
<id>ac3b23778297811cb58508268e1904d45ebbace4</id>
<content type='text'>
- ### Problem

  Bundler awaits for the dependencies of a gem to be download and installed
  before it proceeds to downloading and installing the dependency itself.
  This creates a bottleneck at the end of the installation process and
  block a thread unnecessarily.

  ### Details

  The installation strategy in Bundler is to await for "leaf gems" to
  be download/installed before the "root gem" is processed.

  For instance, in this scenario:

  - Gem "foo" has a dependency on "bar" (We can call this the "root gem")
  - Gem "bar" has no dependency (We call cal this the "leaf gems")
  - A Gemfile adds "gem 'foo'"

  In this case, only a single thread will have work to do, that is
  because Bundler will queue the gem "bar" to be downloaded and
  installed, and only when "bar" is finished, then Bundler will queue
  work for "foo".

  For **pure ruby gems**, this strategy is a waste of time because
  during the installation, a gem's code is not evaluated and no
  "require" statement is evaluated.

  For gems with native extensions, this strategy make sense. When the
  `extconf.rb` of a gem is evaluated, it's possible that the extconf
  requires a dependency and therefore Bundler needs to wait for those
  dependencies to be installed before it can execute the extconf.
  A typical example is a native extension that require 'mini_portile2'.

  ### Solution

  From the explanation above, I'd like to split the download from
  the installation of a gem.

  The tricky aspect is that there is no RubyGems API to know whether
  a gem has a native extension. The only way to know is after we
  download the gem and read the `metadata` from the tarball.

  So the solution in this patch is as follow:

  1. We download all gems without doing any checks.
  2. Once the gems are downloaded, we now know whether a gem has a
     native extensions.
  3. If a gem is a pure ruby gems, we install it without waiting.
  4. If a gem has a native extension, we check whether its dependencies
     are installed. If a dependency is not yet installed, we put back
     the gem in the queue. It will be dequeued later on and we'll redo
     this logic.

  ### Performance gain

  The speed gain highly depends on how deep the dependency tree is.
  E.g. bar depends on foo which depends on baz which depends on jane ...
  Previously we'd proceed to installing gems just one by one and only
  a single thread would be used.

  In a freshly generated Rails application, the speed gain is not that
  important. And the reason is because we are having a "tail latency"
  issue. Around the end of the installation process, the remaining
  gems to be installed are the one with native extensions, since we
  had to wait for for their dependencies to be installed. Compiling
  them is the slowest part, and since we are doing it at the end then
  the speed gain is not that noticeable.

  ### Misc

  Another advantage of this change is to be able to more easily
  implement this kind of feature https://github.com/ruby/rubygems/issues/9138
  to let users solely download gems, without installing them .

https://github.com/ruby/rubygems/commit/e5e8c0a507
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- ### Problem

  Bundler awaits for the dependencies of a gem to be download and installed
  before it proceeds to downloading and installing the dependency itself.
  This creates a bottleneck at the end of the installation process and
  block a thread unnecessarily.

  ### Details

  The installation strategy in Bundler is to await for "leaf gems" to
  be download/installed before the "root gem" is processed.

  For instance, in this scenario:

  - Gem "foo" has a dependency on "bar" (We can call this the "root gem")
  - Gem "bar" has no dependency (We call cal this the "leaf gems")
  - A Gemfile adds "gem 'foo'"

  In this case, only a single thread will have work to do, that is
  because Bundler will queue the gem "bar" to be downloaded and
  installed, and only when "bar" is finished, then Bundler will queue
  work for "foo".

  For **pure ruby gems**, this strategy is a waste of time because
  during the installation, a gem's code is not evaluated and no
  "require" statement is evaluated.

  For gems with native extensions, this strategy make sense. When the
  `extconf.rb` of a gem is evaluated, it's possible that the extconf
  requires a dependency and therefore Bundler needs to wait for those
  dependencies to be installed before it can execute the extconf.
  A typical example is a native extension that require 'mini_portile2'.

  ### Solution

  From the explanation above, I'd like to split the download from
  the installation of a gem.

  The tricky aspect is that there is no RubyGems API to know whether
  a gem has a native extension. The only way to know is after we
  download the gem and read the `metadata` from the tarball.

  So the solution in this patch is as follow:

  1. We download all gems without doing any checks.
  2. Once the gems are downloaded, we now know whether a gem has a
     native extensions.
  3. If a gem is a pure ruby gems, we install it without waiting.
  4. If a gem has a native extension, we check whether its dependencies
     are installed. If a dependency is not yet installed, we put back
     the gem in the queue. It will be dequeued later on and we'll redo
     this logic.

  ### Performance gain

  The speed gain highly depends on how deep the dependency tree is.
  E.g. bar depends on foo which depends on baz which depends on jane ...
  Previously we'd proceed to installing gems just one by one and only
  a single thread would be used.

  In a freshly generated Rails application, the speed gain is not that
  important. And the reason is because we are having a "tail latency"
  issue. Around the end of the installation process, the remaining
  gems to be installed are the one with native extensions, since we
  had to wait for for their dependencies to be installed. Compiling
  them is the slowest part, and since we are doing it at the end then
  the speed gain is not that noticeable.

  ### Misc

  Another advantage of this change is to be able to more easily
  implement this kind of feature https://github.com/ruby/rubygems/issues/9138
  to let users solely download gems, without installing them .

https://github.com/ruby/rubygems/commit/e5e8c0a507
</pre>
</div>
</content>
</entry>
<entry>
<title>[rubygems/rubygems] Complete remembered options removal</title>
<updated>2025-09-11T02:54:49+00:00</updated>
<author>
<name>David Rodríguez</name>
<email>2887858+deivid-rodriguez@users.noreply.github.com</email>
</author>
<published>2025-09-09T12:37:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ecd1284bf246ae739890d154706f4f533bc8d77e'/>
<id>ecd1284bf246ae739890d154706f4f533bc8d77e</id>
<content type='text'>
https://github.com/rubygems/rubygems/commit/573ffad3ea
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/rubygems/rubygems/commit/573ffad3ea
</pre>
</div>
</content>
</entry>
<entry>
<title>[rubygems/rubygems] More aggressive `Performance/FlatMap` cop configuration</title>
<updated>2024-11-26T06:11:05+00:00</updated>
<author>
<name>David Rodríguez</name>
<email>deivid.rodriguez@riseup.net</email>
</author>
<published>2024-11-18T19:51:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4addaaf4df9a7b48c3490b806c195fcb7be999b5'/>
<id>4addaaf4df9a7b48c3490b806c195fcb7be999b5</id>
<content type='text'>
https://github.com/rubygems/rubygems/commit/d8d68cc00e
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/rubygems/rubygems/commit/d8d68cc00e
</pre>
</div>
</content>
</entry>
<entry>
<title>[rubygems/rubygems] Fix `--local` hitting the network when default gems are included</title>
<updated>2024-09-17T05:39:06+00:00</updated>
<author>
<name>David Rodríguez</name>
<email>deivid.rodriguez@riseup.net</email>
</author>
<published>2024-09-12T17:24:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=80e934c29c5bd8b7955e26f8683ac6644d69a200'/>
<id>80e934c29c5bd8b7955e26f8683ac6644d69a200</id>
<content type='text'>
https://github.com/rubygems/rubygems/commit/b9a2d4d539
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/rubygems/rubygems/commit/b9a2d4d539
</pre>
</div>
</content>
</entry>
<entry>
<title>[rubygems/rubygems] Fix gemspec `require_paths` type validation</title>
<updated>2024-07-18T09:25:17+00:00</updated>
<author>
<name>David Rodríguez</name>
<email>deivid.rodriguez@riseup.net</email>
</author>
<published>2024-07-17T20:11:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=86c99a8d14daa15b1b5f6c99697630aa3abb7d5d'/>
<id>86c99a8d14daa15b1b5f6c99697630aa3abb7d5d</id>
<content type='text'>
It was not properly being detected as an Array attribute, and thus not
properly validated.

Fixing this allows us to remove a strange `rescue` clause in Bundler.

https://github.com/rubygems/rubygems/commit/4121a32408
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It was not properly being detected as an Array attribute, and thus not
properly validated.

Fixing this allows us to remove a strange `rescue` clause in Bundler.

https://github.com/rubygems/rubygems/commit/4121a32408
</pre>
</div>
</content>
</entry>
<entry>
<title>[rubygems/rubygems] Improve default gem handling by treating default gems as any other gem</title>
<updated>2024-05-29T13:55:25+00:00</updated>
<author>
<name>David Rodríguez</name>
<email>deivid.rodriguez@riseup.net</email>
</author>
<published>2024-05-20T11:10:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=939d389c549631d84e1603f89850df6aa890ab66'/>
<id>939d389c549631d84e1603f89850df6aa890ab66</id>
<content type='text'>
For backwards compatibility, make sure default gems are still used as a
last resort when materializing, in case no remote, cached, or installed
specs are found.

https://github.com/rubygems/rubygems/commit/93788f689f
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
For backwards compatibility, make sure default gems are still used as a
last resort when materializing, in case no remote, cached, or installed
specs are found.

https://github.com/rubygems/rubygems/commit/93788f689f
</pre>
</div>
</content>
</entry>
<entry>
<title>[rubygems/rubygems] Allow bundle pristine to run in parallel</title>
<updated>2023-12-12T02:10:53+00:00</updated>
<author>
<name>Samuel Giddins</name>
<email>segiddins@segiddins.me</email>
</author>
<published>2023-08-30T22:21:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=e223dde3295cc59415c289305fd8d706d46cd2e9'/>
<id>e223dde3295cc59415c289305fd8d706d46cd2e9</id>
<content type='text'>
Also fix running when BUNDLE_NO_INSTALL happens to be set, same as with install/update commands

https://github.com/rubygems/rubygems/commit/a555fd6ccd
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Also fix running when BUNDLE_NO_INSTALL happens to be set, same as with install/update commands

https://github.com/rubygems/rubygems/commit/a555fd6ccd
</pre>
</div>
</content>
</entry>
<entry>
<title>[rubygems/rubygems] Use modern hashes consistently</title>
<updated>2023-12-07T22:29:33+00:00</updated>
<author>
<name>David Rodríguez</name>
<email>deivid.rodriguez@riseup.net</email>
</author>
<published>2023-12-07T21:10:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=2755cb1b2fbc4a5f08ca56345b5945bd452da74e'/>
<id>2755cb1b2fbc4a5f08ca56345b5945bd452da74e</id>
<content type='text'>
https://github.com/rubygems/rubygems/commit/bb66253f2c
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
https://github.com/rubygems/rubygems/commit/bb66253f2c
</pre>
</div>
</content>
</entry>
</feed>
