starter/app/config/config.go
2026-03-28 19:29:40 +08:00

137 lines
3.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package config
import (
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"gopkg.in/yaml.v3"
)
var (
config *Config
once sync.Once
)
func Init(args []string) {
_initConfig(args)
}
type Config struct {
Server struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Env string `yaml:"env"`
} `yaml:"server"`
// 内部加工配置
LogFile string
}
func GetConfig() *Config {
return _initConfig(nil)
}
func _initConfig(args []string) *Config {
if config == nil {
once.Do(func() {
c, err := loadConfig(args)
if err != nil {
panic(err)
}
config = c
})
}
return config
}
// 获取配置文件的绝对路径
func getConfigFile(confFile string) string {
if confFile != "" {
if _, err := os.Stat(confFile); err == nil {
return confFile
}
}
// 方案:优先从工作目录查找(适配 GoLand 直接运行的场景)
workDir, err := os.Getwd()
if err == nil {
workDirConfig := filepath.Join(workDir, "output/conf/conf.yml")
if _, err := os.Stat(workDirConfig); err == nil {
return workDirConfig
}
workDirConfig = filepath.Join(workDir, "conf/conf.yml")
if _, err := os.Stat(workDirConfig); err == nil {
return workDirConfig
}
if strings.Contains(workDirConfig, "starter") {
values := strings.Split(workDirConfig, "/starter")
if len(values) > 1 {
v := filepath.Join(values[0], "starter", "conf/conf.yml")
if _, err := os.Stat(v); err == nil {
return v
}
}
}
}
// 方案:从程序执行路径推导(适配部署环境)
exePath, err := os.Executable()
if err != nil {
panic(fmt.Sprintf("获取程序路径失败: %v", err))
}
exeDir := filepath.Dir(exePath)
// 判断是否是部署环境bin 目录下)
if filepath.Base(exeDir) == "bin" {
// 部署环境output/bin/ -> output/conf/conf.yml
return filepath.Join(exeDir, "../conf/conf.yml")
}
// 兜底:程序目录下的 conf/conf.yaml
return filepath.Join(exeDir, "conf/conf.yml")
}
// 加载配置文件
func loadConfig(args []string) (*Config, error) {
confFile := getValueFromArgs(args, "config")
configFile := getConfigFile(confFile)
fmt.Println("configFile:", configFile)
// 读取配置文件内容
data, err := os.ReadFile(configFile)
if err != nil {
return nil, fmt.Errorf("读取配置文件失败: %v", err)
}
// 解析 YAML 到结构体
var c Config
if err := yaml.Unmarshal(data, &c); err != nil {
return nil, fmt.Errorf("解析 YAML 失败: %v", err)
}
prefix := ""
if !strings.Contains(configFile, "/output/conf/") {
prefix = "/output"
}
pathArr := strings.Split(configFile, "/conf/")
if len(pathArr) == 0 {
panic("配置文件需要在`conf`目录下")
}
logDir := pathArr[0] + prefix + "/logs"
fmt.Println("logDir:", logDir)
// 自动创建日志目录(关键:避免目录不存在导致写入失败)
if err := os.MkdirAll(logDir, 0755); err != nil {
panic(fmt.Sprintf("创建日志目录失败: %v", err))
}
c.LogFile = filepath.Join(logDir, "starter.log")
return &c, nil
}
func getValueFromArgs(args []string, key string) string {
for _, arg := range args {
if strings.HasPrefix(arg, fmt.Sprintf("%s=", key)) {
value := strings.ReplaceAll(arg, fmt.Sprintf("%s=", key), "")
return value
}
}
return ""
}