Hide unlink option when repo file missing
This commit is contained in:
115
main.go
115
main.go
@@ -835,7 +835,18 @@ func handleStaleLinks(stales []string) error {
|
|||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
for _, path := range stales {
|
for _, path := range stales {
|
||||||
fmt.Printf("stale: %s\n", path)
|
fmt.Printf("stale: %s\n", path)
|
||||||
fmt.Print("action [p=prune, u=unlink, i=ignore]: ")
|
|
||||||
|
canUnlink, err := staleHasRepoFile(path, repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt := "action [p=prune, u=unlink, i=ignore]: "
|
||||||
|
if !canUnlink {
|
||||||
|
prompt = "action [p=prune, i=ignore]: "
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print(prompt)
|
||||||
choice, err := reader.ReadString('\n')
|
choice, err := reader.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -851,7 +862,7 @@ func handleStaleLinks(stales []string) error {
|
|||||||
fmt.Printf("removed %s\n", path)
|
fmt.Printf("removed %s\n", path)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if choice == "u" {
|
if choice == "u" && canUnlink {
|
||||||
if err := unlinkStale(path, repo); err != nil {
|
if err := unlinkStale(path, repo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -863,55 +874,29 @@ func handleStaleLinks(stales []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func unlinkStale(targetPath, repo string) error {
|
func staleHasRepoFile(targetPath, repo string) (bool, error) {
|
||||||
info, err := os.Lstat(targetPath)
|
repoPath, err := repoPathForTarget(targetPath, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
if info.Mode()&os.ModeSymlink == 0 {
|
if repoPath == "" {
|
||||||
return nil
|
return false, 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.Stat(repoPath); errors.Is(err, os.ErrNotExist) {
|
if _, err := os.Stat(repoPath); errors.Is(err, os.ErrNotExist) {
|
||||||
if err := os.Remove(targetPath); err != nil {
|
return false, nil
|
||||||
|
} else if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func unlinkStale(targetPath, repo string) error {
|
||||||
|
repoPath, err := repoPathForTarget(targetPath, repo)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Printf("removed %s (missing repo file)\n", targetPath)
|
if repoPath == "" {
|
||||||
return nil
|
return nil
|
||||||
} else if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Remove(targetPath); err != nil {
|
if err := os.Remove(targetPath); err != nil {
|
||||||
@@ -930,6 +915,48 @@ func unlinkStale(targetPath, repo string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func repoPathForTarget(targetPath, repo string) (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
|
||||||
|
}
|
||||||
|
|
||||||
|
return filepath.Join(repoAbs, rel), nil
|
||||||
|
}
|
||||||
|
|
||||||
func restorePackage(filesDir, targetRoot string, dryRun bool) error {
|
func restorePackage(filesDir, targetRoot string, dryRun bool) error {
|
||||||
filesAbs, err := filepath.Abs(filesDir)
|
filesAbs, err := filepath.Abs(filesDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user