package config import ( "fmt" "github.com/ilyakaznacheev/cleanenv" "github.com/joho/godotenv" "log" "os" "path" "path/filepath" "runtime" "strings" "time" ) type Config struct { Database struct { Driver string `yaml:"driver" env:"DB_DRIVER"` Port string `yaml:"port" env:"DB_PORT" env-default:"3306"` Host string `yaml:"host" env:"DB_HOST"` Name string `yaml:"name" env:"DB_DATABASE"` User string `yaml:"user" env:"DB_USERNAME"` Password string `yaml:"password" env:"DB_PASSWORD"` Charset string `yaml:"charset" env:"DB_CHARSET"` Prefix string `yaml:"prefix" env:"DB_PREFIX"` } `yaml:"database"` Redis struct { Host string `yaml:"host" env:"REDIS_HOST"` Password string `yaml:"password" env:"REDIS_PASSWORD"` Prefix string `yaml:"prefix" env:"REDIS_PREFIX"` } `yaml:"redis"` Log struct { Filename string `yaml:"filename"` MaxSize int `yaml:"max_size"` MaxBackups int `yaml:"max_backups"` MaxAge int `yaml:"max_age"` Compress bool `yaml:"compress"` } `yaml:"log"` Server struct { PidFile string `yaml:"pid_file"` RunMode string `yaml:"run_mode" env:"RUN_MODE"` HttpPort int `yaml:"http_port"` ReadTimeout time.Duration `yaml:"read_timeout"` WriteTimeout time.Duration `yaml:"write_timeout"` } `yaml:"server"` App struct { ProductionUrl string `yaml:"production_url"` TokenExpire int `yaml:"token_expire" env:"TOKEN_EXPIRE"` PageLimitMin int `yaml:"page_limit_min"` PageLimitMax int `yaml:"page_limit_max"` ImgHost string `yaml:"img_host"` ServiceTel string `yaml:"service_tel"` DataPath string `yaml:"data_path"` ExportPath string `yaml:"export_path"` WeixinPath string `yaml:"weixin_path"` } `yaml:"app"` Sms struct { AppID string `yaml:"app_id"` AccessKey string `yaml:"access_key"` AccessSecret string `yaml:"access_secret"` } `yaml:"sms"` Qiniu struct { Bucket string `yaml:"bucket"` AccessKey string `yaml:"access_key"` SecretKey string `yaml:"secret_key"` } `yaml:"qiniu"` } var Cfg Config // setup with option type Option struct { file string env string } type OptionFunc func(opt *Option) func WithFile(file string) OptionFunc { return func(opt *Option) { opt.file = file } } func WithEnv(env string) OptionFunc { return func(opt *Option) { opt.env = env } } func GetRootPath() string { dir := getCurrentAbPathByExecutable() if strings.Contains(dir, "tmp") { return getCurrentAbPathByCaller() } return dir } func getCurrentAbPathByExecutable() string { exePath, err := os.Executable() if err != nil { log.Fatal(err) } res, _ := filepath.EvalSymlinks(filepath.Dir(exePath)) return res + "/" } func getCurrentAbPathByCaller() string { var abPath string _, filename, _, ok := runtime.Caller(0) if ok { abPath = filepath.Join(path.Dir(filename), "../..") + "/" } return abPath } func Setup(options ...OptionFunc) { rootPath := GetRootPath() fmt.Println(rootPath) opt := Option{ file: rootPath + "config/config.yml", env: rootPath + ".env", //file: "config/config.yml", //env: ".env", } for _, fun := range options { fun(&opt) } err := godotenv.Load(opt.env) if err != nil { log.Fatal("Error loading .env file") } var config Config err = cleanenv.ReadConfig(opt.file, &config) if err != nil { panic(err) } config.Server.ReadTimeout = config.Server.ReadTimeout * time.Second config.Server.WriteTimeout = config.Server.ReadTimeout * time.Second Cfg = config }