From 1e9874a4827c2154a74b9abd8886c2d76ed69a01 Mon Sep 17 00:00:00 2001 From: mkelvers Date: Tue, 26 May 2026 15:38:14 +0200 Subject: [PATCH] refactor: migrate env-var reads to config package --- cmd/user/main.go | 8 +++++++- integrations/jikan/client.go | 10 ++++++---- internal/app/app.go | 2 ++ internal/db/sqlite.go | 9 --------- internal/episodes/module.go | 9 +++------ internal/playback/module.go | 7 +++---- internal/server/cors.go | 7 +++++-- internal/server/server.go | 17 ++++++++--------- 8 files changed, 34 insertions(+), 35 deletions(-) diff --git a/cmd/user/main.go b/cmd/user/main.go index 475e1ef..3307802 100644 --- a/cmd/user/main.go +++ b/cmd/user/main.go @@ -11,12 +11,18 @@ import ( "github.com/google/uuid" "golang.org/x/crypto/bcrypt" + "mal/internal/config" "mal/internal/database" "mal/internal/db" ) func main() { - dbConn, err := db.Open(db.GetDBFile()) + cfg, err := config.Load() + if err != nil { + log.Fatalf("load config: %v", err) + } + + dbConn, err := db.Open(cfg.DatabaseFile) if err != nil { log.Fatalf("failed to open db: %v", err) } diff --git a/integrations/jikan/client.go b/integrations/jikan/client.go index b670b4d..57204d9 100644 --- a/integrations/jikan/client.go +++ b/integrations/jikan/client.go @@ -7,19 +7,21 @@ import ( "fmt" "net" "net/http" - "os" "reflect" "strconv" "strings" "sync" "time" + "mal/internal/config" "mal/internal/db" "mal/internal/observability" "golang.org/x/sync/singleflight" ) +var traceEnabled bool + type Client struct { httpClient *http.Client baseURL string @@ -39,7 +41,8 @@ type Client struct { const jikanSlowLogThreshold = 750 * time.Millisecond -func NewClient(queries *db.Queries, metrics *observability.Metrics) *Client { +func NewClient(cfg config.Config, queries *db.Queries, metrics *observability.Metrics) *Client { + traceEnabled = cfg.JikanTrace return &Client{ httpClient: &http.Client{ Timeout: 10 * time.Second, @@ -142,8 +145,7 @@ func waitForRetry(ctx context.Context, delay time.Duration) error { } func jikanTraceEnabled() bool { - value := strings.ToLower(strings.TrimSpace(os.Getenv("MAL_JIKAN_TRACE"))) - return value == "1" || value == "true" || value == "yes" + return traceEnabled } func logJikanCache(cacheKey string, source string, startedAt time.Time, err error) { diff --git a/internal/app/app.go b/internal/app/app.go index 733b1c9..de2783c 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -5,6 +5,7 @@ import ( "mal/integrations/playback/allanime" "mal/internal/anime" "mal/internal/auth" + "mal/internal/config" "mal/internal/database" "mal/internal/episodes" "mal/internal/playback" @@ -19,6 +20,7 @@ import ( func NewApp() *fx.App { return fx.New( + config.Module, database.Module, jikan.Module, allanime.Module, diff --git a/internal/db/sqlite.go b/internal/db/sqlite.go index 3031c28..4c68d5a 100644 --- a/internal/db/sqlite.go +++ b/internal/db/sqlite.go @@ -3,7 +3,6 @@ package db import ( "database/sql" "fmt" - "os" // sqlite3 driver. _ "github.com/mattn/go-sqlite3" @@ -17,11 +16,3 @@ func Open(dbFile string) (*sql.DB, error) { } return db, nil } - -// GetDBFile returns the database file path, checking DATABASE_FILE env var first -func GetDBFile() string { - if f := os.Getenv("DATABASE_FILE"); f != "" { - return f - } - return "mal.db" -} diff --git a/internal/episodes/module.go b/internal/episodes/module.go index d20cee3..345a101 100644 --- a/internal/episodes/module.go +++ b/internal/episodes/module.go @@ -1,11 +1,9 @@ package episodes import ( - "os" - "strings" - "mal/integrations/jikan" "mal/integrations/playback/allanime" + "mal/internal/config" "mal/internal/db" "mal/internal/domain" episodeService "mal/internal/episodes/service" @@ -14,9 +12,8 @@ import ( "go.uber.org/fx" ) -func episodeAvailabilityEnabled() bool { - value := strings.ToLower(strings.TrimSpace(os.Getenv("EPISODE_AVAILABILITY_MODE"))) - return value != "legacy" && value != "jikan" +func episodeAvailabilityEnabled(cfg config.Config) bool { + return cfg.EpisodeAvailabilityMode != config.EpisodeAvailabilityModeLegacy && cfg.EpisodeAvailabilityMode != config.EpisodeAvailabilityModeJikan } var Module = fx.Options( diff --git a/internal/playback/module.go b/internal/playback/module.go index 4128613..b869d36 100644 --- a/internal/playback/module.go +++ b/internal/playback/module.go @@ -1,10 +1,9 @@ package playback import ( - "os" - "mal/integrations/jikan" "mal/integrations/playback/allanime" + "mal/internal/config" "mal/internal/domain" "mal/internal/playback/handler" "mal/internal/playback/repository" @@ -14,8 +13,8 @@ import ( "go.uber.org/fx" ) -func provideProxyTokenKey() string { - return os.Getenv("PLAYBACK_PROXY_SECRET") +func provideProxyTokenKey(cfg config.Config) string { + return cfg.PlaybackProxySecret } var Module = fx.Options( diff --git a/internal/server/cors.go b/internal/server/cors.go index 4d22d2b..c6adb5c 100644 --- a/internal/server/cors.go +++ b/internal/server/cors.go @@ -1,16 +1,19 @@ package server import ( + "mal/internal/config" "net/http" - "os" "strings" "github.com/gin-gonic/gin" ) func CORSMiddleware() gin.HandlerFunc { - allowAll := os.Getenv("MAL_CORS_ALLOW_ALL") == "1" + return CORSMiddlewareWithConfig(config.Config{}) +} +func CORSMiddlewareWithConfig(cfg config.Config) gin.HandlerFunc { + allowAll := cfg.CORSAllowAll return func(c *gin.Context) { origin := c.GetHeader("Origin") if origin != "" && (allowAll || isAllowedOrigin(origin)) { diff --git a/internal/server/server.go b/internal/server/server.go index e57bee9..bd3e992 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -3,9 +3,9 @@ package server import ( "context" "log" + "mal/internal/config" "mal/internal/observability" "net/http" - "os" "time" "github.com/gin-gonic/gin" @@ -19,12 +19,14 @@ var Module = fx.Options( fx.Invoke(RunServer), ) -func ProvideRouter(htmlRender render.HTMLRender, metrics *observability.Metrics) *gin.Engine { - if os.Getenv("GIN_MODE") == "" { +func ProvideRouter(cfg config.Config, htmlRender render.HTMLRender, metrics *observability.Metrics) *gin.Engine { + if cfg.GinMode == "" { gin.SetMode(gin.ReleaseMode) + } else { + gin.SetMode(cfg.GinMode) } r := gin.New() - r.Use(CORSMiddleware(), RequestLogger(metrics), gin.Recovery()) + r.Use(CORSMiddlewareWithConfig(cfg), RequestLogger(metrics), gin.Recovery()) r.Static("/static", "./static") r.Static("/dist", "./dist") r.GET("/metrics", gin.WrapH(metrics.Handler())) @@ -32,11 +34,8 @@ func ProvideRouter(htmlRender render.HTMLRender, metrics *observability.Metrics) return r } -func RunServer(lifecycle fx.Lifecycle, r *gin.Engine) { - port := os.Getenv("PORT") - if port == "" { - port = "3000" - } +func RunServer(cfg config.Config, lifecycle fx.Lifecycle, r *gin.Engine) { + port := cfg.Port srv := newHTTPServer(":"+port, r)