// Package file is adapted from go-kratos/kratos config/file. // // Upstream: https://github.com/go-kratos/kratos/tree/v2.9.2/config/file // License: MIT, see ../LICENSE.kratos. package file import ( "io" "os" "path/filepath" "strings" "github.com/geo-platform/tenant-api/internal/shared/config/runtime" ) type file struct { path string names map[string]struct{} } func NewSource(path string, names ...string) runtime.Source { return &file{path: path, names: namesSet(names)} } func (f *file) loadFile(path string) (*runtime.KeyValue, error) { file, err := os.Open(path) if err != nil { return nil, err } defer file.Close() data, err := io.ReadAll(file) if err != nil { return nil, err } info, err := file.Stat() if err != nil { return nil, err } return &runtime.KeyValue{ Key: info.Name(), Format: format(info.Name()), Value: data, }, nil } func (f *file) loadDir(path string) ([]*runtime.KeyValue, error) { files, err := os.ReadDir(path) if err != nil { return nil, err } kvs := make([]*runtime.KeyValue, 0, len(files)) for _, item := range files { if item.IsDir() || strings.HasPrefix(item.Name(), ".") || !f.matchName(item.Name()) { continue } kv, err := f.loadFile(filepath.Join(path, item.Name())) if err != nil { return nil, err } kvs = append(kvs, kv) } return kvs, nil } func (f *file) Load() ([]*runtime.KeyValue, error) { info, err := os.Stat(f.path) if err != nil { return nil, err } if info.IsDir() { return f.loadDir(f.path) } kv, err := f.loadFile(f.path) if err != nil { return nil, err } return []*runtime.KeyValue{kv}, nil } func (f *file) Watch() (runtime.Watcher, error) { return newWatcher(f) } func (f *file) match(path string) bool { return f.matchName(filepath.Base(path)) } func (f *file) matchName(name string) bool { if len(f.names) == 0 { return true } _, ok := f.names[name] return ok } func namesSet(names []string) map[string]struct{} { if len(names) == 0 { return nil } out := make(map[string]struct{}, len(names)) for _, name := range names { name = strings.TrimSpace(name) if name == "" { continue } out[filepath.Base(name)] = struct{}{} } return out }