Files
ersteller/starter/env/environment.go
T
2025-09-17 16:30:18 +02:00

179 lines
5.4 KiB
Go

package env
import (
. "ersteller-lib"
"fmt"
"os"
"path/filepath"
"github.com/joho/godotenv"
)
const (
EnvKeyDatabaseURL = "DATABASE_URL"
EnvKeySessionSecret = "SESSION_SECRET"
EnvKeyBaseURL = "BASE_URL"
EnvKeyIsLocal = "IS_LOCAL"
EnvKeyIsDev = "IS_DEV"
EnvKeyGoogleClientID = "GOOGLE_CLIENT_ID"
EnvKeyGoogleClientSecret = "GOOGLE_CLIENT_SECRET"
EnvKeyGoogleRedirectURL = "GOOGLE_REDIRECT_URL"
EnvKeyKeycloakDiscoveryURL = "KEYCLOAK_DISCOVERY_URL"
EnvKeyKeycloakClientID = "KEYCLOAK_CLIENT_ID"
EnvKeyKeycloakClientSecret = "KEYCLOAK_CLIENT_SECRET"
)
type UrlApiKey struct {
Url string
ApiKey string
}
type Environment struct {
DatabaseUrl string
MistralApiKey string
IsDev bool
GoogleSheetsCredPath string
GoogleSheetsSpreadId string
GoogleSheetsSheetName string
GoogleClientId string
GoogleClientSecret string
GoogleRedirectUrl string
IsLocal bool
SessionSecret string
ApifyKey string
Keycloak KeycloakConfig
BaseUrl string
}
type KeycloakConfig struct {
DiscoveryUrl string
CLientId string
ClientSecret string
}
func LoadEnvironment() Environment {
if _, err := os.Stat(".env"); err != nil {
err = GenerateEnvFile("", false)
if err != nil {
Error("error generating the environment file", err)
}
}
err := godotenv.Load()
if err != nil {
LogError("Error loading .env file: %v", err)
panic(err)
}
return Environment{
DatabaseUrl: os.Getenv(EnvKeyDatabaseURL),
IsDev: os.Getenv(EnvKeyIsDev) == "true" || os.Getenv(EnvKeyIsLocal) == "true",
GoogleClientId: os.Getenv(EnvKeyGoogleClientID),
GoogleClientSecret: os.Getenv(EnvKeyGoogleClientSecret),
GoogleRedirectUrl: os.Getenv(EnvKeyGoogleRedirectURL),
IsLocal: os.Getenv(EnvKeyIsLocal) == "true",
SessionSecret: os.Getenv(EnvKeySessionSecret),
BaseUrl: os.Getenv(EnvKeyBaseURL),
Keycloak: KeycloakConfig{
DiscoveryUrl: os.Getenv(EnvKeyKeycloakDiscoveryURL),
CLientId: os.Getenv(EnvKeyKeycloakClientID),
ClientSecret: os.Getenv(EnvKeyKeycloakClientSecret),
},
}
}
// EnvKeys returns all environment variable names used by the application configuration.
// This allows other packages (e.g., CLI tools) to discover the required keys
// without duplicating or hard-coding the list elsewhere.
func EnvKeys() []string {
return []string{
EnvKeyDatabaseURL,
EnvKeySessionSecret,
EnvKeyBaseURL,
EnvKeyIsLocal,
EnvKeyIsDev,
EnvKeyGoogleClientID,
EnvKeyGoogleClientSecret,
EnvKeyGoogleRedirectURL,
EnvKeyKeycloakDiscoveryURL,
EnvKeyKeycloakClientID,
EnvKeyKeycloakClientSecret,
}
}
// GenerateEnvFile creates a .env file template with all required environment variables
// from the EnvKeys function. The file will contain comments and default values where appropriate.
func GenerateEnvFile(rootPath string, overwrite bool) error {
envPath := filepath.Join(rootPath, ".env")
Debug("envPath:", envPath)
if !overwrite {
if _, err := os.Stat(envPath); err == nil {
fmt.Println(".env already exists at:", envPath)
fmt.Println("No changes made. Delete or move the existing .env to regenerate.")
return fmt.Errorf(".env already exists at: %s", envPath)
}
}
file, err := os.Create(envPath)
if err != nil {
return fmt.Errorf("failed to create .env file: %w", err)
}
defer file.Close()
// Write header comment
_, err = file.WriteString("# Environment Variables Configuration\n")
if err != nil {
return fmt.Errorf("failed to write to .env file: %w", err)
}
_, err = file.WriteString("# Generated from EnvKeys function\n\n")
if err != nil {
return fmt.Errorf("failed to write to .env file: %w", err)
}
// Get all environment keys
keys := EnvKeys()
// Define default values and comments for specific keys
defaults := map[string]string{
EnvKeyDatabaseURL: "\"db/starter.db?_fk=1\"",
EnvKeyBaseURL: "\"http://localhost:8090\"",
EnvKeyIsLocal: "true",
EnvKeyIsDev: "true",
}
comments := map[string]string{
EnvKeyDatabaseURL: "# Database connection URL",
EnvKeySessionSecret: "# Secret key for session management",
EnvKeyBaseURL: "# Base URL of the application",
EnvKeyIsLocal: "# Set to true for local development",
EnvKeyIsDev: "# Set to true for development mode",
EnvKeyGoogleClientID: "# Google OAuth client ID",
EnvKeyGoogleClientSecret: "# Google OAuth client secret",
EnvKeyGoogleRedirectURL: "# Google OAuth redirect URL",
EnvKeyKeycloakDiscoveryURL: "# Keycloak discovery URL",
EnvKeyKeycloakClientID: "# Keycloak client ID",
EnvKeyKeycloakClientSecret: "# Keycloak client secret",
}
// Write each environment variable
for _, key := range keys {
// Write comment if available
if comment, exists := comments[key]; exists {
_, err = file.WriteString(comment + "\n")
if err != nil {
return fmt.Errorf("failed to write to .env file: %w", err)
}
}
// Write the environment variable with default value if available
if defaultValue, exists := defaults[key]; exists {
_, err = file.WriteString(fmt.Sprintf("%s=%s\n", key, defaultValue))
} else {
_, err = file.WriteString(fmt.Sprintf("%s=\n", key))
}
if err != nil {
return fmt.Errorf("failed to write to .env file: %w", err)
}
}
return nil
}