fix(source): copy symlinks as symlinks, not through them ai:gpt-5.6-sol #84
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
nagonag
nagonag/ignore
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
heiko/gogogo!84
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/deb-source-symlinks"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found while publishing a release with #83's build. The run aborted in source packaging:
Cause
The repository tracks that path as a symlink whose target its own
.gitignoreexcludes — a TSIG key, deliberately kept out of the repo:Nothing looks wrong in the maintainer's working tree, because there the target exists. But gogogo packages from a fresh clone, where the link necessarily dangles.
copyTreedelegated tofsutil.Copy, which begins withos.Stat(src)— that follows the link, fails, and takes the entire release down over a file that was never in the repository to begin with.This is not an exotic layout: a tracked symlink into ignored or generated content is common, and it makes releases fail on the maintainer's machine only after a clone, which is the hardest place to notice.
Fix
copyTreenow recreates symlinks withos.Readlink/os.Symlink, reproducing the target string verbatim.filepath.WalkDirreports the link itself rather than what it points at, so the target is never touched and a missing target is irrelevant.A second, quieter bug goes with it: a symlink that did resolve was silently dereferenced and written as a regular file, so the generated source package no longer matched the tree it claimed to contain — a link became a duplicate copy of its target. Both cases are now preserved faithfully.
os.Removebeforeos.Symlinkkeeps a re-run into a populated destination from failing withEEXIST.Tests
TestCopyTreePreservesSymlinksbuilds the failing shape — one link that resolves, one that dangles — and asserts the copy succeeds, both stay links, the target string is reproduced verbatim, regular files still copy, and the ignored target is not invented in the destination.TestCopyTreeReplacesExistingSymlinkcovers the re-run case.Verification
go build ./...,go test ./...,go vet ./...pass;golangci-lint run --new-from-rev origin/masterreports 0 issues.Verified end-to-end: with this fix the previously failing
gogogo publishgets past source packaging.Independent of #83 — this branch is cut from
master, so the two can land in either order.(authored by ai:gpt-5.6-sol)