80 lines
2.4 KiB
Go
80 lines
2.4 KiB
Go
package utils
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
logger "git.site.quack-lab.dev/dave/cylogger"
|
|
)
|
|
|
|
// pathLogger is a scoped logger for the utils/path package.
|
|
var pathLogger = logger.Default.WithPrefix("utils/path")
|
|
|
|
// ResolvePath resolves a path to an absolute path, handling ~ expansion and cleaning
|
|
func ResolvePath(path string) string {
|
|
resolvePathLogger := pathLogger.WithPrefix("ResolvePath").WithField("inputPath", path)
|
|
resolvePathLogger.Trace("Resolving path: %q", path)
|
|
|
|
// Handle empty path
|
|
if path == "" {
|
|
resolvePathLogger.Trace("Empty path, returning empty string")
|
|
return ""
|
|
}
|
|
|
|
// Check if path is absolute
|
|
if filepath.IsAbs(path) {
|
|
resolvePathLogger.Trace("Path is already absolute: %q", path)
|
|
cleaned := filepath.ToSlash(filepath.Clean(path))
|
|
resolvePathLogger.Trace("Cleaned absolute path: %q", cleaned)
|
|
return cleaned
|
|
}
|
|
|
|
// Handle ~ expansion
|
|
if strings.HasPrefix(path, "~") {
|
|
homeDir, _ := os.UserHomeDir()
|
|
if strings.HasPrefix(path, "~/") || strings.HasPrefix(path, "~\\") {
|
|
path = filepath.Join(homeDir, path[2:])
|
|
} else if path == "~" {
|
|
path = homeDir
|
|
} else {
|
|
// ~something (like ~~), treat first ~ as home expansion, rest as literal
|
|
path = homeDir + path[1:]
|
|
}
|
|
resolvePathLogger.Trace("Expanded ~ to home directory: %q", path)
|
|
}
|
|
|
|
// Make absolute if not already
|
|
if !filepath.IsAbs(path) {
|
|
absPath, err := filepath.Abs(path)
|
|
if err != nil {
|
|
resolvePathLogger.Error("Failed to get absolute path: %v", err)
|
|
return filepath.ToSlash(filepath.Clean(path))
|
|
}
|
|
resolvePathLogger.Trace("Made path absolute: %q -> %q", path, absPath)
|
|
path = absPath
|
|
}
|
|
|
|
// Clean the path and normalize to forward slashes for consistency
|
|
cleaned := filepath.ToSlash(filepath.Clean(path))
|
|
resolvePathLogger.Trace("Final cleaned path: %q", cleaned)
|
|
return cleaned
|
|
}
|
|
|
|
// GetRelativePath returns the relative path from base to target
|
|
func GetRelativePath(base, target string) (string, error) {
|
|
getRelativePathLogger := pathLogger.WithPrefix("GetRelativePath")
|
|
getRelativePathLogger.Debug("Getting relative path from %q to %q", base, target)
|
|
|
|
relPath, err := filepath.Rel(base, target)
|
|
if err != nil {
|
|
getRelativePathLogger.Error("Failed to get relative path: %v", err)
|
|
return "", err
|
|
}
|
|
|
|
// Use forward slashes for consistency
|
|
relPath = filepath.ToSlash(relPath)
|
|
getRelativePathLogger.Debug("Relative path: %q", relPath)
|
|
return relPath, nil
|
|
}
|