Prompt per stale link during apply
This commit is contained in:
108
main.go
108
main.go
@@ -188,15 +188,7 @@ func applyCmd(args []string) error {
|
||||
}
|
||||
|
||||
fmt.Printf("Stale links found: %d\n", len(stales))
|
||||
ok, err := promptYesNo("Prune them?", false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ok {
|
||||
return removeLinks(stales, false)
|
||||
}
|
||||
|
||||
return nil
|
||||
return handleStaleLinks(stales)
|
||||
}
|
||||
|
||||
func addCmd(args []string) error {
|
||||
@@ -761,6 +753,104 @@ func removeLinks(paths []string, dryRun bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleStaleLinks(stales []string) error {
|
||||
if len(stales) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
repo, err := repoPath()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
for _, path := range stales {
|
||||
fmt.Printf("stale: %s\n", path)
|
||||
fmt.Print("action [p=prune, u=unlink, i=ignore]: ")
|
||||
choice, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
choice = strings.TrimSpace(strings.ToLower(choice))
|
||||
if choice == "" || choice == "i" {
|
||||
continue
|
||||
}
|
||||
if choice == "p" {
|
||||
if err := os.Remove(path); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("removed %s\n", path)
|
||||
continue
|
||||
}
|
||||
if choice == "u" {
|
||||
if err := unlinkStale(path, repo); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
fmt.Println("invalid choice; skipping")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func unlinkStale(targetPath, repo string) error {
|
||||
info, err := os.Lstat(targetPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.Mode()&os.ModeSymlink == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
src, err := os.Readlink(targetPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !filepath.IsAbs(src) {
|
||||
src = filepath.Join(filepath.Dir(targetPath), src)
|
||||
}
|
||||
src = filepath.Clean(src)
|
||||
|
||||
repoAbs, err := filepath.Abs(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rel, err := filepath.Rel(repoAbs, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.HasPrefix(rel, "..") {
|
||||
return nil
|
||||
}
|
||||
|
||||
parts := strings.Split(rel, string(os.PathSeparator))
|
||||
if len(parts) < 3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if parts[1] != filesDirName {
|
||||
return nil
|
||||
}
|
||||
|
||||
repoPath := filepath.Join(repoAbs, rel)
|
||||
if err := os.Remove(targetPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := copyFile(repoPath, targetPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.Remove(repoPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("unlinked %s (removed %s)\n", targetPath, repoPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func restorePackage(filesDir, targetRoot string, dryRun bool) error {
|
||||
filesAbs, err := filepath.Abs(filesDir)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user