Go apply writes the shared replace into ./go.work when GOWORK names another file in the same directory, reports success, and the workspace builds unpatched
Maintainer antworten meist innerhalb von 1 Tag
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 1-2 Tage
- Anfängerfreundlichkeit
- 35/100
Rechercherichtung
Read crates/socket-patch-core/src/vendor/go_mod_edit.rs around lines 209 and 273, then trace how ReplaceHost is chosen in vendor/go_workspace.rs and used by go_consumer_sync.rs and patch/redirect/mod.rs. Reproduce with the GOWORK fixture in the issue and check that apply writes to the workspace file Go uses, or refuses without changing files. Confirm apply --check and the member builds reflect the patch; linked PR #1812 is already open.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
[agent] Found by the scheduled Go modules bug-hunt routine (ledger #317).
Summary
Since #1764 (eb75d20), apply run at a go.work root puts the shared module's replace into go.work. It decides that from the workspace go actually uses (GOWORK), but it always writes the file <root>/go.work. When GOWORK names another file in the same directory (for example GOWORK=$PWD/ci.work next to a developer go.work), the replace lands in a file go doesn't read. apply still reports 1 of 1 targeted patch applied and exits 0, re-runs do the same, and every member builds the unpatched module.
apply --check (exit 1, "missing go.mod replace") and vex (not_applied, exit 1) both catch it, so nothing gets attested. But apply's own success report is wrong, and it changes a file the user didn't ask it to change.
If <root>/go.work doesn't exist at all (only ci.work), apply fails with a misleading failed to update go.mod: read ./go.work: No such file or directory.
v5.0.1 and the parent of eb75d20 (86457da) fail closed on the same fixture: apply exits 1 and writes nothing.
Impact
CI setups that pick a workspace file with GOWORK=/abs/path/x.work (a documented go feature, and docs/ecosystems.md says socket-patch honours it) get a green apply and an unpatched build. The stray replace also changes the developer go.work.
Repro (Linux, go 1.24.7, hermetic file GOPROXY, hand-staged .socket/manifest.json and blob as in e2e_golang_workspace_build.rs::write_local_patch)
# ws/ has no go.mod; members ./a and ./b both `require example.com/upstream v1.0.0`
# (lib returns "PRISTINE"; the patch blob makes it return "PATCHED")
cd ws
printf 'go 1.18\n\nuse (\n\t./a\n\t./b\n)\n' > ci.work # the workspace CI uses
printf 'go 1.18\n\nuse ./a\n' > go.work # a developer's go.work
export GOWORK=$PWD/ci.work
socket-patch apply --offline --ecosystems golang
# Summary: 1 of 1 targeted patch applied ... exit 0
grep -l replace go.work ci.work a/go.mod b/go.mod
# go.work <- only the file go isn't reading
(cd a && go run .); (cd b && go run .)
# A: PRISTINE
# B: PRISTINE
socket-patch apply --check --ecosystems golang # exit 1: missing go.mod `replace`
socket-patch apply --offline --ecosystems golang # exit 0 again, still unpatched
Controls: with GOWORK unset, the same go.work replace makes a print PATCHED (which shows go really reads ci.work above). With a root go.mod that is a use member, the mirrored root go.mod replace happens to patch the build, but apply still adds the replace to the unused go.work.
Expected vs actual
- docs/ecosystems.md, "Go workspaces (go.work)": "The
go.workin effect isGOWORKwhen it names an absolute file … Run in the directory holdinggo.work,apply,vendorandscan --mode hostedwrite thereplace… intogo.work." Expected: the replace goes into the file in effect (ci.work), orapplyrefuses. Actual: it goes into./go.work, andapplyreports the patch as applied. - CLI_CONTRACT:
applyexits 0 only when the patches it reports as applied take effect.
OS × version
| OS | go | main ecd4924 |
v5.0.1 / 86457da |
|---|---|---|---|
| Linux | 1.21.13 | fail (exit 0, PRISTINE) | — |
| Linux | 1.24.7 | fail (3 fresh fixtures) | refuses (exit 1, nothing written) |
| Linux | 1.26.8 | fail | — |
| macOS / Windows | — | untested (no probe branch this run) | — |
Untested: vendor and scan --mode hosted (the hosted engine also builds go.work paths itself, see hosted/engine.rs:554), and rollback/remove of a replace sitting in a non-go.work workspace file.
First bad commit
eb75d20 "Write shared Go patch replaces into go.work (#1764)". Its parent 86457da refuses.
Suspect code
crates/socket-patch-core/src/vendor/go_mod_edit.rs:209:let host_path = project_root.join(host.file_name());gives<root>/go.work. The host decision comes from the resolved workspace file (GoWorkspace::rooted_at,vendor/go_workspace.rs:642, which compares only its directory).crates/socket-patch-core/src/vendor/go_workspace.rs:238:ReplaceHost::GoWork => "go.work", also used bygo_consumer_sync.rs:416andpatch/redirect/mod.rs:9464.crates/socket-patch-core/src/vendor/go_mod_edit.rs:273:drop_replace_entryhardcodesproject_root.join("go.work")too.
The host should carry the resolved work_file path, or rooted_at should require the file to be <root>/go.work.
- Vorherrschende Sprache
- Rust
- Sterne
- 8
- Forks
- 2
- Ø Merge
- 19 Std. 12 Min.
- Gemergte PRs (30 T.)
- 709
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus SocketDev/socket-patch
-
agent:triaged arch-audit priority:p3 refactor
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 83/100
SocketDev/socket-patch#1860 ·
Maintainer antworten meist innerhalb von 1 Tag
-
agent:triaged arch-audit priority:p3 refactor
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
SocketDev/socket-patch#1838 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Share one scoped env-var test guard: EnvGuard is copy-pasted 11 times across core unit and integration testsEvtl. vergeben @mikolalysenko hat das heute übernommen. Offenagent:claimed agent:triaged arch-audit priority:p3 refactor
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 55/100
SocketDev/socket-patch#1889 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
Memoize env-keyed subprocess probes through one helper: composer, python and ruby each define the same env key and drifted on when an answer is keptEvtl. vergeben @mikolalysenko hat das heute übernommen. Offenagent:claimed agent:triaged arch-audit priority:p1 refactor
Schwierigkeit 4/5 1-2 Tage Anfängerfreundlichkeit 25/100
SocketDev/socket-patch#1888 · 3 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
agent:triaged arch-audit priority:p3 refactor
Schwierigkeit 4/5 1-2 Tage Anfängerfreundlichkeit 55/100
SocketDev/socket-patch#1887 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in SocketDev/socket-patch
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 85/100
Maintainer antworten meist innerhalb von 1 Tag
-
compiler P4 perf
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 78/100
HerringtonDarkholme/hd-lang#1044 ·
Maintainer antworten meist innerhalb von 1 Tag
-
good first issue help wanted r-docs
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
servo/rust-smallvec#824 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 90/100
akitaonrails/ai-usagebar#552 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100