From 84bd3246b2ee68fd5e42097a208989cddcfc0301 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Tue, 19 Aug 2025 15:21:49 -0300 Subject: [PATCH] feat(fsext): add function to search for something in parent directories --- internal/fsext/parent.go | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 internal/fsext/parent.go diff --git a/internal/fsext/parent.go b/internal/fsext/parent.go new file mode 100644 index 0000000000000000000000000000000000000000..4a9e58cd6d7f208fca4023b2fd8ba70753026ea0 --- /dev/null +++ b/internal/fsext/parent.go @@ -0,0 +1,43 @@ +package fsext + +import ( + "errors" + "os" + "path/filepath" +) + +// SearchParent searches for a target file or directory starting from dir +// and walking up the directory tree until found or root or home is reached. +// Returns the full path to the target if found, empty string and false otherwise. +// The search includes the starting directory itself. +func SearchParent(dir, target string) (string, bool) { + absDir, err := filepath.Abs(dir) + if err != nil { + return "", false + } + + path := filepath.Join(absDir, target) + if _, err := os.Stat(path); err == nil { + return path, true + } else if !errors.Is(err, os.ErrNotExist) { + return "", false + } + + previousParent := absDir + + for { + parent := filepath.Dir(previousParent) + if parent == previousParent || parent == HomeDir() { + return "", false + } + + path := filepath.Join(parent, target) + if _, err := os.Stat(path); err == nil { + return path, true + } else if !errors.Is(err, os.ErrNotExist) { + return "", false + } + + previousParent = parent + } +}