go项目脚手架
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.
sorbet/pkg/env/env.go

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
}