Skip to content

Conversation

@eileencodes
Copy link
Member

@eileencodes eileencodes commented Dec 19, 2025

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: 9439f463e0ef974c447edcc1b17882f072e99d22
  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.

What was the end-user or developer problem that led to this PR?

What is your fix for the problem, implemented in this PR?

Make sure the following tasks are checked

@eileencodes eileencodes force-pushed the fix-dependency-source-bug branch from 8071235 to 4336836 Compare December 19, 2025 19:40
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: 9439f463e0ef974c447edcc1b17882f072e99d22
  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.
@hsbt
Copy link
Member

hsbt commented Dec 23, 2025

/cc @zzak This PR may resolve your issue too.

@hsbt
Copy link
Member

hsbt commented Dec 23, 2025

I will look this after releasing Ruby 4.0. Sorry to not merge this for Bundler 4.0.3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants