From 4e58a2a0b99344fe1a62970e2a2438c89348b977 Mon Sep 17 00:00:00 2001 From: 12 <153109197+LittleYier@users.noreply.github.com> Date: Thu, 24 Sep 2026 07:10:01 +0900 Subject: [PATCH] Fix export overwrite confirmation on EOF (#1342) --- Sources/tart/Commands/Export.swift | 2 +- integration-tests/export_darwin_test.go | 60 +++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 integration-tests/export_darwin_test.go diff --git a/Sources/tart/Commands/Export.swift b/Sources/tart/Commands/Export.swift index 7d0c3d2..5e0bb21 100644 --- a/Sources/tart/Commands/Export.swift +++ b/Sources/tart/Commands/Export.swift @@ -37,7 +37,7 @@ struct Export: AsyncParsableCommand { func userWantsOverwrite(_ filename: String) -> Bool { print("file \(filename) already exists, are you sure you want to overwrite it? (yes, [no])? ", terminator: "") - let answer = readLine()! + let answer = readLine() return answer == "yes" } diff --git a/integration-tests/export_darwin_test.go b/integration-tests/export_darwin_test.go new file mode 100644 index 0000000..5cf4205 --- /dev/null +++ b/integration-tests/export_darwin_test.go @@ -0,0 +1,60 @@ +package integration_test + +import ( + "bytes" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func TestExportOverwriteConfirmation(t *testing.T) { + for _, tt := range []struct { + name string + input string + overwrite bool + }{ + {name: "EOF"}, + {name: "empty line", input: "\n"}, + {name: "no", input: "no\n"}, + {name: "yes", input: "yes\n", overwrite: true}, + } { + t.Run(tt.name, func(t *testing.T) { + home := t.TempDir() + t.Setenv("TART_HOME", home) + t.Setenv("TART_NO_AUTO_PRUNE", "1") + createSyntheticVM(t, home, "source", "92:81:b5:ab:39:37") + + directory := t.TempDir() + destination := filepath.Join(directory, "source.tvm") + original := []byte("existing archive") + if err := os.WriteFile(destination, original, 0600); err != nil { + t.Fatal(err) + } + + cmd := exec.CommandContext(t.Context(), "tart", "export", "source") + cmd.Dir = directory + cmd.Stdin = strings.NewReader(tt.input) + output, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("export: %v: %s", err, output) + } + if !strings.Contains(string(output), "are you sure you want to overwrite it?") { + t.Fatalf("expected overwrite confirmation: %s", output) + } + if strings.Contains(string(output), "exporting...") != tt.overwrite { + t.Fatalf("unexpected export behavior: %s", output) + } + + current, err := os.ReadFile(destination) + if err != nil { + t.Fatal(err) + } + changed := !bytes.Equal(original, current) + if changed != tt.overwrite { + t.Fatalf("destination changed = %t, want %t", changed, tt.overwrite) + } + }) + } +}