minor changes

This commit is contained in:
Yevhen Odynets
2026-08-31 19:00:09 +03:00
parent 167d98ac9c
commit fedb470da6
16 changed files with 120 additions and 56 deletions
+79 -15
View File
@@ -2,32 +2,43 @@ package sugar
import (
"fmt"
"log"
"log/slog"
"os"
"path/filepath"
"strconv"
)
// EnsureDir joins the given path segments and creates the directory
// (including all parent directories) if it does not already exist.
// Returns the resolved path or an error if creation fails.
func EnsureDir(dirPath ...string) (string, error) {
outPath := filepath.Join(dirPath...)
if len(outPath) < 3 {
return "", fmt.Errorf("the path is short to be a folder: %s", outPath)
if outPath == "" {
return "", fmt.Errorf("path must not be empty")
}
if _, err := os.Stat(outPath); os.IsNotExist(err) {
var dirMod uint64
if dirMod, err = strconv.ParseUint("0775", 8, 32); err == nil {
err = os.Mkdir(outPath, os.FileMode(dirMod))
}
if err != nil && !os.IsExist(err) {
slog.Error("error creating tmp dir", "err", err)
}
if err := os.MkdirAll(outPath, os.FileMode(0775)); err != nil {
return "", fmt.Errorf("failed to ensure directory %q: %w", outPath, err)
}
return outPath, nil
}
// ExecDir returns the directory of the running binary.
// Works correctly even with symlinks and -trimpath builds.
func ExecDir() (string, error) {
exe, err := os.Executable()
if err != nil {
return "", err
}
// EvalSymlinks is critical — os.Executable can return a symlink path
resolved, err := filepath.EvalSymlinks(exe)
if err != nil {
return "", err
}
return filepath.Dir(resolved), nil
}
func WriteDataToTmpFile(content, fp string) (int, string, error) {
dir, err := EnsureDir(os.TempDir(), "mdb")
if err != nil {
@@ -58,6 +69,59 @@ func WriteDataToTmpFile(content, fp string) (int, string, error) {
return filesize, fp, nil
}
/*
REMOVED_FROM_MMT_DUE_TO_REDOING_OF_THE_EVENT_LOG
*/
// ConfigPaths returns candidate directories for config lookup.
// Priority: XDG_CONFIG_HOME → binary dir → CWD → /etc/appname
func ConfigPaths(appName string) []string {
var candidates []string
// 1. Explicit env override (highest priority)
if envPath := os.Getenv("APP_CONFIG_DIR"); envPath != "" {
candidates = append(candidates, envPath)
}
// 2. Relative to binary (best for production deployments)
if exe, err := os.Executable(); err == nil {
if resolved, err := filepath.EvalSymlinks(exe); err == nil {
candidates = append(candidates, filepath.Dir(resolved))
}
}
// 3. CWD (convenient for `go run` and development)
if cwd, err := os.Getwd(); err == nil {
candidates = append(candidates, cwd)
}
// 4. XDG standard (Linux/Unix)
if xdg := os.Getenv("XDG_CONFIG_HOME"); xdg != "" {
candidates = append(candidates, filepath.Join(xdg, appName))
} else if home, err := os.UserHomeDir(); err == nil {
candidates = append(candidates, filepath.Join(home, ".config", appName))
}
// 5. System-wide fallback
candidates = append(candidates, filepath.Join("/etc", appName))
return candidates
}
// FindConfig searches all candidate dirs for the given filename.
func FindConfig(appName, filename string) (string, error) {
for _, dir := range ConfigPaths(appName) {
path := filepath.Join(dir, filename)
if _, err := os.Stat(path); err == nil {
return path, nil
}
}
return "", fmt.Errorf("config %q not found in any candidate directory", filename)
}
// DebugPath Debug helper — remove before production
func DebugPath(path string) {
info, err := os.Stat(path)
log.Printf("path=%q exists=%v err=%v mode=%v", path, err == nil, err, func() string {
if info != nil {
return info.Mode().String()
}
return "n/a"
}())
}