feat: load explicit configuration references and remove implicit env overlays

This commit is contained in:
2026-09-26 16:14:54 +08:00
parent 4bf6e88cfe
commit d598b2ebee
94 changed files with 1355 additions and 1759 deletions

View File

@@ -26,6 +26,7 @@ func (f DecoderFunc) Decode(data []byte) (Document, error) { return f(data) }
type Loader struct {
decoders map[string]Decoder
sealed bool
lookup func(string) (string, bool)
}
type LoaderOption func(*Loader) error
@@ -55,7 +56,7 @@ func WithDecoder(extension string, decoder Decoder) LoaderOption {
}
func NewLoader(options ...LoaderOption) (*Loader, error) {
l := &Loader{decoders: map[string]Decoder{"json": JSONDecoder{}, "yaml": YAMLDecoder{}, "yml": YAMLDecoder{}, "xml": XMLDecoder{}}}
l := &Loader{lookup: os.LookupEnv, decoders: map[string]Decoder{"json": JSONDecoder{}, "yaml": YAMLDecoder{}, "yml": YAMLDecoder{}, "xml": XMLDecoder{}}}
for _, o := range options {
if o == nil {
return nil, errors.New("config: nil loader option")
@@ -135,7 +136,7 @@ func (l *Loader) read(path string) (doc Document, err error) {
if _, ok := doc.Value.(map[string]any); !ok {
return doc, doc.diagnostic("", "root must be an object", nil)
}
return doc, nil
return resolveDocument(doc, l.lookup)
}
func decodeSafely(decoder Decoder, data []byte) (doc Document, err error) {
defer func() {
@@ -165,11 +166,12 @@ func DecodeFile[T any](path string, defaults T, loaders ...*Loader) (T, error) {
if err != nil {
return zero, err
}
if err := rejectEnvironmentTags(reflect.TypeOf(defaults), map[reflect.Type]bool{}); err != nil {
return zero, err
}
result, err := bindDocument(doc, defaults)
if err != nil {
d := validationError(err)
d.File = path
return zero, d
return zero, locateError(err, path, doc)
}
return result, nil
}