diff --git a/cmd/core/pkgcmd/cmd_remove.go b/cmd/core/pkgcmd/cmd_remove.go index 8a45e0f..d901c4e 100644 --- a/cmd/core/pkgcmd/cmd_remove.go +++ b/cmd/core/pkgcmd/cmd_remove.go @@ -10,6 +10,7 @@ package pkgcmd import ( "errors" "fmt" + "os" "os/exec" "path/filepath" "strings" @@ -71,11 +72,11 @@ func runPkgRemove(name string, force bool) error { if !force { blocked, reasons := checkRepoSafety(repoPath) if blocked { - fmt.Printf("%s Cannot remove %s:\n", errorStyle.Render("Blocked:"), repoNameStyle.Render(name)) + fmt.Fprintf(os.Stderr, "%s Cannot remove %s:\n", errorStyle.Render("Blocked:"), repoNameStyle.Render(name)) for _, r := range reasons { - fmt.Printf(" %s %s\n", errorStyle.Render("·"), r) + fmt.Fprintf(os.Stderr, " %s %s\n", errorStyle.Render("·"), r) } - fmt.Printf("\nResolve the issues above or use --force to override.\n") + fmt.Fprintln(os.Stderr, "\nResolve the issues above or use --force to override.") return errors.New("package has unresolved changes") } } diff --git a/cmd/core/pkgcmd/cmd_remove_test.go b/cmd/core/pkgcmd/cmd_remove_test.go index 262b3b9..2c131a3 100644 --- a/cmd/core/pkgcmd/cmd_remove_test.go +++ b/cmd/core/pkgcmd/cmd_remove_test.go @@ -1,8 +1,9 @@ package pkgcmd import ( + "bytes" + "io" "os" - "os/exec" "path/filepath" "strings" "testing" @@ -13,24 +14,52 @@ import ( func setupTestRepo(t *testing.T, dir, name string) string { t.Helper() + repoPath := filepath.Join(dir, name) require.NoError(t, os.MkdirAll(repoPath, 0755)) - cmds := [][]string{ - {"git", "init"}, - {"git", "config", "user.email", "test@test.com"}, - {"git", "config", "user.name", "Test"}, - {"git", "commit", "--allow-empty", "-m", "initial"}, - } - for _, c := range cmds { - cmd := exec.Command(c[0], c[1:]...) - cmd.Dir = repoPath - out, err := cmd.CombinedOutput() - require.NoError(t, err, "cmd %v failed: %s", c, string(out)) - } + gitCommand(t, repoPath, "init") + gitCommand(t, repoPath, "config", "user.email", "test@test.com") + gitCommand(t, repoPath, "config", "user.name", "Test") + gitCommand(t, repoPath, "commit", "--allow-empty", "-m", "initial") + return repoPath } +func capturePkgStreams(t *testing.T, fn func()) (string, string) { + t.Helper() + + oldStdout := os.Stdout + oldStderr := os.Stderr + + rOut, wOut, err := os.Pipe() + require.NoError(t, err) + rErr, wErr, err := os.Pipe() + require.NoError(t, err) + + os.Stdout = wOut + os.Stderr = wErr + + defer func() { + os.Stdout = oldStdout + os.Stderr = oldStderr + }() + + fn() + + require.NoError(t, wOut.Close()) + require.NoError(t, wErr.Close()) + + var stdout bytes.Buffer + var stderr bytes.Buffer + _, err = io.Copy(&stdout, rOut) + require.NoError(t, err) + _, err = io.Copy(&stderr, rErr) + require.NoError(t, err) + + return stdout.String(), stderr.String() +} + func TestCheckRepoSafety_Clean(t *testing.T) { tmp := t.TempDir() repoPath := setupTestRepo(t, tmp, "clean-repo") @@ -56,24 +85,17 @@ func TestCheckRepoSafety_Stash(t *testing.T) { tmp := t.TempDir() repoPath := setupTestRepo(t, tmp, "stash-repo") - // Create a file, add, stash require.NoError(t, os.WriteFile(filepath.Join(repoPath, "stash.txt"), []byte("data"), 0644)) - cmd := exec.Command("git", "add", ".") - cmd.Dir = repoPath - require.NoError(t, cmd.Run()) - - cmd = exec.Command("git", "stash") - cmd.Dir = repoPath - require.NoError(t, cmd.Run()) + gitCommand(t, repoPath, "add", ".") + gitCommand(t, repoPath, "stash") blocked, reasons := checkRepoSafety(repoPath) assert.True(t, blocked) + found := false for _, r := range reasons { - if assert.ObjectsAreEqual("stashed", "") || len(r) > 0 { - if contains(r, "stash") { - found = true - } + if strings.Contains(r, "stash") { + found = true } } assert.True(t, found, "expected stash warning in reasons: %v", reasons) @@ -116,15 +138,37 @@ repos: assert.Contains(t, string(updated), "core-beta") } -func contains(s, substr string) bool { - return len(s) >= len(substr) && (s == substr || len(s) > 0 && containsStr(s, substr)) -} +func TestRunPkgRemove_Bad_BlockedWarningsGoToStderr(t *testing.T) { + tmp := t.TempDir() -func containsStr(s, substr string) bool { - for i := 0; i <= len(s)-len(substr); i++ { - if s[i:i+len(substr)] == substr { - return true - } - } - return false + registry := strings.TrimSpace(` +org: host-uk +base_path: . +repos: + core-alpha: + type: foundation + description: Alpha package +`) + "\n" + require.NoError(t, os.WriteFile(filepath.Join(tmp, "repos.yaml"), []byte(registry), 0644)) + + repoPath := filepath.Join(tmp, "core-alpha") + require.NoError(t, os.MkdirAll(repoPath, 0755)) + gitCommand(t, repoPath, "init") + gitCommand(t, repoPath, "config", "user.email", "test@test.com") + gitCommand(t, repoPath, "config", "user.name", "Test") + commitGitRepo(t, repoPath, "file.txt", "v1\n", "initial") + require.NoError(t, os.WriteFile(filepath.Join(repoPath, "file.txt"), []byte("v2\n"), 0644)) + + withWorkingDir(t, tmp) + + stdout, stderr := capturePkgStreams(t, func() { + err := runPkgRemove("core-alpha", false) + require.Error(t, err) + assert.Contains(t, err.Error(), "unresolved changes") + }) + + assert.Empty(t, stdout) + assert.Contains(t, stderr, "Cannot remove core-alpha") + assert.Contains(t, stderr, "uncommitted changes") + assert.Contains(t, stderr, "Resolve the issues above or use --force to override.") }