299 lines
11 KiB
Go
299 lines
11 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/yaoapp/kun/log"
|
|
|
|
"github.com/caarlos0/env/v6"
|
|
"github.com/joho/godotenv"
|
|
"github.com/yaoapp/kun/exception"
|
|
)
|
|
|
|
// Conf 配置参数
|
|
var Conf Config
|
|
|
|
func init() {
|
|
filename, _ := filepath.Abs(filepath.Join(".", ".env"))
|
|
if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) {
|
|
Conf = Load()
|
|
return
|
|
}
|
|
Conf = LoadFrom(filename)
|
|
}
|
|
|
|
// LoadFrom 从配置项中加载
|
|
func LoadFrom(envfile string) Config {
|
|
|
|
file, err := filepath.Abs(envfile)
|
|
if err != nil {
|
|
log.Warn("Can't load env file. %s", err.Error())
|
|
}
|
|
err = godotenv.Overload(file)
|
|
if err != nil {
|
|
log.Warn("Can't load env file. %s", err.Error())
|
|
}
|
|
|
|
return Load()
|
|
}
|
|
|
|
// Load 加载配置
|
|
func Load() Config {
|
|
cfg := Config{}
|
|
if err := env.Parse(&cfg); err != nil {
|
|
exception.New("Can't read config %s", 500, err.Error()).Throw()
|
|
}
|
|
cfg.Root, _ = filepath.Abs(cfg.Root)
|
|
return cfg
|
|
}
|
|
|
|
// // Config 系统配置
|
|
// type Config struct {
|
|
// XiangConfig
|
|
// Service ServiceConfig `json:"service,omitempty"`
|
|
// Session SessionConfig `json:"session,omitempty"`
|
|
// Database DatabaseConfig `json:"database,omitempty"`
|
|
// JWT JWTConfig `json:"jwt,omitempty"`
|
|
// Log LogConfig `json:"log,omitempty"`
|
|
// }
|
|
|
|
// // JWTConfig JWT配置
|
|
// type JWTConfig struct {
|
|
// Secret string `json:"secret,omitempty" env:"YAO_JWT_SECRET"` // JWT 密钥
|
|
// }
|
|
|
|
// // LogConfig 日志配置
|
|
// type LogConfig struct {
|
|
// Access string `json:"access,omitempty" env:"XIANG_LOG_ACCESS" envDefault:"os://stdout"` // 服务访问日志
|
|
// Error string `json:"error,omitempty" env:"XIANG_LOG_ERROR" envDefault:"os://stderr"` // 服务错误日志
|
|
// DB string `json:"database,omitempty" env:"XIANG_LOG_DB" envDefault:"os://stdout"` // 数据库日志
|
|
// Plugin string `json:"plugin,omitempty" env:"XIANG_LOG_PLUGIN" envDefault:"os://stdout"` // 插件日志
|
|
// }
|
|
|
|
// // XiangConfig 象传应用引擎配置
|
|
// type XiangConfig struct {
|
|
// Mode string `json:"mode,omitempty" env:"XIANG_MODE" envDefault:"release"` // 象传引擎模式 debug/release/test
|
|
// Source string `json:"source,omitempty" env:"XIANG_SOURCE" envDefault:"fs://."` // 源码路径(用于单元测试载入数据)
|
|
// Path string `json:"path,omitempty" env:"XIANG_PATH" envDefault:"bin://xiang"` // 引擎文件目录
|
|
// Root string `json:"root,omitempty" env:"XIANG_ROOT" envDefault:"fs://."` // 应用文件目录
|
|
// RootUI string `json:"root_ui,omitempty" env:"XIANG_ROOT_UI"` // 应用界面静态文件目录
|
|
// RootDB string `json:"root_db,omitempty" env:"XIANG_ROOT_DB"` // 应用SQLite数据库目录
|
|
// RootData string `json:"root_data,omitempty" env:"XIANG_ROOT_DATA"` // 应用数据文件目录
|
|
// RootAPI string `json:"root_api,omitempty" env:"XIANG_ROOT_API"` // 应用API文件目录
|
|
// RootModel string `json:"root_model,omitempty" env:"XIANG_ROOT_MODEL"` // 应用模型文件目录
|
|
// RootFLow string `json:"root_flow,omitempty" env:"XIANG_ROOT_FLOW"` // 应用业务逻辑文件目录
|
|
// RootPlugin string `json:"root_plugin,omitempty" env:"XIANG_ROOT_PLUGIN"` // 应用业务插件文件目录
|
|
// RootLib string `json:"root_lib,omitempty" env:"XIANG_ROOT_LIB"` // 应用资料库文件目录
|
|
// RootTable string `json:"root_table,omitempty" env:"XIANG_ROOT_TABLE"` // 应用数据表格文件目录
|
|
// RootChart string `json:"root_chart,omitempty" env:"XIANG_ROOT_CHART"` // 应用分析图表文件目录
|
|
// RootPage string `json:"root_page,omitempty" env:"XIANG_ROOT_PAGE"` // 应用通用页面文件目录
|
|
// RootScreen string `json:"root_screen,omitempty" env:"XIANG_ROOT_SCREEN"` // 应用大屏文件目录
|
|
// RootForm string `json:"root_form,omitempty" env:"XIANG_ROOT_FORM"` // 表单文件目录
|
|
// RootWorkFlow string `json:"root_workflow,omitempty" env:"XIANG_ROOT_WORKFLOW"` // 工作流文件目录
|
|
// }
|
|
|
|
// // ServiceConfig 服务配置
|
|
// type ServiceConfig struct {
|
|
// Debug bool `json:"debug,omitempty" env:"XIANG_SERVICE_DEBUG" envDefault:"false"` // DEBUG 开关
|
|
// HTTPS bool `json:"https,omitempty" env:"XIANG_SERVICE_HTTPS" envDefault:"false"` // HTTPS 开关
|
|
// Cert string `json:"cert,omitempty" env:"XIANG_SERVICE_CERT"` // HTTPS 证书
|
|
// Key string `json:"key,omitempty" env:"XIANG_SERVICE_KEY"` // HTTPS 证书密钥
|
|
// Allow []string `json:"allow,omitempty" env:"XIANG_SERVICE_ALLOW" envSeparator:"|"` // 跨域访问域名列表
|
|
// Host string `json:"host,omitempty" env:"XIANG_SERVICE_HOST" envDefault:"127.0.0.1"` // 服务监听IP
|
|
// Port int `json:"port,omitempty" env:"XIANG_SERVICE_PORT" envDefault:"5099"` // 服务监听端口
|
|
// }
|
|
|
|
// SessionConfig 会话服务器
|
|
type SessionConfig struct {
|
|
Debug bool `json:"debug,omitempty" env:"XIANG_SESSION_DEBUG" envDefault:"false"` // DEBUG 开关
|
|
Hosting bool `json:"hosting,omitempty" env:"XIANG_SESSION_HOSTING" envDefault:"true"` // 会话服务器
|
|
IsCLI bool `json:"iscli,omitempty" env:"XIANG_SESSION_ISCLI" envDefault:"false"` // 是否为客户端启动
|
|
Host string `json:"host,omitempty" env:"XIANG_SESSION_HOST" envDefault:"127.0.0.1"` // 会话服务器IP
|
|
Port int `json:"port,omitempty" env:"XIANG_SESSION_PORT" envDefault:"3322"` // 会话服务器端口
|
|
}
|
|
|
|
// // DatabaseConfig 数据库配置
|
|
// type DatabaseConfig struct {
|
|
// Debug bool `json:"debug,omitempty" env:"XIANG_DB_DEBUG" envDefault:"false"` // DEBUG 开关
|
|
// Driver string `json:"driver,omitempty" env:"XIANG_DB_DRIVER" envDefault:"sqlite3"` // 数据库驱动 ( sqlite3, mysql, postgres)
|
|
// Primary []string `json:"primary,omitempty" env:"XIANG_DB_PRIMARY" envSeparator:"|" envDefault:"file:./db/xiang.db"` // 主库连接DSN
|
|
// Secondary []string `json:"secondary,omitempty" env:"XIANG_DB_SECONDARY" envSeparator:"|"` // 从库连接DSN
|
|
// AESKey string `json:"aeskey,omitempty" env:"XIANG_DB_AESKEY"` // 加密存储KEY
|
|
// }
|
|
|
|
// // NewConfig 创建配置文件
|
|
// func NewConfig(envfile ...string) Config {
|
|
|
|
// filename := os.Getenv("XIANG_ENV_FILE")
|
|
// if filename == "" {
|
|
// filename = ".env"
|
|
// }
|
|
|
|
// if len(envfile) > 0 {
|
|
// file, err := filepath.Abs(envfile[0])
|
|
// if err == nil {
|
|
// // log.Printf("加载环境配置文件%s出错 %s\n", envfile[0], err.Error())
|
|
// // } else {
|
|
// filename = file
|
|
// }
|
|
// }
|
|
|
|
// godotenv.Overload(filename)
|
|
// // if err != nil {
|
|
// // log.Printf("加载环境配置文件%s出错 %s\n", filename, err.Error())
|
|
// // }
|
|
|
|
// cfg := Config{}
|
|
// if err := env.Parse(&cfg); err != nil {
|
|
// exception.New("解析配置文件出错 %s", 500, err.Error()).Throw()
|
|
// }
|
|
|
|
// cfg.SetDefaults()
|
|
// return cfg
|
|
// }
|
|
|
|
// // NewConfigFrom 创建配置文件
|
|
// func NewConfigFrom(input io.Reader) Config {
|
|
// cfg := Config{}
|
|
// err := helper.UnmarshalFile(input, &cfg)
|
|
// if err != nil {
|
|
// exception.New("解析配置文件出错 %s", 500, err.Error()).Throw()
|
|
// }
|
|
// cfg.SetDefaults()
|
|
// return cfg
|
|
// }
|
|
|
|
// // SetDefaults 设定默认值
|
|
// func (cfg *Config) SetDefaults() {
|
|
|
|
// pwd, err := os.Getwd()
|
|
// if err != nil {
|
|
// log.Fatal(err.Error())
|
|
// }
|
|
|
|
// if cfg.Root == "fs://." || cfg.Root == "." {
|
|
// cfg.Root = pwd
|
|
// }
|
|
|
|
// if cfg.RootAPI == "" {
|
|
// cfg.RootAPI = cfg.Root + "/apis"
|
|
// }
|
|
// if cfg.RootFLow == "" {
|
|
// cfg.RootFLow = cfg.Root + "/flows"
|
|
// }
|
|
// if cfg.RootModel == "" {
|
|
// cfg.RootModel = cfg.Root + "/models"
|
|
// }
|
|
// if cfg.RootPlugin == "" {
|
|
// cfg.RootPlugin = cfg.Root + "/plugins"
|
|
// }
|
|
|
|
// if cfg.RootTable == "" {
|
|
// cfg.RootTable = cfg.Root + "/tables"
|
|
// }
|
|
|
|
// if cfg.RootLib == "" {
|
|
// cfg.RootLib = cfg.Root + "/libs"
|
|
// }
|
|
|
|
// if cfg.RootChart == "" {
|
|
// cfg.RootChart = cfg.Root + "/charts"
|
|
// }
|
|
|
|
// if cfg.RootPage == "" {
|
|
// cfg.RootPage = cfg.Root + "/pages"
|
|
// }
|
|
|
|
// if cfg.RootWorkFlow == "" {
|
|
// cfg.RootWorkFlow = cfg.Root + "/workflows"
|
|
// }
|
|
|
|
// if cfg.RootData == "" {
|
|
// cfg.RootData = cfg.Root + "/data"
|
|
// }
|
|
|
|
// if cfg.RootDB == "" {
|
|
// cfg.RootDB = cfg.Root + "/db"
|
|
// }
|
|
|
|
// if cfg.RootUI == "" {
|
|
// cfg.RootUI = cfg.Root + "/ui"
|
|
// }
|
|
|
|
// if len(cfg.Database.Primary) > 0 {
|
|
// if strings.HasPrefix(cfg.Database.Primary[0], "file:.") {
|
|
// cfg.Database.Primary[0] = strings.ReplaceAll(cfg.Database.Primary[0], "file:.", pwd)
|
|
// } else if strings.HasPrefix(cfg.Database.Primary[0], "file:/") {
|
|
// cfg.Database.Primary[0] = strings.ReplaceAll(cfg.Database.Primary[0], "file:.", cfg.RootDB)
|
|
// }
|
|
// }
|
|
|
|
// // 过滤数据
|
|
// cfg.RootDB = strings.TrimPrefix(cfg.RootDB, "fs://")
|
|
// cfg.RootDB = strings.TrimPrefix(cfg.RootDB, "file://")
|
|
// cfg.RootData = strings.TrimPrefix(cfg.RootData, "fs://")
|
|
// cfg.RootData = strings.TrimPrefix(cfg.RootData, "file://")
|
|
// cfg.RootUI = strings.TrimPrefix(cfg.RootUI, "fs://")
|
|
// cfg.RootUI = strings.TrimPrefix(cfg.RootUI, "file://")
|
|
// cfg.RootLib = strings.TrimPrefix(cfg.RootLib, "fs://")
|
|
// cfg.RootLib = strings.TrimPrefix(cfg.RootLib, "file://")
|
|
|
|
// }
|
|
|
|
// // SetEnvFile 指定ENV文件
|
|
// func SetEnvFile(filename string) {
|
|
// Conf = NewConfig(filename)
|
|
// }
|
|
|
|
// // SetAppPath 设定应用目录
|
|
// func SetAppPath(root string, envfile ...string) {
|
|
|
|
// fullpath, err := filepath.Abs(root)
|
|
// if err != nil {
|
|
// log.Panic("设定应用目录%s出错 %s\n", root, err.Error())
|
|
// }
|
|
|
|
// // 创建应用目录
|
|
// pathinfo, err := os.Stat(fullpath)
|
|
// if os.IsNotExist(err) {
|
|
// err := os.MkdirAll(fullpath, os.ModePerm)
|
|
// if err != nil {
|
|
// log.Panic("创建目录失败(%s) %s", root, err)
|
|
// }
|
|
// }
|
|
// pathinfo, err = os.Stat(fullpath)
|
|
// if !pathinfo.IsDir() {
|
|
// log.Panic("检查应用目录失败(%s) ", err)
|
|
// }
|
|
|
|
// if !pathinfo.IsDir() {
|
|
// log.Panic("应用目录不是文件夹(%s) ", root)
|
|
// }
|
|
|
|
// // Set ENV
|
|
// if len(envfile) > 0 {
|
|
// Conf = NewConfig(envfile[0])
|
|
// }
|
|
|
|
// // 从加载配置文件
|
|
// Conf.Root = fullpath
|
|
// Conf.RootAPI = filepath.Join(fullpath, "/apis")
|
|
// Conf.RootFLow = filepath.Join(fullpath, "/flows")
|
|
// Conf.RootModel = filepath.Join(fullpath, "/models")
|
|
// Conf.RootPlugin = filepath.Join(fullpath, "/plugins")
|
|
// Conf.RootTable = filepath.Join(fullpath, "/tables")
|
|
// Conf.RootChart = filepath.Join(fullpath, "/charts")
|
|
// Conf.RootPage = filepath.Join(fullpath, "/pages")
|
|
// Conf.RootWorkFlow = filepath.Join(fullpath, "/workflows")
|
|
// Conf.RootData = filepath.Join(fullpath, "/data")
|
|
// Conf.RootUI = filepath.Join(fullpath, "/ui")
|
|
// Conf.RootDB = filepath.Join(fullpath, "/db")
|
|
// Conf.RootLib = filepath.Join(fullpath, "/libs")
|
|
// }
|
|
|
|
// // IsDebug 是否为调试模式
|
|
// func IsDebug() bool {
|
|
// return Conf.Mode == "debug"
|
|
// }
|