f2b6c07ff7
Re-run validator after PostLoad, return errors from RootDir, and add Config alias for C(). Hooks receive *T instead of *Manager. Co-authored-by: Cursor <cursoragent@cursor.com>
62 lines
1.3 KiB
Go
62 lines
1.3 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// RootDir walks from the working directory upward, looking for searchName as a
|
|
// regular file. depth limits how many parent directories are checked (0 = CWD only).
|
|
func RootDir(searchName string, depth ...int) (string, error) {
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
depthVal := 0
|
|
if len(depth) > 0 {
|
|
depthVal = depth[0]
|
|
}
|
|
|
|
path, err := walkRootDir(searchName, cwd, depthVal)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if path == "" {
|
|
return "", fmt.Errorf("RootDir checked %d directories, no '%s' file found", depthVal+1, searchName)
|
|
}
|
|
|
|
return filepath.Abs(path)
|
|
}
|
|
|
|
// MustRootDir is like [RootDir] but panics on error.
|
|
func MustRootDir(searchName string, depth ...int) string {
|
|
dir, err := RootDir(searchName, depth...)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return dir
|
|
}
|
|
|
|
func walkRootDir(searchName, path string, reverseDepth int) (string, error) {
|
|
candidate := filepath.Join(path, searchName)
|
|
info, err := os.Stat(candidate)
|
|
if err == nil {
|
|
if info.IsDir() {
|
|
return "", fmt.Errorf("RootDir found directory %q, expected a regular file", candidate)
|
|
}
|
|
return path, nil
|
|
}
|
|
|
|
if reverseDepth > 0 {
|
|
parent := filepath.Dir(path)
|
|
if parent == path {
|
|
return "", nil
|
|
}
|
|
return walkRootDir(searchName, parent, reverseDepth-1)
|
|
}
|
|
|
|
return "", nil
|
|
}
|