// Package config provides shared utilities for the fetch_ml project. package config import ( "fmt" "os" "path/filepath" "strings" ) // ExpandPath expands environment variables and tilde in a path func ExpandPath(path string) string { if path == "" { return "" } expanded := os.ExpandEnv(path) if strings.HasPrefix(expanded, "~") { home, err := os.UserHomeDir() if err == nil { expanded = filepath.Join(home, expanded[1:]) } } return expanded } // ResolveConfigPath resolves a config file path, checking multiple locations func ResolveConfigPath(path string) (string, error) { candidates := []string{path} if !filepath.IsAbs(path) { candidates = append(candidates, filepath.Join("configs", path)) } var checked []string for _, candidate := range candidates { resolved := ExpandPath(candidate) checked = append(checked, resolved) if _, err := os.Stat(resolved); err == nil { return resolved, nil } } return "", fmt.Errorf("config file not found (looked in %s)", strings.Join(checked, ", ")) } // JobPaths provides helper methods for job directory paths type JobPaths struct { BasePath string } // NewJobPaths creates a new JobPaths instance func NewJobPaths(basePath string) *JobPaths { return &JobPaths{BasePath: basePath} } // PendingPath returns the path to pending jobs directory func (j *JobPaths) PendingPath() string { return filepath.Join(j.BasePath, "pending") } // RunningPath returns the path to running jobs directory func (j *JobPaths) RunningPath() string { return filepath.Join(j.BasePath, "running") } // FinishedPath returns the path to finished jobs directory func (j *JobPaths) FinishedPath() string { return filepath.Join(j.BasePath, "finished") } // FailedPath returns the path to failed jobs directory func (j *JobPaths) FailedPath() string { return filepath.Join(j.BasePath, "failed") }