From 6f39d532ce362d5e79cf923f4a7b8a02ea362699 Mon Sep 17 00:00:00 2001 From: lew Date: Thu, 18 Dec 2025 12:47:38 +0000 Subject: [PATCH] feat(config): config at XDG dir --- cmd/config.go | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/keyspec.go | 6 ++--- cmd/root.go | 5 ++++ cmd/shared.go | 4 +-- 4 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 cmd/config.go diff --git a/cmd/config.go b/cmd/config.go new file mode 100644 index 0000000..e6a8724 --- /dev/null +++ b/cmd/config.go @@ -0,0 +1,67 @@ +package cmd + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/BurntSushi/toml" + gap "github.com/muesli/go-app-paths" +) + +type Config struct { + DefaultDB string `toml:"default_db"` +} + +var ( + config Config + configErr error +) + +func init() { + config, configErr = loadConfig() +} + +func defaultConfig() Config { + return Config{ + DefaultDB: "default", + } +} + +func loadConfig() (Config, error) { + cfg := defaultConfig() + + path, err := configPath() + if err != nil { + return cfg, err + } + + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + return cfg, nil + } + return cfg, err + } + + if _, err := toml.DecodeFile(path, &cfg); err != nil { + return cfg, fmt.Errorf("parse %s: %w", path, err) + } + + if cfg.DefaultDB == "" { + cfg.DefaultDB = defaultConfig().DefaultDB + } + + return cfg, nil +} + +func configPath() (string, error) { + if override := os.Getenv("PDA_CONFIG"); override != "" { + return override, nil + } + scope := gap.NewVendorScope(gap.User, "pda", "config") + dir, err := scope.ConfigPath("") + if err != nil { + return "", err + } + return filepath.Join(dir, "config.toml"), nil +} diff --git a/cmd/keyspec.go b/cmd/keyspec.go index 330a43f..28e0f1a 100644 --- a/cmd/keyspec.go +++ b/cmd/keyspec.go @@ -15,7 +15,7 @@ type KeySpec struct { } // ParseKey parses "KEY[@DB]" into a normalized KeySpec. -// When defaults is true, a missing DB defaults to "default". +// When defaults is true, a missing DB defaults to the configured default. func ParseKey(raw string, defaults bool) (KeySpec, error) { parts := strings.Split(raw, "@") if len(parts) > 2 { @@ -34,7 +34,7 @@ func ParseKey(raw string, defaults bool) (KeySpec, error) { key := strings.ToLower(rawKey) db := strings.ToLower(rawDB) if db == "" && defaults { - db = "default" + db = config.DefaultDB } return KeySpec{ @@ -57,7 +57,7 @@ func (k KeySpec) Full() string { // Display returns the normalized key reference // but omits the default database if none was set manually func (k KeySpec) Display() string { - if k.DB == "" || k.DB == "default" { + if k.DB == "" || k.DB == config.DefaultDB { return k.Key } return fmt.Sprintf("%s@%s", k.Key, k.DB) diff --git a/cmd/root.go b/cmd/root.go index 1dfca4c..99df604 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -22,6 +22,7 @@ THE SOFTWARE. package cmd import ( + "fmt" "os" "github.com/spf13/cobra" @@ -42,6 +43,10 @@ var rootCmd = &cobra.Command{ `} func Execute() { + if configErr != nil { + fmt.Fprintln(os.Stderr, "failed to load config:", configErr) + os.Exit(1) + } err := rootCmd.Execute() if err != nil { os.Exit(1) diff --git a/cmd/shared.go b/cmd/shared.go index 9a0c791..6addd25 100644 --- a/cmd/shared.go +++ b/cmd/shared.go @@ -173,7 +173,7 @@ func (s *Store) parseDB(v string, defaults bool) (string, error) { } if db == "" { if defaults { - return "default", nil + return config.DefaultDB, nil } return "", fmt.Errorf("cannot parse db: bad db format, use DB or @DB") } @@ -182,7 +182,7 @@ func (s *Store) parseDB(v string, defaults bool) (string, error) { func (s *Store) open(name string) (*badger.DB, error) { if name == "" { - name = "default" + name = config.DefaultDB } path, err := s.path(name) if err != nil {