Skip to content

feat(storage): apply implicit file:// resolution to all top-level URI helpers#92

Merged
achille-roussel merged 1 commit into
mainfrom
file-paths-on-all-top-level-functions
May 18, 2026
Merged

feat(storage): apply implicit file:// resolution to all top-level URI helpers#92
achille-roussel merged 1 commit into
mainfrom
file-paths-on-all-top-level-functions

Conversation

@achille-roussel

Copy link
Copy Markdown
Contributor

Summary

  • PR feat(storage): treat bare paths as file:// in LoadBucket #91 wired resolveImplicitFileURI into LoadBucket so storage.LoadBucket(ctx, "some-path") would treat a bare path as a file:// URI. The intent was for the same to hold for every top-level URI-taking helper, but the fix was only wired into one entry point — GetObject(ctx, "input.json") still failed with bucket not found.
  • This PR applies resolveImplicitFileURI at the top of every *At helper: HeadObjectAt, GetObjectAt, PutObjectAt, DeleteObjectAt, CopyObjectAt (both sourceURI and destURI), and ListObjectsAt. The non-At wrappers and PutObjectAtWriter inherit the fix transitively.
  • Two TestCopyObject subtests (invalid source URI, invalid dest URI) asserted that the bare string "invalid-uri" should fail; that's exactly the behavior being changed. The remaining bucket not found subtest still covers unknown-scheme rejection.

Why a per-function fix (not deeper)

  • Inside registryFunc.LoadBucket: each *At helper splits the object URI before loading the bucket. For GetObject(ctx, "input.json"), uri.Split returns ("", "", "input.json"), so the call into registry.LoadBucket is already passing "". Resolution at the registry level is too late.
  • Inside uri.Split: would change semantics for every caller (Split("foo") flipping from ("", "", "foo") to ("file", "", "/abs/cwd/foo")). uri.Split is exported and consumed elsewhere; broadening its file-path detection past the existing /, ./, ../, ~ rule is a load-bearing change not worth taking on here.

Test plan

  • go test ./storage/...
  • go test -race ./storage/
  • New TestImplicitFileObjectURIs exercises Put → Head → Get → Copy → List → Delete with bare-path URIs under t.Chdir(t.TempDir()).
  • Existing TestLoadBucketImplicitFile, TestResolveImplicitFileURI, and full TestStorage matrix still pass (no behavior changes for explicit URIs — resolveImplicitFileURI short-circuits on any input containing :).

Downstream

Once this lands, stripes's resolveSourceURI helper (which exists only to work around this asymmetry) becomes redundant and can be removed.

🤖 Generated with Claude Code

… helpers

PR #91 wired resolveImplicitFileURI into LoadBucket but the object-level
helpers (GetObject, HeadObject, PutObject, DeleteObject, CopyObject,
ListObjects, and their *At variants) still called uri.Split directly on
raw inputs, so a bare path like "input.json" failed with "bucket not
found" even though the same input worked for LoadBucket. This change
applies resolveImplicitFileURI at the top of every *At function so all
top-level URI-taking helpers behave uniformly; the non-At wrappers and
PutObjectAtWriter inherit the fix transitively.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@achille-roussel achille-roussel merged commit 37998e8 into main May 18, 2026
3 checks passed
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.

1 participant