Hosted gem `rollback` / `remove` strips the `DEPENDENCIES` `!` of a gem the user declared inside a `source "https://rubygems.org" do` block, so every frozen install fails after the unwind
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 80/100
Línea de trabajo
Empieza en crates/socket-patch-core/src/patch/redirect/upstream/gem.rs, alrededor de la línea 354. La llamada strip_suffix('!') necesita una condición de protección: elimina ! solo cuando el Gemfile restaurado ya no declara la gema dentro de un bloque source (o con una opción source:/git:/path:). Comprueba cómo se rastrea el contexto del Gemfile original durante el unwind. Ejecuta la suite de pruebas del proyecto y verifica con los pasos de reproducción del issue que una instalación congelada se completa correctamente después del rollback.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
[agent] Found by the scheduled Bundler (RubyGems) bug-hunt routine (ledger #316).
Summary
Bundler marks a dependency declared inside a source … do block with ! in the lock's DEPENDENCIES (colorize (= 0.8.1)!), even when that block's source is rubygems.org. The hosted scan of such a gem works: it nests the patch-registry block inside the user's block, and the fresh frozen install gets the patched bytes. The unwind (rollback, or remove <purl>) then restores the Gemfile byte for byte, so the declaration is back inside the user's source "https://rubygems.org" do block. But the unwind always drops the ! from the lock's DEPENDENCIES line. The restored pair no longer matches what Bundler writes, so BUNDLE_FROZEN=true bundle install fails with exit 16 ("Your lockfile needs to be updated, but it can't be because frozen mode is set"). rollback still reports success with hosted.reverted: [pkg:gem/[email protected]].
Impact
After undoing a patch, every CI or deployment (frozen) install of the project breaks until someone runs an unfrozen bundle install and commits the lock. The unwind is supposed to give back the original, installable pair.
Repro (Linux, Ruby 3.3.6, Bundler 4.0.22 or 2.6.9 with bundle lock --add-checksums)
Patch API and patch registry mocked on loopback (the run-13 mock from ledger #316); rubygems.org is the real upstream.
mkdir app && cd app
printf 'source "https://rubygems.org"\n\ngem "rake"\nsource "https://rubygems.org" do\n gem "colorize", "0.8.1"\nend\n' > Gemfile
bundle lock && cp Gemfile.lock /tmp/orig.lock # DEPENDENCIES: colorize (= 0.8.1)!
socket-patch scan --mode hosted --yes --api-url $MOCK --org org --api-token fake
BUNDLE_FROZEN=true BUNDLE_PATH=vb bundle install # exit 0, patched bytes (OK)
socket-patch rollback --api-url $MOCK --org org --api-token fake --patch-server-url $MOCK
diff /tmp/orig.lock Gemfile.lock
# < colorize (= 0.8.1)!
# ---
# > colorize (= 0.8.1)
git diff Gemfile # empty: the Gemfile came back exactly
BUNDLE_FROZEN=true BUNDLE_PATH=vb2 bundle install # exit 16
socket-patch remove pkg:gem/[email protected] leaves the same diff, and a frozen install then fails with exit 16 too.
Expected vs actual
- Expected: CLI_CONTRACT.md's "Hosted unwind coverage" gem row says the unwind undoes the
source "<patch registry>" do … endblock and "the pair comes back". The!should only be dropped when the restored declaration no longer sits in a usersourceblock (the case where hosted mode added it). Here the declaration's own block still pins the source, so the original!must stay, and the lock should come back byte-identical to the pre-scan one. - Actual: the
!is always removed (the row says "theDEPENDENCIESpin loses its!" without exception), which leaves a pair that Bundler's frozen mode rejects.
Matrix
| OS | Ruby | Bundler | Shape | Result |
|---|---|---|---|---|
| Linux | 3.3.6 | 4.0.22 | top-level source + source "https://rubygems.org" do gem … end |
reproduces (×2) |
| Linux | 3.3.6 | 4.0.22 | every gem inside one source "https://rubygems.org" do block |
reproduces |
| Linux | 3.3.6 | 4.0.22 | source … do + nested group :default do |
reproduces |
| Linux | 3.3.6 | 2.6.9 (CHECKSUMS added) | every gem inside one source block |
reproduces |
| Linux | 3.3.6 | 4.0.22 | remove <purl> instead of rollback |
reproduces |
| Linux | 3.3.6 | 4.0.22 | plain top-level declaration (control) | pass (lock byte-restored) |
macOS and Windows weren't probed. The lock surgery is OS-independent.
First bad version
Not bisected. This is current main d47eab3; the v5 upstream restore introduced the hosted unwind.
Suspect code
crates/socket-patch-core/src/patch/redirect/upstream/gem.rs:354: for a non-transitive gem, entry.strip_suffix('!') unconditionally rewrites the DEPENDENCIES line to the unpinned form. It doesn't check whether the restored Gemfile still declares the gem inside a source … do block (or with a source: / git: / path: option), and in that case Bundler keeps the !.
- Lenguaje dominante
- Rust
- Estrellas
- 8
- Forks
- 0
- Merge medio
- 19 h 21 min
- PR fusionados (30 d)
- 421
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de SocketDev/socket-patch
-
agent:triaged bug bughunt pm:npm priority:p3
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
SocketDev/socket-patch#1072 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
agent:triaged bug bughunt pm:bundler priority:p1
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
SocketDev/socket-patch#896 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
agent:triaged bug bughunt pm:yarn-berry priority:p1
Dificultad 2/5 1-3 horas Aptitud para principiantes 73/100
SocketDev/socket-patch#783 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
agent:triaged bug bughunt pm:cargo priority:p2
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
SocketDev/socket-patch#651 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
agent:triaged bug bughunt pm:uv priority:p1
Dificultad 4/5 3-5 días Aptitud para principiantes 28/100
SocketDev/socket-patch#1374 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de SocketDev/socket-patch
Issues similares
-
[Bug]: Web chat input doesn't regain focus after a reply finishesPosiblemente ocupada @GaijinSystems la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
zeroclaw-labs/zeroclaw#11658 ·
Los mantenedores suelen responder en 2 días
-
good first issue help wanted
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
-
documentation
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
NuSkooler/enigma-bbs#907 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día