Files
fn_registry/functions/infra/resolve_registry_root.go
egutierrez 6aec0413bb feat(infra): auto-commit con 6 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-03 16:16:36 +02:00

62 lines
1.9 KiB
Go

package infra
import (
"fmt"
"os"
"path/filepath"
)
// ResolveRegistryRoot returns the absolute path of the fn_registry root
// (the directory that contains registry.db), or an error if not found.
//
// Resolution order:
// 1. FN_REGISTRY_ROOT env var — if set and <dir>/registry.db exists, return it.
// 2. Walk up from the executable's directory — up to 6 levels; first dir
// that contains registry.db wins. Covers binaries at <root>/fn and at
// <root>/apps/<x>/<bin>.
// 3. $HOME/fn_registry — if <$HOME>/fn_registry/registry.db exists.
// 4. Error — no method found a valid registry root.
func ResolveRegistryRoot() (string, error) {
// 1. Env var
if envDir := os.Getenv("FN_REGISTRY_ROOT"); envDir != "" {
if nonEmptyFile(filepath.Join(envDir, "registry.db")) {
return filepath.Clean(envDir), nil
}
}
// 2. Walk up from executable
if exe, err := os.Executable(); err == nil {
dir := filepath.Dir(exe)
for i := 0; i < 6; i++ {
if nonEmptyFile(filepath.Join(dir, "registry.db")) {
return dir, nil
}
parent := filepath.Dir(dir)
if parent == dir {
// Reached filesystem root
break
}
dir = parent
}
}
// 3. $HOME/fn_registry
if home, err := os.UserHomeDir(); err == nil {
candidate := filepath.Join(home, "fn_registry")
if nonEmptyFile(filepath.Join(candidate, "registry.db")) {
return candidate, nil
}
}
return "", fmt.Errorf("resolve_registry_root: no se encontro registry.db (set FN_REGISTRY_ROOT)")
}
// nonEmptyFile reports whether path is an existing, non-empty regular file.
// A zero-byte registry.db — which sql.Open silently creates when handed a
// mis-resolved path — must NOT count as a valid registry root, otherwise such
// a shadow file would hijack the walk-up and mask the real database.
func nonEmptyFile(path string) bool {
fi, err := os.Stat(path)
return err == nil && fi.Mode().IsRegular() && fi.Size() > 0
}