package env import ( "errors" "os" "path/filepath" "strings" "time" ) // 缓存的环境变量 var env = New() // Init 加载运行目录下的 .env 文件 func Init() error { if path, err := filepath.Abs("."); err != nil { return err } else { return InitWithDir(path) } } // InitWithDir 加载指定录下的 .env 文件 func InitWithDir(dir string) error { // 重置缓存的环境变量 clear(env) // 加载系统的环境变量 for _, value := range os.Environ() { parts := strings.SplitN(value, "=", 2) key := strings.TrimSpace(parts[0]) val := strings.TrimSpace(parts[1]) env[key] = val } // 将 windows 系统风格的目录分隔符替换为 Unix 风格, // 并且排除尾部的目录分隔符。 dir = strings.TrimSuffix(strings.ReplaceAll(dir, "\\", "/"), "/") // 加载 .env 文件 if err := loadEnv(dir, ""); err != nil { return err } // 加载 .env.{APP_ENV} 文件 if appEnv := String("APP_ENV", "prod"); len(appEnv) > 0 { if err := loadEnv(dir, "."+strings.ToLower(appEnv)); err != nil { return err } } return nil } func loadEnv(dir, env string) error { if err := Load(dir + "/.env" + env); err != nil { if !errors.Is(err, os.ErrNotExist) { return err } } if err := Load(dir + "/.env" + env + ".local"); err != nil { if !errors.Is(err, os.ErrNotExist) { return err } } return nil } // Load 加载指定的环境变量文件 func Load(filenames ...string) error { return env.Load(filenames...) } // Is 判断是不是期望的值 func Is(name string, value any) bool { switch value.(type) { case bool: return Bool(name) == value case int: return Int(name) == value case time.Duration: return Duration(name) == value default: return String(name) == value } } // IsEnv 判断应用环境是否与给出的一致 func IsEnv(env string) bool { return Is("APP_ENV", env) } // Lookup 查看配置 func Lookup(name string) (string, bool) { return env.Lookup(name) } // Exists 配置是否存在 func Exists(name string) bool { return env.Exists(name) } // String 取字符串值 func String(name string, value ...string) string { return env.String(name, value...) } // Bytes 取二进制值 func Bytes(name string, value ...[]byte) []byte { return env.Bytes(name, value...) } // Int 取整型值 func Int(name string, value ...int) int { return env.Int(name, value...) } func Duration(name string, value ...time.Duration) time.Duration { return env.Duration(name, value...) } func Bool(name string, value ...bool) bool { return env.Bool(name, value...) } // List 将值按 `,` 分割并返回 func List(name string, fallback ...[]string) []string { return env.List(name, fallback...) } func Map(prefix string) map[string]string { return env.Map(prefix) } func Where(filter func(name string, value string) bool) map[string]string { return env.Where(filter) } // Fill 将环境变量填充到指定结构体 func Fill(structure any) error { return env.Fill(structure) } // All 返回所有值 func All() map[string]string { clone := make(map[string]string) for key, value := range env { clone[key] = value } return clone }