package config import "os" func Load(configPath, secretsPath string) (*Config, error) { return loadFile(configPath, secretsPath, true) } func loadFile(configPath, secretsPath string, exact bool) (*Config, error) { cfg, problems := readFile(configPath) return withSecrets(cfg, problems, secretsPath, exact) } func readFile(configPath string) (*Config, []Problem) { cfg, problems := loadConfig(configPath) if len(problems) == 0 { problems = readTrust(cfg) } if cfg != nil { problems = append(problems, readAppsDir(configPath, cfg)...) } return cfg, problems } func withSecrets(cfg *Config, problems []Problem, secretsPath string, exact bool) (*Config, error) { vars, secretProblems := readSecrets(secretsPath) problems = append(problems, secretProblems...) var secrets Secrets if len(problems) == 0 { secrets, secretProblems = checkSecrets(secretsPath, vars, cfg, exact) problems = append(problems, secretProblems...) } if len(problems) > 0 { sortProblems(problems) return nil, &Error{Problems: problems} } cfg.Secrets = secrets return cfg, nil } func loadConfig(path string) (*Config, []Problem) { data, err := os.ReadFile(path) if err != nil { return nil, []Problem{{File: path, Reason: reasonUnreadable}} } return loadBytes(path, data) } func loadBytes(file string, data []byte) (*Config, []Problem) { idx, problems := indexKeys(file, data) if idx == nil { return nil, problems } raw, typed := decodeTyped(file, data, idx, problems) problems = append(problems, typed...) if raw == nil || len(problems) > 0 { return nil, problems } return validate(file, idx, raw) } func LoadDisk(configPath, secretsPath string) (*Config, error) { cfg, problems := readFile(configPath) return withSecrets(cfg, problems, secretsPath, cfg == nil || cfg.Source != sourceGit) } func Check(name string, data []byte) error { _, problems := loadBytes(name, data) if len(problems) > 0 { sortProblems(problems) return &Error{Problems: problems} } return nil }