rename LoadConfig to Load(by AI)

This commit is contained in:
AI Engineer 2026-05-02 13:36:06 +08:00
parent f29b426c2d
commit 254aff7873
7 changed files with 23 additions and 23 deletions

View File

@ -1,7 +1,7 @@
# 更新日志 (Changelog) # 更新日志 (Changelog)
## [1.0.4] - 2026-05-02 ## [1.0.4] - 2026-05-02
- **变更**: 重构了 `LoadConfig`,使用 `errors.Join` 改进了错误处理。 - **变更**: 重构了 `Load`,使用 `errors.Join` 改进了错误处理。
- **变更**: 将 `findFile` 重命名为 `resolveConfigFilePath` 以提高代码清晰度。 - **变更**: 将 `findFile` 重命名为 `resolveConfigFilePath` 以提高代码清晰度。
- **变更**: 更新了测试套件以验证错误返回,并移除了重复的类型定义。 - **变更**: 更新了测试套件以验证错误返回,并移除了重复的类型定义。
- **变更**: 新增 `bench_test.go` 用于性能评估。 - **变更**: 新增 `bench_test.go` 用于性能评估。

View File

@ -3,7 +3,7 @@
`config` 模块负责从文件JSON/YAML加载配置并支持通过环境变量进行覆盖。 `config` 模块负责从文件JSON/YAML加载配置并支持通过环境变量进行覆盖。
## API 指南 ## API 指南
### `LoadConfig(name string, conf interface{}) error` ### `Load(name string, conf interface{}) error`
从当前目录、可执行文件目录或用户主目录中加载 `name.json``name.yml`。随后,它会尝试加载 `env.json``env.yml` 并使用环境变量进行最终覆盖。 从当前目录、可执行文件目录或用户主目录中加载 `name.json``name.yml`。随后,它会尝试加载 `env.json``env.yml` 并使用环境变量进行最终覆盖。
## 环境变量覆盖规则 ## 环境变量覆盖规则

View File

@ -17,7 +17,7 @@
goos: darwin goos: darwin
goarch: amd64 goarch: amd64
pkg: apigo.cc/go/config pkg: apigo.cc/go/config
BenchmarkLoadConfig-16 9104 123326 ns/op 5136 B/op 104 allocs/op BenchmarkLoad-16 9104 123326 ns/op 5136 B/op 104 allocs/op
BenchmarkApplyEnvOverrides-16 260586 4700 ns/op 2657 B/op 64 allocs/op BenchmarkApplyEnvOverrides-16 260586 4700 ns/op 2657 B/op 64 allocs/op
``` ```

View File

@ -5,18 +5,18 @@ import (
"testing" "testing"
) )
func BenchmarkLoadConfig(b *testing.B) { func BenchmarkLoad(b *testing.B) {
os.WriteFile("bench.json", []byte(`{"name":"bench-test","sets":[1,2,3]}`), 0644) os.WriteFile("bench.json", []byte(`{"name":"bench-test","sets":[1,2,3]}`), 0644)
defer os.Remove("bench.json") defer os.Remove("bench.json")
var conf struct { var conf struct {
Name string Name string
Sets []int Sets []int
} }
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
_ = LoadConfig("bench", &conf) _ = Load("bench", &conf)
} }
} }
@ -24,7 +24,7 @@ func BenchmarkApplyEnvOverrides(b *testing.B) {
os.Setenv("APP_DB_HOST", "localhost") os.Setenv("APP_DB_HOST", "localhost")
os.Setenv("APP_DB_PORT", "5432") os.Setenv("APP_DB_PORT", "5432")
os.Setenv("APP_SERVER_TIMEOUT", "30s") os.Setenv("APP_SERVER_TIMEOUT", "30s")
var conf struct { var conf struct {
App struct { App struct {
Db struct { Db struct {
@ -36,7 +36,7 @@ func BenchmarkApplyEnvOverrides(b *testing.B) {
} }
} }
} }
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
applyEnvOverrides(&conf) applyEnvOverrides(&conf)

View File

@ -43,9 +43,9 @@ func (d Duration) TimeDuration() time.Duration {
return time.Duration(d) return time.Duration(d)
} }
// LoadConfig loads configuration from a file, then applies env.json/yaml if exists, // Load loads configuration from a file, then applies env.json/yaml if exists,
// and finally overrides with environment variables. // and finally overrides with environment variables.
func LoadConfig(name string, conf interface{}) error { func Load(name string, conf interface{}) error {
var errs []error var errs []error
// 1. Load base file // 1. Load base file
@ -118,7 +118,7 @@ func applyEnvOverrides(conf interface{}) {
if len(pair) != 2 { if len(pair) != 2 {
continue continue
} }
// Convert DB_HOST to {"db": {"host": value}} // Convert DB_HOST to {"db": {"host": value}}
parts := strings.Split(strings.ToLower(pair[0]), "_") parts := strings.Split(strings.ToLower(pair[0]), "_")
curr := envMap curr := envMap

View File

@ -38,8 +38,8 @@ func TestConfig_ComplexStruct(t *testing.T) {
os.Setenv("LIST_BBB", "{\"name\":\"xxx\"}") os.Setenv("LIST_BBB", "{\"name\":\"xxx\"}")
var conf testConfType var conf testConfType
if err := LoadConfig("complex", &conf); err != nil { if err := Load("complex", &conf); err != nil {
t.Errorf("LoadConfig failed: %v", err) t.Errorf("Load failed: %v", err)
} }
if conf.Name != "test-config" { if conf.Name != "test-config" {

View File

@ -20,13 +20,13 @@ func TestForMap_Regression(t *testing.T) {
os.Clearenv() os.Clearenv()
os.WriteFile("test.json", []byte(`{"name":"test-config"}`), 0644) os.WriteFile("test.json", []byte(`{"name":"test-config"}`), 0644)
defer os.Remove("test.json") defer os.Remove("test.json")
os.Setenv("TEST_LIST_CCC", "333") os.Setenv("TEST_LIST_CCC", "333")
testConf := map[string]interface{}{} testConf := map[string]interface{}{}
err := LoadConfig("test", &testConf) err := Load("test", &testConf)
if err != nil { if err != nil {
t.Fatalf("LoadConfig failed: %v", err) t.Fatalf("Load failed: %v", err)
} }
if testConf["name"] != "test-config" { if testConf["name"] != "test-config" {
t.Errorf("Expected name test-config, got %v", testConf["name"]) t.Errorf("Expected name test-config, got %v", testConf["name"])
@ -42,13 +42,13 @@ func TestForStruct_Regression(t *testing.T) {
"duration": "100s" "duration": "100s"
}`), 0644) }`), 0644)
defer os.Remove("test.json") defer os.Remove("test.json")
os.Setenv("LIST_CCC", "{\"name\":\"333\"}") os.Setenv("LIST_CCC", "{\"name\":\"333\"}")
os.Setenv("LIST_DDD", "{\"name\":\"444\"}") os.Setenv("LIST_DDD", "{\"name\":\"444\"}")
var testConf RegressionConf var testConf RegressionConf
if err := LoadConfig("test", &testConf); err != nil { if err := Load("test", &testConf); err != nil {
t.Errorf("LoadConfig failed: %v", err) t.Errorf("Load failed: %v", err)
} }
if testConf.Name != "test-config" || len(testConf.Sets) != 3 || testConf.Sets[1] != 2 { if testConf.Name != "test-config" || len(testConf.Sets) != 3 || testConf.Sets[1] != 2 {
@ -79,8 +79,8 @@ extList: ["a", "222", {val: "111"}]
defer os.Remove("test2.yml") defer os.Remove("test2.yml")
var testConf RegressionConf var testConf RegressionConf
if err := LoadConfig("test2", &testConf); err != nil { if err := Load("test2", &testConf); err != nil {
t.Errorf("LoadConfig failed: %v", err) t.Errorf("Load failed: %v", err)
} }
if testConf.Name != "test-config" || len(testConf.List2) != 2 { if testConf.Name != "test-config" || len(testConf.List2) != 2 {