feat(doctor): detects undecoded config keys

This commit is contained in:
Lewis Wynne 2026-02-12 00:35:28 +00:00
parent df70be2c4f
commit 4bd45e7d3c
3 changed files with 52 additions and 10 deletions

View file

@ -63,7 +63,8 @@ type GitConfig struct {
}
var (
config Config
config Config
configUndecodedKeys []string
asciiArt string = `
@ -77,7 +78,7 @@ var (
)
func init() {
config, configErr = loadConfig()
config, configUndecodedKeys, configErr = loadConfig()
}
func defaultConfig() Config {
@ -105,24 +106,29 @@ func defaultConfig() Config {
}
}
func loadConfig() (Config, error) {
func loadConfig() (Config, []string, error) {
cfg := defaultConfig()
path, err := configPath()
if err != nil {
return cfg, err
return cfg, nil, err
}
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
return cfg, nil
return cfg, nil, nil
}
return cfg, err
return cfg, nil, err
}
_, err = toml.DecodeFile(path, &cfg)
meta, err := toml.DecodeFile(path, &cfg)
if err != nil {
return cfg, fmt.Errorf("parse %s: %w", path, err)
return cfg, nil, fmt.Errorf("parse %s: %w", path, err)
}
var undecoded []string
for _, key := range meta.Undecoded() {
undecoded = append(undecoded, key.String())
}
if cfg.Store.DefaultStoreName == "" {
@ -133,10 +139,10 @@ func loadConfig() (Config, error) {
cfg.List.DefaultListFormat = defaultConfig().List.DefaultListFormat
}
if err := validListFormat(cfg.List.DefaultListFormat); err != nil {
return cfg, fmt.Errorf("parse %s: list.default_list_format: %w", path, err)
return cfg, undecoded, fmt.Errorf("parse %s: list.default_list_format: %w", path, err)
}
return cfg, nil
return cfg, undecoded, nil
}
func configPath() (string, error) {

View file

@ -161,6 +161,12 @@ func runDoctor(w io.Writer) bool {
}
}
// 7b. Unrecognised config keys
if len(configUndecodedKeys) > 0 {
emit("WARN", fmt.Sprintf("Unrecognised config key(s) (ignored):"))
tree(configUndecodedKeys)
}
// 8. Data directory
store := &Store{}
dataDir, err := store.path()

View file

@ -88,6 +88,36 @@ func TestDoctorIdentityPermissions(t *testing.T) {
}
}
func TestDoctorUndecodedKeys(t *testing.T) {
dataDir := t.TempDir()
configDir := t.TempDir()
t.Setenv("PDA_DATA", dataDir)
t.Setenv("PDA_CONFIG", configDir)
// Write a config with an unknown key.
cfgContent := "[store]\nno_such_key = true\n"
if err := os.WriteFile(filepath.Join(configDir, "config.toml"), []byte(cfgContent), 0o644); err != nil {
t.Fatal(err)
}
savedCfg, savedUndecoded, savedErr := config, configUndecodedKeys, configErr
config, configUndecodedKeys, configErr = loadConfig()
t.Cleanup(func() {
config, configUndecodedKeys, configErr = savedCfg, savedUndecoded, savedErr
})
var buf bytes.Buffer
runDoctor(&buf)
out := buf.String()
if !strings.Contains(out, "Unrecognised config key") {
t.Errorf("expected undecoded key warning, got:\n%s", out)
}
if !strings.Contains(out, "store.no_such_key") {
t.Errorf("expected 'store.no_such_key' in output, got:\n%s", out)
}
}
func TestDoctorGitInitialised(t *testing.T) {
dataDir := t.TempDir()
configDir := t.TempDir()