You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
3.1 KiB
153 lines
3.1 KiB
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
|
|
}
|
|
|