aboutsummaryrefslogtreecommitdiff
path: root/internal/cli/storage.go
diff options
context:
space:
mode:
authortsne <tsne.dev@outlook.com>2026-07-06 16:52:20 +0200
committertsne <tsne.dev@outlook.com>2026-07-06 21:37:42 +0200
commit84da43998f7cc42cc72652333ac6e3d293abb23e (patch)
tree6610f82df854ae86f7f34152bb05fc712ef6f314 /internal/cli/storage.go
downloadhopper-84da43998f7cc42cc72652333ac6e3d293abb23e.tar.gz
initialHEADmain
Diffstat (limited to 'internal/cli/storage.go')
-rw-r--r--internal/cli/storage.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/internal/cli/storage.go b/internal/cli/storage.go
new file mode 100644
index 0000000..654ed85
--- /dev/null
+++ b/internal/cli/storage.go
@@ -0,0 +1,46 @@
+package cli
+
+import (
+ "context"
+
+ "tsne.dev/hopper/internal/bunny"
+)
+
+// storageAPI is the full storage surface the dry-run decorator delegates to.
+// Its read side (List) must stay real even under --dry-run; its
+// write side (Upload/Delete) is what the decorator stubs. The real
+// *bunny.Client satisfies this, as does the recording fake used in tests.
+type storageAPI interface {
+ Upload(ctx context.Context, path string, body []byte) error
+ List(ctx context.Context, dir string) *bunny.Iterator
+ Delete(ctx context.Context, path string) error
+ DeleteDir(ctx context.Context, path string) error
+}
+
+func newStorageAPI(endpoint, zone, accessKey string) storageAPI {
+ var api storageAPI = bunny.NewAPI(endpoint, zone, accessKey)
+ if dryRun {
+ api = dryRunStorageAPI{api}
+ }
+ return api
+}
+
+type dryRunStorageAPI struct {
+ upstream storageAPI
+}
+
+func (api dryRunStorageAPI) List(ctx context.Context, dir string) *bunny.Iterator {
+ return api.upstream.List(ctx, dir)
+}
+
+func (api dryRunStorageAPI) Upload(ctx context.Context, path string, body []byte) error {
+ return nil
+}
+
+func (api dryRunStorageAPI) Delete(ctx context.Context, path string) error {
+ return nil
+}
+
+func (api dryRunStorageAPI) DeleteDir(ctx context.Context, path string) error {
+ return nil
+}