package config import ( "fmt" "os" "path/filepath" ) // RootDir checks the current working directory and its parent directories for // a given filename and returns the absolute path to the directory. If the file // is not found within the specified depth or any other error occurs, it will // panic. If depth is zero or negative, RootDir checks the current directory only. func RootDir(searchName string, depth ...int) string { // Get the current working directory cwd, err := os.Getwd() if err != nil { panic(err) } // Apply default depth if not provided depthVal := 0 if len(depth) > 0 { depthVal = depth[0] } // Walk directories up to the specified depth to find the file path := walkRootDir(searchName, cwd, depthVal) if path == "" { panic(fmt.Errorf("RootDir checked %d directories, no '%s' file found", depthVal+1, searchName)) } // Try to get the absolute path of the found directory abs, err := filepath.Abs(path) if err != nil || abs == "" { panic(fmt.Errorf("RootDir failed to get absolute path: %v", err)) } return abs } // walkRootDir recursively checks directories up to the specified reverseDepth. func walkRootDir(searchName, path string, reverseDepth int) string { if _, err := os.Stat(filepath.Join(path, searchName)); err == nil { return path } if reverseDepth > 0 { return walkRootDir(searchName, path+"/..", reverseDepth-1) } return "" }