Record `override` directives in Gemfile.lock (an `OVERRIDES` section)
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 35/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- ruby
- Ambito
- build-system, developer-experience
Direzione di ricerca
Start by reading the referenced override changes in #9517 and #9935, then trace LockfileParser, SECTIONS_BY_VERSION_INTRODUCED, and Definition#converge_overrides_outside_dependencies, which the issue names. The proposal leaves syntax and whether to record all overrides open, so first resolve those design questions and inspect existing lockfile tests. Done means overrides are recorded, changes trigger convergence and frozen mode reports them, while existing lockfiles remain unchanged.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
Bundler 4.1's override (#9517, #9935) changes how a bundle resolves, but Gemfile.lock doesn't record it. Each gem's dependency list in the lockfile stays as published, which is a good decision. The catch is that the overrides that explain the result live only in the Gemfile, so the lockfile alone no longer describes the dependency graph Bundler actually loads.
I'd like to propose an additive OVERRIDES section that records the Gemfile's overrides at lock time and leaves spec dependency lists untouched.
The problem
A minimal reproduction with public gems and Bundler 4.1.0.beta2:
source "https://rubygems.org"
gem "rack-test", "2.2.0"
gem "mustermann", "3.0.4"
gem "rack-pure", path: "gems/rack-pure" # any local replacement gem
override "rack", from: "rack-test", to: "rack-pure" # replace one dependency
override "ruby2_keywords", from: "mustermann", to: nil # drop one dependency
bundle lock writes:
GEM
remote: https://rubygems.org/
specs:
mustermann (3.0.4)
ruby2_keywords (~> 0.0.1)
rack-test (2.2.0)
rack (>= 1.3)
with no rack and no ruby2_keywords spec anywhere. Bundler handles this fine because it re-applies the overrides from the Gemfile. Everything else that reads the lockfile sees two dependencies that point at nothing.
1. Lockfile consumers can't tell an override from a broken lockfile. Tools that build from Gemfile.lock without evaluating the Gemfile run into these dangling edges. One concrete case: nixpkgs' bundlerEnv calls getAttrs on every spec's dependency names (pkgs/development/ruby-modules/bundled-common/functions.nix), so evaluation fails with attribute 'rack' missing. Anything else that walks the lockfile graph, such as dependency-graph, SBOM or audit tooling, either errors or reports a graph that isn't what gets loaded. These tools can't evaluate the Gemfile instead: it is arbitrary Ruby, and override lists are often generated in loops.
We worked around this in our Nix build by dropping dependency names that have no spec. That loads the right gems, but it also hides a genuinely incomplete lockfile, because the tool can no longer tell "an override removed this" from "this lockfile is missing a gem."
2. Bundler itself works around the missing record. Definition#converge_overrides_outside_dependencies says:
:alland metadata overrides are intentionally not pre-unlocked. The lockfile does not record overrides, so unlocking for them would re-resolve on every run and reject every frozen install.
If the lockfile recorded overrides, Bundler could compare the Gemfile's overrides with the locked ones, the way it already compares DEPENDENCIES. It would then re-resolve exactly when an override is added, changed or removed, including :all and metadata overrides, and a frozen install could fail with a clear "overrides changed" message instead of skipping the check.
3. Lockfile diffs don't explain themselves. Adding a replacement override removes specs from the lockfile while their dependents still list them. A reviewer reading only the lockfile diff can't see why.
Proposal
Write an OVERRIDES section whenever the Gemfile declares at least one override, one line per override, sorted, in roughly the form Override#to_s already uses:
OVERRIDES
:all (required_ruby_version: ignore_upper)
minitest (required_ruby_version: ignore_upper)
rack (from: rack-test, to: rack-pure)
rack (version: >= 3)
ruby2_keywords (from: mustermann, to: nil)
Properties:
- No change for existing lockfiles. The section appears only when the Gemfile uses
override. - Spec dependency lists stay as published, keeping the decision from #9517 and #9935.
- Backward compatible.
LockfileParseralready skips unknown sections. The section can be registered inSECTIONS_BY_VERSION_INTRODUCED, asCHECKSUMSwas in 2.5.0, so older Bundlers warn throughunknown_sections_in_lockfile. - Converge. If the Gemfile's overrides differ from the locked ones, treat it like a changed dependency: re-resolve normally, and fail in frozen mode with a message naming the override.
- Consumers apply
from:/to:lines to the dependency edges they read, and can use or ignoreversion:and metadata lines.
Open questions:
- Record every override, or only
from:/to:, which are the ones that change the graph's shape? Recording all of them is what makes point 2 possible. - Exact syntax: one line per override as above, or a nested form like
CHECKSUMSandPATH.
Alternatives considered
- Rewrite dependency lists in the lockfile. This loses published metadata, and Bundler couldn't notice when an override is removed, because the lockfile would keep claiming the rewritten edges. That's presumably why #9935 kept published dependencies.
- Consumers evaluate the Gemfile. Not realistic for non-Ruby tooling, and unsafe for tooling that shouldn't run project code.
- Consumers drop dangling names. It works for loading, but it can't tell an override from corruption (see point 1).
Happy to work on a PR if this direction sounds right.
- Lingua principale
- Ruby
- Stelle
- 4k
- Fork
- 1.9k
- Merge medio
- 1g 4h
- PR unite (30g)
- 36
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di ruby/rubygems
-
Uninstalling a gem fails if bin directory doesn't existForse già presa @Nacl-HCl l’ha presa 1 giorno fa. ApertaRubyGems
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
I maintainer di solito rispondono entro 1 giorno
-
`bundle install` exits 0 even when a git gem's submodules fail to cloneForse già presa @mattyb l’ha presa 1 giorno fa. ApertaBundler
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
I maintainer di solito rispondono entro 1 giorno
-
Parallel `bundle install` races on a git cache shared by multiple gems from one repoForse già presa @Shaisolaris l’ha presa 9 giorni fa. ApertaBundler
Difficoltà 4/5 3-5 giorni Idoneità per principianti 58/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
ruby/rubygems#9945 · 2 reazioni ·
I maintainer di solito rispondono entro 1 giorno
-
Bundler
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di ruby/rubygems
Issue simili
-
Bug: Assistant replies lose the space before numbers ("Oct7", "as of10-22-2026") with OpenAI modelsAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
we-promise/sure#4441 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
lugassawan/swe-workbench#823 ·
I maintainer di solito rispondono entro 1 giorno
-
[BUG] Transcription spans omit the requested temperatureForse già presa @yorzi l’ha presa oggi. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
crmne/ruby_llm#1276 · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Admin user page looks up a Tag for every instance-scoped role (`Role#resource_name`)Forse già presa @pkfrank l’ha presa oggi. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
forem/forem#24083 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
rubyjs/mini_racer#449 ·