Skip to content

Commit 4d34cc9

Browse files
committed
refactor(gmail): dedupe attachment output/path logic
1 parent 2c34f8f commit 4d34cc9

2 files changed

Lines changed: 28 additions & 44 deletions

File tree

internal/cmd/gmail_attachment.go

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func resolveAttachmentOutPath(outPathFlag string, name string) (string, error) {
4848
// Directory intent:
4949
// - existing directory path
5050
// - or explicit trailing slash for a (possibly non-existent) directory
51-
isDir := strings.HasSuffix(outPathFlag, "/") || strings.HasSuffix(outPathFlag, "\\")
51+
isDir := strings.HasSuffix(outPathFlag, string(os.PathSeparator)) || strings.HasSuffix(outPathFlag, "/") || strings.HasSuffix(outPathFlag, "\\")
5252
if !isDir {
5353
if info, statErr := os.Stat(outPath); statErr == nil && info.IsDir() {
5454
isDir = true
@@ -61,6 +61,16 @@ func resolveAttachmentOutPath(outPathFlag string, name string) (string, error) {
6161
return outPath, nil
6262
}
6363

64+
func printAttachmentDownloadResult(ctx context.Context, u *ui.UI, path string, cached bool, bytes int64) error {
65+
if outfmt.IsJSON(ctx) {
66+
return outfmt.WriteJSON(ctx, os.Stdout, map[string]any{"path": path, "cached": cached, "bytes": bytes})
67+
}
68+
u.Out().Printf("path\t%s", path)
69+
u.Out().Printf("cached\t%t", cached)
70+
u.Out().Printf("bytes\t%d", bytes)
71+
return nil
72+
}
73+
6474
func (c *GmailAttachmentCmd) Run(ctx context.Context, flags *RootFlags) error {
6575
u := ui.FromContext(ctx)
6676
messageID := normalizeGmailMessageID(c.MessageID)
@@ -124,13 +134,7 @@ func (c *GmailAttachmentCmd) Run(ctx context.Context, flags *RootFlags) error {
124134
if dlErr != nil {
125135
return dlErr
126136
}
127-
if outfmt.IsJSON(ctx) {
128-
return outfmt.WriteJSON(ctx, os.Stdout, map[string]any{"path": path, "cached": cached, "bytes": bytes})
129-
}
130-
u.Out().Printf("path\t%s", path)
131-
u.Out().Printf("cached\t%t", cached)
132-
u.Out().Printf("bytes\t%d", bytes)
133-
return nil
137+
return printAttachmentDownloadResult(ctx, u, path, cached, bytes)
134138
}
135139

136140
outPath, err := resolveAttachmentOutPath(outPathFlag, c.Name)
@@ -141,13 +145,7 @@ func (c *GmailAttachmentCmd) Run(ctx context.Context, flags *RootFlags) error {
141145
if err != nil {
142146
return err
143147
}
144-
if outfmt.IsJSON(ctx) {
145-
return outfmt.WriteJSON(ctx, os.Stdout, map[string]any{"path": path, "cached": cached, "bytes": bytes})
146-
}
147-
u.Out().Printf("path\t%s", path)
148-
u.Out().Printf("cached\t%t", cached)
149-
u.Out().Printf("bytes\t%d", bytes)
150-
return nil
148+
return printAttachmentDownloadResult(ctx, u, path, cached, bytes)
151149
}
152150

153151
func downloadAttachmentToPath(

internal/cmd/gmail_attachment_more_test.go

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,13 @@ func TestDownloadAttachmentToPath_DirectoryNotCachedBySize(t *testing.T) {
150150
}
151151
}
152152

153-
func TestGmailAttachmentCmd_DryRun_OutDir_UsesName(t *testing.T) {
154-
outDir := t.TempDir()
153+
func mustDryRunAttachmentPath(t *testing.T, args ...string) string {
154+
t.Helper()
155+
155156
ctx := outfmt.WithMode(context.Background(), outfmt.Mode{JSON: true})
156157

157158
out := captureStdout(t, func() {
158-
err := runKong(t, &GmailAttachmentCmd{}, []string{"m1", "a1", "--out", outDir, "--name", "invoice.pdf"}, ctx, &RootFlags{DryRun: true})
159+
err := runKong(t, &GmailAttachmentCmd{}, args, ctx, &RootFlags{DryRun: true})
159160
var exitErr *ExitError
160161
if !errors.As(err, &exitErr) || exitErr.Code != 0 {
161162
t.Fatalf("expected exit code 0, got: %v", err)
@@ -174,40 +175,25 @@ func TestGmailAttachmentCmd_DryRun_OutDir_UsesName(t *testing.T) {
174175
if !ok {
175176
t.Fatalf("expected request.path string, got=%T", req["path"])
176177
}
178+
return path
179+
}
180+
181+
func TestGmailAttachmentCmd_DryRun_OutDir_UsesName(t *testing.T) {
182+
outDir := t.TempDir()
183+
got := mustDryRunAttachmentPath(t, "m1", "a1", "--out", outDir, "--name", "invoice.pdf")
177184
want := filepath.Join(outDir, "invoice.pdf")
178-
if path != want {
179-
t.Fatalf("unexpected path: got=%q want=%q", path, want)
185+
if got != want {
186+
t.Fatalf("unexpected path: got=%q want=%q", got, want)
180187
}
181188
}
182189

183190
func TestGmailAttachmentCmd_DryRun_OutDirTrailingSlash_UsesNameEvenIfMissing(t *testing.T) {
184191
base := t.TempDir()
185192
outDir := filepath.Join(base, "newdir") + string(os.PathSeparator)
186-
ctx := outfmt.WithMode(context.Background(), outfmt.Mode{JSON: true})
187-
188-
out := captureStdout(t, func() {
189-
err := runKong(t, &GmailAttachmentCmd{}, []string{"m1", "a1", "--out", outDir, "--name", "invoice.pdf"}, ctx, &RootFlags{DryRun: true})
190-
var exitErr *ExitError
191-
if !errors.As(err, &exitErr) || exitErr.Code != 0 {
192-
t.Fatalf("expected exit code 0, got: %v", err)
193-
}
194-
})
195-
196-
var got map[string]any
197-
if err := json.Unmarshal([]byte(out), &got); err != nil {
198-
t.Fatalf("unmarshal: %v\noutput=%q", err, out)
199-
}
200-
req, ok := got["request"].(map[string]any)
201-
if !ok {
202-
t.Fatalf("expected request object, got=%T", got["request"])
203-
}
204-
path, ok := req["path"].(string)
205-
if !ok {
206-
t.Fatalf("expected request.path string, got=%T", req["path"])
207-
}
193+
got := mustDryRunAttachmentPath(t, "m1", "a1", "--out", outDir, "--name", "invoice.pdf")
208194
want := filepath.Join(filepath.Join(base, "newdir"), "invoice.pdf")
209-
if path != want {
210-
t.Fatalf("unexpected path: got=%q want=%q", path, want)
195+
if got != want {
196+
t.Fatalf("unexpected path: got=%q want=%q", got, want)
211197
}
212198
}
213199

0 commit comments

Comments
 (0)