Commit Graph
15145 Commits
Author SHA1 Message Date
Kevin Newton 2947aa41d4 [ruby/prism] Use each_line to avoid allocating array
Though very unlikely, it could potentially allocate a large array
of whitespace.

https://github.com/ruby/prism/commit/3389947819
2026-01-26 14:43:01 +00:00
Earlopain 5f25420918 [ruby/prism] Fix on_words_sep for ripper translator with newlines
Ripper emits a token each per line.

https://github.com/ruby/prism/commit/4b5c9f5437
2026-01-26 11:34:49 +00:00
Hiroshi SHIBATA e410d938fa Workround for directly loading Gem::Version 2026-01-26 20:24:14 +09:00
Hiroshi SHIBATA a308311336 [ruby/rubygems] Removed unused deprecate loading
https://github.com/ruby/rubygems/commit/e379022ed0
2026-01-26 09:38:31 +00:00
Edouard CHIN ace5b10de4 [ruby/rubygems] Fix Bundler that re-exec $0 when a version is present in the config:
- ### Problem

  If you have a `version` in your config file (this feature was
  introduced in #6817), then running any `bundle` command will
  make Bundler re-exec and ultimately run the `bundle` binstub twice.

  ### Details

  When the `bundle` binstub gets executed, a `require "bundler"` is
  evaluated. RubyGems tries to require the `bundler.rb` file from
  the right `bundler` gem (in the event where you have multiple
  bundler versions in your system).
  RubyGems will prioritize a bundler version based on a few
  heurisitics.

  https://github.com/ruby/rubygems/blob/b50c40c92abb00bb172f1579356cc73c242b1849/lib/rubygems/bundler_version_finder.rb#L19-L21

  This prioritize logic doesn't take into account the bundler version
  a user has specific in this config. So what happens is:

  1. User execute the `bundle` binstub
  2. `require 'bundler'` is evaluated.
  3. RubyGems prioritize activating the bundler version specified
     in the Gemfile.lock
  4. The CLI starts, and [Auto switch kicks in](https://github.com/ruby/rubygems/blob/b50c40c92abb00bb172f1579356cc73c242b1849/bundler/lib/bundler/cli.rb#L81). Bundler detects that
     user specifed a version in its config and the current Bundler
     version doesn't match.
  5. Bundler exit and re-exec with the right bundler version.

  ### Solution

  This patch introduce two fixes. First, it reads the bundler config
  file and check for the local config first and then the global
  config. This is because the local has precedence over global.

  Second, the prioritization takes into account the version in config
  and let RubyGems activate the right version in order to prevent
  re-exec moments later.

  Finally, I also want to fix this problem because its a step toward
  fixing https://github.com/ruby/rubygems/issues/8106. I'll open
  a follow up patch to explain.

https://github.com/ruby/rubygems/commit/d6e0f43133
2026-01-26 08:48:22 +00:00
Edouard CHIN 78d9b454ce [ruby/rubygems] Fix RubyGems not able to require the right gem:
- Fix https://github.com/ruby/rubygems/issues/9238
- ### Problem

  This is an issue that bites gem maintainers from time to time, with
  the most recent one in https://github.com/minitest/minitest/issues/1040#issuecomment-3679370619

  The issue is summarized as follow:

  1) A gem "X" has a feature in "lib/feature.rb"
  2) Maintainer wants to extract this feature into its own gem "Y"
  3) Maintainer cut a release of X without that new feature.
  4) Users install the new version of X and also install the new
     gem "Y" since the feature is now extracted.
  5) When a call to "require 'feature'" is encountered, RG will
     fail to load the right gem, resulting in a `LoadError`.

  ### Details

  Now that we have two gems (old version of X and new gem Y) with
  the same path, RubyGems will detect that `feature.rb` can be loaded
  from the old version of X, but if the new version of X had already
  been loaded, then RubyGems will raise due to versions conflicting.

  ```ruby
  require 'x' # Loads the new version of X without the feature which was extracted.
  require 'feature' # Rubygems see that the old version of X include that file and tries to activate the spec.
  ```

  ### Solution

  I propose that RubyGems fallback to a spec that's not yet loaded.
  We try to find a spec by its path and filter it out in case a spec
  with the same name has already been loaded.

  Its worth to note that RubyGems already has a
  `find_inactive_by_path` but we can't use it. This method only checks
  if the spec object is active and doesn't look if other spec with the
  same name have been loaded. The new method we are introducing
  verifies this.

https://github.com/ruby/rubygems/commit/f298e2c68e
2026-01-26 05:56:37 +00:00
Earlopain 9269069e90 [ruby/prism] Optimize ripper translator token sorting
With the benchmark from https://github.com/ruby/prism/commit/2ea81398cc6f776dca686125847dbf9b0af58c16
Prism is:
* 1.33x slower before
* 1.07x slower after

https://github.com/ruby/prism/commit/a18b0acd80
2026-01-25 21:14:13 +00:00
Earlopain 985b58a4ed [ruby/prism] Remove unneeded lex_compat token types
These are either fixed in prism or ruby/ripper itself.

https://github.com/ruby/prism/commit/41c7c126b2
2026-01-24 23:11:19 +00:00
Earlopain f7bc28d824 [ruby/prism] Further optimize ripper translator by not using delegate
Using it seems pretty bad for performance:

```rb
require "benchmark/ips"
require "prism"
require "ripper"

codes = Dir["**/*.rb"].map { File.read(it) }

Benchmark.ips do |x|
  x.report("prism") { codes.each { Prism::Translation::Ripper.lex(it) } }
  x.report("ripper") { codes.each { Ripper.lex(it) } }
  x.compare!
end
```

```
# Before
ruby 4.0.0 (2025-12-25 revision https://github.com/ruby/prism/commit/553f1675f3) +PRISM [x86_64-linux]
Warming up --------------------------------------
               prism     1.000 i/100ms
              ripper     1.000 i/100ms
Calculating -------------------------------------
               prism      0.319 (± 0.0%) i/s     (3.14 s/i) -      2.000 in   6.276154s
              ripper      0.647 (± 0.0%) i/s     (1.54 s/i) -      4.000 in   6.182662s

Comparison:
              ripper:        0.6 i/s
               prism:        0.3 i/s - 2.03x  slower
# After
ruby 4.0.0 (2025-12-25 revision https://github.com/ruby/prism/commit/553f1675f3) +PRISM [x86_64-linux]
Warming up --------------------------------------
               prism     1.000 i/100ms
              ripper     1.000 i/100ms
Calculating -------------------------------------
               prism      0.482 (± 0.0%) i/s     (2.08 s/i) -      3.000 in   6.225603s
              ripper      0.645 (± 0.0%) i/s     (1.55 s/i) -      4.000 in   6.205636s

Comparison:
              ripper:        0.6 i/s
               prism:        0.5 i/s - 1.34x  slower
```

`vernier` tells me it does `method_missing` even for explicitly defined methods like `location`.

https://github.com/ruby/prism/commit/2ea81398cc
2026-01-24 23:10:34 +00:00
Hiroshi SHIBATA 13bb5599a4 [ruby/rubygems] Validate executable names for invalid characters
https://github.com/ruby/rubygems/commit/95dabef672
2026-01-23 00:24:03 +00:00
Schneems 7f687b0abc [ruby/syntax_suggest] v2.0.3
https://github.com/ruby/syntax_suggest/commit/a81b92fcf2
2026-01-21 16:01:16 +00:00
Schneems 54fa9c81e1 [ruby/syntax_suggest] Refactor multi-prism version logic
The reason this logic for different methods branches in the class instead of internally was to be eagerly aggressive about runtime performance. This code is currently only used once for the document where it's invoked ~N times (where N is number of lines):

```ruby
module SyntaxSuggest
  class CleanDocument
    # ...
    def join_trailing_slash!
      trailing_groups = @document.select(&:trailing_slash?).map do |code_line|
        take_while_including(code_line.index..) { |x| x.trailing_slash? }
      end
      join_groups(trailing_groups)
      self
    end
```

Since this is not currently a hot-spot I think merging the branches and using a case statement is a reasonable tradeoff and avoids the need to do specific version testing.

An alternative idea was presented in #241 of behavior-based testing for branch logic (which I would prefer), however, calling the code triggered requiring a `DelegateClass` when the `syntax_suggest/api` is being required.

https://github.com/ruby/syntax_suggest/commit/ab122c455f
2026-01-21 15:57:38 +00:00
Earlopain 8aedb89681 [ruby/prism] Also handle BasicObject as a return value
We should touch these as little as possible and just pass them along

https://github.com/ruby/prism/commit/52c4fa785e
2026-01-21 13:21:37 +00:00
Benoit Daloze 913ffcd1dd [ruby/prism] Check using Prism nodes if a command call has any arguments in Ripper translator
* We don't know what `on_*` events might return so we cannot assume it's an Array.
* See https://github.com/ruby/prism/issues/3838#issuecomment-3774702396

https://github.com/ruby/prism/commit/bed4271ce2
2026-01-21 13:21:37 +00:00
Jason Lunn 3aa866ca0d [ruby/rubygems] Remove special behavior for rake
Fixes https://github.com/ruby/rubygems/pull/9244

https://github.com/ruby/rubygems/commit/7dc3d43d2e
2026-01-21 07:40:47 +00:00
Earlopain 9ad8dd00b1 [ruby/prism] Fix on_* return value of ripper translator
You're supposed to return the first argument.
```rb
# Before
[[:stmts_new], [:rescue_mod, nil, nil], [:stmts_add, nil, nil], [:program, nil]]
# After
[[:stmts_new], [:rescue_mod, "1", "2"], [:stmts_add, nil, "1"], [:program, nil]]
```

The correct result would be:
`[[:rescue_mod, "1", "2"], [:stmts_new], [:stmts_add, nil, "1"], [:program, nil]]`

But the order depends on the prism AST so it seems very difficult to match.

https://github.com/ruby/prism/commit/94e0107729
2026-01-20 20:23:18 +00:00
Earlopain 2842e61c92 Reapply "[ruby/prism] Add Ripper :on_sp events for Prism.lex_compat and Prism::Translation::Ripper"
This reverts commit 58f1127b51.
2026-01-20 14:18:30 +01:00
Earlopain 20113a228d Handle on_sp in syntax_suggest when using prism
It used to not emit this token type, but now it does.
So when a newer version of prism is present, we can fall back
to the same code that ripper uses.
2026-01-20 14:18:30 +01:00
Hiroshi SHIBATA 58f1127b51 Revert "[ruby/prism] Add Ripper :on_sp events for Prism.lex_compat and Prism::Translation::Ripper"
This reverts commit 35a7b5159f.

This broke syntax_suggest.

https://github.com/ruby/ruby/actions/runs/21167011751/job/60874111912
2026-01-20 19:10:16 +09:00
Benoit DalozeandEarlopain 35a7b5159f [ruby/prism] Add Ripper :on_sp events for Prism.lex_compat and Prism::Translation::Ripper
* Handle line continuations.
* Handle space at the end of file in LexCompat.

https://github.com/ruby/prism/commit/32bd13eb7d

Co-authored-by: Earlopain <14981592+Earlopain@users.noreply.github.com>
2026-01-20 09:53:08 +00:00
Earlopain 16adb9303f [ruby/prism] Optimize ripper translator
Creating state classes is pretty expensive.
Since they are not modifiable, we can reuse them instead.

Benchmark script:
```rb
require "ripper"
require "prism"
require "benchmark/ips"

codes = Dir["**/*.rb"].map { File.read(it) }

Benchmark.ips do |x|
  x.config(time: 10)
  x.report("prism") { codes.each { Prism::Translation::Ripper.lex(it) } }
  x.report("ripper") { codes.each { Ripper.lex(it) } }

  x.compare!
end
```

Before:

```
ruby 4.0.0 (2025-12-25 revision https://github.com/ruby/prism/commit/553f1675f3) +PRISM [x86_64-linux]
Warming up --------------------------------------
               prism     1.000 i/100ms
              ripper     1.000 i/100ms
Calculating -------------------------------------
               prism      0.293 (± 0.0%) i/s     (3.42 s/i) -      3.000 in  10.248348s
              ripper      0.633 (± 0.0%) i/s     (1.58 s/i) -      7.000 in  11.055687s

Comparison:
              ripper:        0.6 i/s
               prism:        0.3 i/s - 2.16x  slower
```

After

```
ruby 4.0.0 (2025-12-25 revision https://github.com/ruby/prism/commit/553f1675f3) +PRISM [x86_64-linux]
Warming up --------------------------------------
               prism     1.000 i/100ms
              ripper     1.000 i/100ms
Calculating -------------------------------------
               prism      0.486 (± 0.0%) i/s     (2.06 s/i) -      5.000 in  10.280413s
              ripper      0.635 (± 0.0%) i/s     (1.58 s/i) -      7.000 in  11.027169s

Comparison:
              ripper:        0.6 i/s
               prism:        0.5 i/s - 1.31x  slower
```

https://github.com/ruby/prism/commit/bdde16554c
2026-01-19 23:54:39 +00:00
Benoit Daloze 859920dfd2 [ruby/prism] Add Prism::Source#line_to_byte_offset and replace direct accesses to offsets
https://github.com/ruby/prism/commit/ff81a29ba5
2026-01-19 12:03:33 +00:00
Hiroshi SHIBATA df479f41f8 [ruby/rubygems] Added another usage of pristine command
ref. https://github.com/rubygems/guides/issues/388

https://github.com/ruby/rubygems/commit/43f3768f09
2026-01-19 07:14:33 +00:00
Sutou Kouhei fb75e99efe [ruby/rubygems] Add missing .binmode for Gem::AtomicFileWriter
In https://github.com/ruby/rubygems/pull/9202, I commented that `temp_file.binmode` is redundant. But I
was wrong. We need `temp_file.binmode` even when we specify
`File::BINARY`. Sorry.

https://github.com/ruby/rubygems/commit/d9f1f5c6a6
2026-01-19 07:10:42 +00:00
Earlopain d1dc4bdb2f [ruby/prism] Fix ripper translator for __END__
https://github.com/ruby/prism/commit/2792ac78ca
2026-01-18 14:07:06 +00:00
Masafumi Koba 81e06e7004 [ruby/timeout] Improve Timeout.timeout documentation formatting and typos
This commit makes a few minor improvements to the documentation of the `Timeout.timeout` method.
The changes include fixing typos and enhancing formatting for better readability.

We can see the latest version of the documentation here:
https://docs.ruby-lang.org/en/master/Timeout.html#method-c-timeout

Also, we can verify this change locally by running:

```shell
rdoc
open doc/Timeout.html
```

https://github.com/ruby/timeout/commit/53ee559e15
2026-01-17 14:05:07 +00:00
Earlopain 87147ba5e9 [ruby/prism] Make the ripper shim work with rdoc
The filter class is a 1:1 copy of ruby.

rdoc has 32 test failures. It seems to expect `on_sp` in some cases to render code as written.

https://github.com/ruby/prism/commit/74bb12c825
2026-01-16 20:19:26 +00:00
Earlopain 074a23ab77 [ruby/prism] Add Ripper.tokenize to translation layer
It's public API and trivial to implement.

https://github.com/ruby/prism/commit/e77545f8b5
2026-01-16 12:07:41 +00:00
Earlopain 15939e3c30 [ruby/prism] Make irb work with the ripper shim
This is everything that `irb` uses. It works in their test-suite, but there are 20 failures when using the shim that I haven't looked into at all.

`parse` is not used by `irb`. `scan` is, and it's basically `parse` but also including errors. `irb` doesn't seem to care about the errors, so I didn't implement that.

https://github.com/ruby/prism/commit/2c5826b39f
2026-01-15 21:03:55 +00:00
Daisuke Aritomo ca9c61800b Suppress bundled gem warning on `binding.irb'
This patch silences the "this won't work in the next version of Ruby"
warning displayed when irb is autoloaded via `binding.irb`.

    main.rb:1: warning: irb used to be loaded from the standard library, but is not part of the default gems since Ruby 4.0.0.
    You can add irb to your Gemfile or gemspec to fix this error.
    /.../irb.rb:9: warning: reline used to be loaded from the standard library, but is not part of the default gems since Ruby 4.0.0.
    You can add reline to your Gemfile or gemspec to fix this error.

    From: main.rb @ line 1 :

     => 1: binding.irb

    /.../input-method.rb:284: warning: rdoc used to be loaded from the standard library, but is not part of the default gems since Ruby 4.0.0.
    You can add rdoc to your Gemfile or gemspec to fix this error.

This warning is incorrect and misleading: users should not need to
include irb (and its dependencies) to their Gemfiles to use
`binding.irb`, even in future versions of Ruby. It is agreed that the
runtime takes care of that.
2026-01-15 17:20:34 +09:00
Daisuke Aritomo a28c856183 Add comments 2026-01-15 16:16:16 +09:00
Daisuke Aritomo 270c7fcec1 Fake BUNDLE_GEMFILE and BUNDLE_LOCKFILE to let checks pass
Bundler::Runtime#setup requires a real existing lockfile (see
Bundler::SharedHelpers#default_lockfile).
2026-01-15 16:16:16 +09:00
Daisuke Aritomo 943b085949 [Bug #21723] Let binding.irb properly load irb by fixing force_activate()
This patch fixes a problem where `binding.irb` (= force_activate('irb'))
fails under `bundle exec` when the Gemfile does not contain `irb` and
does contain a gem which is (1) not installed in GEM_HOME (2) sourced
using `path:`/`git:`.

The original approach constructing a temporary definition fails since
it does not set the equalivent of `path:`/`git:`.

Always reconstructing a definition from a Gemfile and applying lockfile
constraints should be a more robust approach.

[Bug #21723]
2026-01-15 16:16:16 +09:00
Edouard CHIN b722d37f21 [ruby/rubygems] Add a missing "require 'etc'" statement:
- Ref https://github.com/ruby/rubygems/pull/9171#discussion_r2658056892
- Referencing the constant Etc may raise a `NameError` depending on
  whether other Rubygems/Bundler codepath have evaluated a prior
  "require 'etc'". This can be reproduced with this Gemfile:

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

  gem 'prism', github: "ruby/prism"
  ```

https://github.com/ruby/rubygems/commit/5d435e6863
2026-01-13 11:12:00 +00:00
eileencodes b7dbdfe23a [ruby/rubygems] Refactor atomic file write
This refactoring is based off the changes in
test/rubygems/test_gem_remote_fetcher.rb. It no longer uses tempfile as
a result.

https://github.com/ruby/rubygems/commit/be6fd6550b
2026-01-13 07:12:47 +00:00
Takashi Kokubun ead107f0d7 [ruby/prism] Bump to v1.8.0
https://github.com/ruby/prism/commit/9c12be6e6a
2026-01-13 01:52:48 +00:00
Earlopain ee1aa78bee [ruby/prism] Correctly expose ripper state
It is for example used by `irb`, `rdoc`, `syntax_suggest`

https://github.com/ruby/prism/commit/255aeb2485
2026-01-12 22:08:25 +00:00
Earlopain a1ba9f5733 [ruby/prism] Use one file for versioned parser classes
One per version seems excessive.

Do note that `rubocop-ast` used to require individual parser files. I wouldn't consider that to be part of the API since everything is autoloaded.
From a GitHub code search, I didn't find anyone else doing it like that.

https://github.com/ruby/prism/commit/458f622c34
2026-01-12 16:13:08 +00:00
Earlopain 16863f2ec1 [ruby/prism] Decouple ripper translator from ripper library
Ripper exposes Ripper::Lexer:State in its output, which is a bit of a problem. To make this work, I basically copy-pasted the implementation.

I'm unsure if that is acceptable and added a test to make sure that these values never go out of sync.
I don't imagine them changing often, prism maps them 1:1 for its own usage.

This also fixed the shim by accident. `Ripper.lex` went to `Translation::Ripper.lex` when it should have been the original. Removing the need for the original resolves that issue.

https://github.com/ruby/prism/commit/2c0bea076d
2026-01-08 18:35:26 +00:00
Earlopain fc66de3e6b [ruby/prism] Remove unneeded ripper requires
Ripper is either not used or loaded where it is actually needed

https://github.com/ruby/prism/commit/a73a4fb00c
2026-01-08 18:35:25 +00:00
Earlopain 3bfc86558b [ruby/prism] Move LexRipper into its own file
It has a hard dependency on ripper that can't be removed.
This makes it so that ripper can be loaded only when the class is actually used.

https://github.com/ruby/prism/commit/3b5b4a8a6d
2026-01-08 18:35:25 +00:00
Hiroshi SHIBATA 9580c7d07b Migrate tsort as bundled gems 2026-01-08 18:48:00 +09:00
Chris Hasiński 7688628684 Fix incorrect bundled gems warning for hyphenated gem names
When requiring a file like "benchmark/ips", the warning system would
incorrectly warn about the "benchmark" gem not being a default gem,
even when the user has "benchmark-ips" (a separate third-party gem)
in their Gemfile.

The fix checks if a hyphenated version of the require path exists in
the bundle specs before issuing a warning. For example, requiring
"benchmark/ips" now checks for both "benchmark" and "benchmark-ips"
in the Gemfile.

[Bug #21828]
2026-01-08 13:15:29 +09:00
Takuya Noguchi 3657700c40 [ruby/rubygems] Bundler: validate more options for add sub-command
Signed-off-by: Takuya Noguchi <takninnovationresearch@gmail.com>

https://github.com/ruby/rubygems/commit/6ca2e28680
2026-01-07 08:49:23 +00:00
neimadTL 8846799686 [ruby/rubygems] Update custom errors with Exception#full_message
The use of `Exception#full_message` makes more sense as it shows
the cause and the backstrace.

https://github.com/ruby/rubygems/commit/62a92c3f5e
2026-01-07 07:44:55 +00:00
eileencodes e1087c1226 [ruby/rubygems] Fix dependency source bug in bundler
I stumbled across a bundler bug that had me scratching my head for
awhile, because I hadn't experienced it before.

In some cases when changing the source in a gemfile from a
`Source::Gemspec` to either a `Source::Path` or `Source::Git` only the
parent gem will have it's gem replaced and updated and the child
components will retain the original version. This only happens if the gem
version of the `Source::Gemspec` and `Source::Git` are the same. It also
requires another gem to share a dependency with the one being updated.

For example if I have the following gemfile:

```
gem "rails", "~> 8.1.1"
gem "propshaft"
```

Rails has a component called `actionpack` which `propshaft` depends on.

If I change `rails` to point at a git source (or path source), only the
path for `rails` gets updated:

```
gem "rails", github: "rails/rails", branch: "8-1-stable"
gem "propshaft"
```

Because `actionpack` is a dependency of `propshaft`, it will remain in
the rubygems source in the lock file WHILE the other gems are correctly
pointing to the git source.

Gemfile.lock:

```
GIT
  remote: https://github.com/rails/rails.git
  revision: https://github.com/ruby/rubygems/commit/9439f463e0ef
  branch: 8-1-stable
  specs:
    actioncable (8.1.1)
      ...
    actionmailbox (8.1.1)
      ...
    actionmailer (8.1.1)
      ...
    actiontext (8.1.1)
      ...
    activejob (8.1.1)
      ...
    activemodel (8.1.1)
      ...
    activerecord (8.1.1)
      ...
    activestorage (8.1.1)
      ...
    rails (8.1.1)
      ...
    railties (8.1.1)
      ...

GEM
  remote: https://rubygems.org/
  specs:
    action_text-trix (2.1.15)
      railties
    actionpack (8.1.1) <===== incorrectly left in Rubygems source
      ...
```

The gemfile will contain `actionpack` in the rubygems source, but will
be missing in the git source so the path will be incorrect. A bundle
show on Rails will point to the correct place:

```
$ bundle show rails
/Users/eileencodes/.gem/ruby/3.4.4/bundler/gems/rails-9439f463e0ef
```

but a bundle show on actionpack will be incorrect:

```
$ bundle show actionpack
/Users/eileencodes/.gem/ruby/3.4.4/gems/actionpack-8.1.1
```

This bug requires the following to reproduce:

1) A gem like Rails that contains components that are released as their
own standalone gem is added to the gemfile pointing to rubygems
2) A second gem is added that depends on one of the gems in the first
gem (like propshaft does on actionpack)
3) The Rails gem is updated to use a git source, pointing to the same
version that is being used by rubygems (ie 8.1.1)
4) `bundle` will only update the path for Rails component gems if no
other gem depends on it.

This incorrectly leaves Rails (or any gem like it) using two different
codepaths / gem source code.

https://github.com/ruby/rubygems/commit/dff76ba4f6
2026-01-07 07:30:26 +00:00
Philip Hallstrom b2ed4cdced [ruby/time] Add changelog URI to time.gemspec
https://github.com/ruby/time/commit/08f896ca0d
2026-01-06 23:05:30 +00:00
Schneems ad6b85450d [ruby/rubygems] Retain current bundler version on bundle clean
Previously: In #9218 a reproduction is shared where running `bundle clean` using a binstub (`bin/bundle`) results in bundler removing itself. This results in Ruby falling back to its default bundler version. This behavior seems to be present for as long as there has been a default version of bundler (Ruby 2.6+).

Now: Bundler will explicitly add its current version number to the specs to be preserved. This prevents `bundle clean` from removing the current bundler version.

close https://github.com/ruby/rubygems/pull/9218

https://github.com/ruby/rubygems/commit/e3f0167ae4
2026-01-06 04:38:13 +00:00
Schneems 16bdfa1b2a [ruby/rubygems] Split logic to two lines
https://github.com/ruby/rubygems/commit/5a6eca4cf9
2026-01-06 04:38:12 +00:00
lolwut 3143543f95 [ruby/rubygems] Compare like values in find_bundler
The input to this method is not guaranteed to be a string, it could be a `Gem::Version` this normalizes the comparison.

https://github.com/ruby/rubygems/commit/1f43c7a988
2026-01-06 04:38:12 +00:00