package main
import (
"bufio"
"fmt"
"log"
"os"
"strings"
"sync"
)
var (
envOnce sync.Once
envErr error
)
// loadEnv loads .env file once at application startup
func loadEnv() error {
file, err := os.Open(".env")
if err != nil {
// Silent fail - .env is optional (production uses system env vars)
if os.IsNotExist(err) {
return nil
}
return fmt.Errorf("failed to open .env: %w", err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
lineNum := 0
for scanner.Scan() {
lineNum++
line := strings.TrimSpace(scanner.Text())
// Skip empty lines and comments
if line == "" || strings.HasPrefix(line, "#") {
continue
}
// Split on first = only (values can contain =)
parts := strings.SplitN(line, "=", 2)
if len(parts) != 2 {
log.Printf("Warning: skipping malformed .env line %d: %s", lineNum, line)
continue
}
key := strings.TrimSpace(parts[0])
value := strings.TrimSpace(parts[1])
// Remove surrounding quotes if present
value = unquote(value)
// Skip if key is empty
if key == "" {
continue
}
// Set in environment (Viper will pick this up automatically)
if err := os.Setenv(key, value); err != nil {
return fmt.Errorf("failed to set env var %s: %w", key, err)
}
}
if err := scanner.Err(); err != nil {
return fmt.Errorf("error reading .env: %w", err)
}
return nil
}
// unquote removes surrounding single or double quotes from a value
func unquote(s string) string {
if len(s) >= 2 {
if (s[0] == '"' && s[len(s)-1] == '"') ||
(s[0] == '\'' && s[len(s)-1] == '\'') {
return s[1 : len(s)-1]
}
}
return s
}
// InitEnv initializes environment variables from .env file
// Call this ONCE at the start of main()
func InitEnv() {
envOnce.Do(func() {
envErr = loadEnv()
if envErr != nil {
log.Printf("Warning: .env loading failed: %v", envErr)
}
})
}
// GetEnv returns environment variable value (after .env is loaded)
// Use this instead of os.Getenv for consistency
func GetEnv(key, defaultValue string) string {
InitEnv() // Ensures .env is loaded (no-op after first call)
if val := os.Getenv(key); val != "" {
return val
}
return defaultValue
}
Last active
April 25, 2026 05:57
-
-
Save ayoubzulfiqar/542ae0ffac2ba1be8ffab7eaf3b42492 to your computer and use it in GitHub Desktop.
READ ENV - without any package
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment