Skip to content

fs: replace Copy's == backend comparison with a SameBackend interface - #180

Merged
srerickson merged 1 commit into
mainfrom
claude/github-issue-174-b6u0mq
Aug 26, 2026
Merged

fs: replace Copy's == backend comparison with a SameBackend interface#180
srerickson merged 1 commit into
mainfrom
claude/github-issue-174-b6u0mq

Conversation

@srerickson

Copy link
Copy Markdown
Owner

Stacked on #179.

Summary

fs.Copy compared dstFS == srcFS to decide whether to use a CopyFS's server-side Copy method. That produced false negatives (two distinct *BucketFS values over the same bucket/client never matched) and could panic outright when both values shared a non-comparable dynamic type.

  • Add an optional SameBackend interface FS implementations can use to report backend identity, and have Copy consult it on dstFS instead of comparing interface values directly.
  • Implement SameBackend for s3.BucketFS: bucket name plus a reflect-guarded client comparison, so a non-comparable client can't reproduce the panic one level down.
  • Implement SameBackend for local.FS as a one-liner (same absolute root path).

Fixes #174 (and settles #125, per that issue's note: whichever design wins between them, one issue closes).

Test plan

  • fs/fs_test.go (new): Copy dispatch tests — same-backend, different-backend, no-SameBackend, and a reproduction of the original panic with a non-comparable dynamic type.
  • fs/s3/fs_test.go: TestSameBackend_Mock (including the non-comparable-client guard) and TestCopyDispatch_Mock, which asserts the s3 fast path via mock.Calls() (one CopyObject, zero GetObject/PutObject).
  • go build ./..., go vet ./..., go test ./... -count=5 -race all pass.

Generated by Claude Code

Base automatically changed from claude/github-issue-173-walk-nil-deref to main August 26, 2026 13:32
fs.Copy compared dstFS == srcFS to decide whether to use a CopyFS's
server-side Copy method. That produced false negatives (two distinct
*BucketFS values over the same bucket/client never matched) and could
panic outright when both values shared a non-comparable dynamic type.

Add an optional SameBackend interface FS implementations can use to
report backend identity, and have Copy consult it on dstFS instead of
comparing interface values directly. Implement it for s3.BucketFS
(bucket name plus a reflect-guarded client comparison, so a
non-comparable client can't reproduce the panic one level down) and,
as a one-line bonus, for local.FS (same absolute root path).

Fixes #174
@srerickson
srerickson force-pushed the claude/github-issue-174-b6u0mq branch from 5a78ea0 to d8c84e6 Compare August 26, 2026 13:37
@srerickson
srerickson merged commit b396682 into main Aug 26, 2026
1 check passed
@srerickson
srerickson deleted the claude/github-issue-174-b6u0mq branch August 26, 2026 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fs: Copy decides "same backend" by comparing interface values

2 participants