1package fsext
2
3import (
4 "errors"
5 "os"
6 "path/filepath"
7)
8
9// SearchParent searches for a target file or directory starting from dir
10// and walking up the directory tree until found or root or home is reached.
11// Returns the full path to the target if found, empty string and false otherwise.
12// The search includes the starting directory itself.
13func SearchParent(dir, target string) (string, bool) {
14 absDir, err := filepath.Abs(dir)
15 if err != nil {
16 return "", false
17 }
18
19 path := filepath.Join(absDir, target)
20 if _, err := os.Stat(path); err == nil {
21 return path, true
22 } else if !errors.Is(err, os.ErrNotExist) {
23 return "", false
24 }
25
26 previousParent := absDir
27
28 for {
29 parent := filepath.Dir(previousParent)
30 if parent == previousParent || parent == HomeDir() {
31 return "", false
32 }
33
34 path := filepath.Join(parent, target)
35 if _, err := os.Stat(path); err == nil {
36 return path, true
37 } else if !errors.Is(err, os.ErrNotExist) {
38 return "", false
39 }
40
41 previousParent = parent
42 }
43}