diff --git a/internal/cmd/docs/cmd_sync.go b/internal/cmd/docs/cmd_sync.go index 2cbfb4dc..a1611056 100644 --- a/internal/cmd/docs/cmd_sync.go +++ b/internal/cmd/docs/cmd_sync.go @@ -126,8 +126,8 @@ func runDocsSync(registryPath string, outputDir string, dryRun bool) error { outName := packageOutputName(info.Name) repoOutDir := filepath.Join(outputDir, outName) - // Clear existing directory - io.Local.Delete(repoOutDir) // Recursive delete + // Clear existing directory (recursively) + _ = io.Local.DeleteAll(repoOutDir) if err := io.Local.EnsureDir(repoOutDir); err != nil { cli.Print(" %s %s: %s\n", errorStyle.Render("✗"), info.Name, err) diff --git a/internal/cmd/pkgcmd/cmd_install.go b/internal/cmd/pkgcmd/cmd_install.go index d3d0bf55..b5052325 100644 --- a/internal/cmd/pkgcmd/cmd_install.go +++ b/internal/cmd/pkgcmd/cmd_install.go @@ -74,7 +74,7 @@ func runPkgInstall(repoArg, targetDir string, addToRegistry bool) error { repoPath := filepath.Join(targetDir, repoName) - if _, err := coreio.Local.List(filepath.Join(repoPath, ".git")); err == nil { + if coreio.Local.Exists(filepath.Join(repoPath, ".git")) { fmt.Printf("%s %s\n", dimStyle.Render(i18n.Label("skip")), i18n.T("cmd.pkg.install.already_exists", map[string]string{"Name": repoName, "Path": repoPath})) return nil } diff --git a/internal/cmd/pkgcmd/cmd_manage.go b/internal/cmd/pkgcmd/cmd_manage.go index cabba86f..cabcbde1 100644 --- a/internal/cmd/pkgcmd/cmd_manage.go +++ b/internal/cmd/pkgcmd/cmd_manage.go @@ -57,9 +57,8 @@ func runPkgList() error { var installed, missing int for _, r := range allRepos { repoPath := filepath.Join(basePath, r.Name) - exists := false - if _, err := coreio.Local.List(filepath.Join(repoPath, ".git")); err == nil { - exists = true + exists := coreio.Local.Exists(filepath.Join(repoPath, ".git")) + if exists { installed++ } else { missing++ @@ -219,7 +218,7 @@ func runPkgOutdated() error { for _, r := range reg.List() { repoPath := filepath.Join(basePath, r.Name) - if _, err := coreio.Local.List(filepath.Join(repoPath, ".git")); err != nil { + if !coreio.Local.Exists(filepath.Join(repoPath, ".git")) { notInstalled++ continue } diff --git a/internal/cmd/setup/cmd_bootstrap.go b/internal/cmd/setup/cmd_bootstrap.go index a7d354ec..4ea2839c 100644 --- a/internal/cmd/setup/cmd_bootstrap.go +++ b/internal/cmd/setup/cmd_bootstrap.go @@ -105,7 +105,7 @@ func runBootstrap(ctx context.Context, only string, dryRun, all bool, projectNam // Clone core-devops first devopsPath := filepath.Join(targetDir, devopsRepo) - if _, err := coreio.Local.List(filepath.Join(devopsPath, ".git")); err != nil { + if !coreio.Local.Exists(filepath.Join(devopsPath, ".git")) { fmt.Printf("%s %s %s...\n", dimStyle.Render(">>"), i18n.T("common.status.cloning"), devopsRepo) if !dryRun { @@ -148,9 +148,9 @@ func runBootstrap(ctx context.Context, only string, dryRun, all bool, projectNam } // isGitRepoRoot returns true if the directory is a git repository root. +// Handles both regular repos (.git is a directory) and worktrees (.git is a file). func isGitRepoRoot(path string) bool { - _, err := coreio.Local.List(filepath.Join(path, ".git")) - return err == nil + return coreio.Local.Exists(filepath.Join(path, ".git")) } // isDirEmpty returns true if the directory is empty or contains only hidden files. diff --git a/internal/cmd/setup/cmd_registry.go b/internal/cmd/setup/cmd_registry.go index 896a4e63..d9714329 100644 --- a/internal/cmd/setup/cmd_registry.go +++ b/internal/cmd/setup/cmd_registry.go @@ -118,7 +118,7 @@ func runRegistrySetupWithReg(ctx context.Context, reg *repos.Registry, registryP // Check if already exists repoPath := filepath.Join(basePath, repo.Name) // Check .git dir existence via List - if _, err := coreio.Local.List(filepath.Join(repoPath, ".git")); err == nil { + if coreio.Local.Exists(filepath.Join(repoPath, ".git")) { exists++ continue } @@ -147,7 +147,7 @@ func runRegistrySetupWithReg(ctx context.Context, reg *repos.Registry, registryP // Check if already exists repoPath := filepath.Join(basePath, repo.Name) - if _, err := coreio.Local.List(filepath.Join(repoPath, ".git")); err == nil { + if coreio.Local.Exists(filepath.Join(repoPath, ".git")) { exists++ continue } diff --git a/pkg/io/io.go b/pkg/io/io.go index e542872c..1e5020b7 100644 --- a/pkg/io/io.go +++ b/pkg/io/io.go @@ -276,22 +276,32 @@ func (m *MockMedium) Rename(oldPath, newPath string) error { newPrefix += "/" } - // Move files under this directory + // Collect files to move first (don't mutate during iteration) + filesToMove := make(map[string]string) for f, content := range m.Files { if strings.HasPrefix(f, oldPrefix) { newF := newPrefix + strings.TrimPrefix(f, oldPrefix) - m.Files[newF] = content - delete(m.Files, f) + filesToMove[f] = newF + _ = content // content will be copied in next loop } } - // Move subdirectories + for oldF, newF := range filesToMove { + m.Files[newF] = m.Files[oldF] + delete(m.Files, oldF) + } + + // Collect directories to move first + dirsToMove := make(map[string]string) for d := range m.Dirs { if strings.HasPrefix(d, oldPrefix) { newD := newPrefix + strings.TrimPrefix(d, oldPrefix) - m.Dirs[newD] = true - delete(m.Dirs, d) + dirsToMove[d] = newD } } + for oldD, newD := range dirsToMove { + m.Dirs[newD] = true + delete(m.Dirs, oldD) + } return nil } return coreerr.E("io.MockMedium.Rename", "path not found: "+oldPath, os.ErrNotExist)