package main import ( "io/fs" "log/slog" "os" assets "galo" "galo/internal/config" "galo/internal/db" ) func main() { loadDotEnv(".env") loadDotEnv("../.env") cfg, err := config.Load() if err != nil { slog.Error("config error", "error", err) os.Exit(1) } migFS, err := fs.Sub(assets.Migrations, "migrations") if err != nil { slog.Error("migrations fs", "error", err) os.Exit(1) } if err := db.Migrate(cfg.Postgres.DSN(), migFS); err != nil { slog.Error("migration failed", "error", err) os.Exit(1) } slog.Info("migrations applied") } func loadDotEnv(path string) { data, err := os.ReadFile(path) if err != nil { return } for _, line := range splitLines(string(data)) { if line == "" || line[0] == '#' { continue } for i := 0; i < len(line); i++ { if line[i] == '=' { key := line[:i] val := line[i+1:] if _, exists := os.LookupEnv(key); !exists { _ = os.Setenv(key, val) } break } } } } func splitLines(s string) []string { var out []string start := 0 for i := 0; i < len(s); i++ { if s[i] == '\n' { out = append(out, trim(s[start:i])) start = i + 1 } } out = append(out, trim(s[start:])) return out } func trim(s string) string { start, end := 0, len(s) for start < end && (s[start] == ' ' || s[start] == '\t' || s[start] == '\r') { start++ } for end > start && (s[end-1] == ' ' || s[end-1] == '\t' || s[end-1] == '\r') { end-- } return s[start:end] }