package syncer import ( "encoding/json" "fmt" "os" "path/filepath" ) // LoadConfigFile 从网关的 config.json 里读出同步配置。 // // 取值规则:以 `sync` 段打底;其中 auth_dir / data_dir 为空时,回落到顶层的 // `auth_dir` 与 `state_file` 所在目录。这样最小改动就是在现有 config.json 里加一个 // sync 段,不必把同一批路径抄两遍(也就不会抄歪)。 // // 文件不存在时返回 os.ErrNotExist——调用方据此区分"没配置同步"与"配置读坏了", // 前者不是错误(网关自己会在首启生成配置)。 // // 相对路径**以 config.json 所在目录为基准**(调用方负责 chdir 或先解析), // 这样启动器与网关子进程看到的 ./auths 一定是同一个目录。 func LoadConfigFile(path string) (Config, error) { raw, err := os.ReadFile(path) if err != nil { return Config{}, err } var doc struct { AuthDir string `json:"auth_dir"` StateFile string `json:"state_file"` Sync *Config `json:"sync"` } if err := json.Unmarshal(raw, &doc); err != nil { return Config{}, fmt.Errorf("解析 %s: %w", path, err) } var cfg Config if doc.Sync != nil { cfg = *doc.Sync } if cfg.AuthDir == "" { cfg.AuthDir = doc.AuthDir } if cfg.DataDir == "" { // state_file 的目录就是同步用的 data/ if dir := filepath.Dir(doc.StateFile); dir != "" && dir != "." { cfg.DataDir = dir } } return cfg, nil }