feat(config): restructures config

This commit is contained in:
Lewis Wynne 2025-12-18 18:20:51 +00:00
parent 65a393f8d6
commit f0be9c42d3
10 changed files with 71 additions and 59 deletions

View file

@ -32,10 +32,19 @@ import (
) )
type Config struct { type Config struct {
DefaultDB string `toml:"default_db"` DisplayAsciiArt bool `toml:"display_ascii_art"`
DisplayArt bool `toml:"display_art"` Key KeyConfig `toml:"key"`
WarnOnDelete bool `toml:"warn_on_delete"` Store StoreConfig `toml:"store"`
WarnOnOverwrite bool `toml:"warn_on_overwrite"` }
type KeyConfig struct {
AlwaysPromptDelete bool `toml:"always_prompt_delete"`
AlwaysPromptOverwrite bool `toml:"always_prompt_overwrite"`
}
type StoreConfig struct {
DefaultStoreName string `toml:"default_store_name"`
AlwaysPromptDelete bool `toml:"always_prompt_delete"`
} }
var ( var (
@ -58,10 +67,15 @@ func init() {
func defaultConfig() Config { func defaultConfig() Config {
return Config{ return Config{
DefaultDB: "default", DisplayAsciiArt: true,
DisplayArt: false, Key: KeyConfig{
WarnOnOverwrite: true, AlwaysPromptDelete: false,
WarnOnDelete: true, AlwaysPromptOverwrite: false,
},
Store: StoreConfig{
DefaultStoreName: "default",
AlwaysPromptDelete: true,
},
} }
} }
@ -85,20 +99,25 @@ func loadConfig() (Config, error) {
return cfg, fmt.Errorf("parse %s: %w", path, err) return cfg, fmt.Errorf("parse %s: %w", path, err)
} }
if !md.IsDefined("default_db") || cfg.DefaultDB == "" { if !md.IsDefined("display_ascii_art") {
cfg.DefaultDB = defaultConfig().DefaultDB cfg.DisplayAsciiArt = defaultConfig().DisplayAsciiArt
} }
if !md.IsDefined("display_art") { if !md.IsDefined("key", "always_prompt_delete") {
cfg.DisplayArt = defaultConfig().DisplayArt cfg.Key.AlwaysPromptDelete = defaultConfig().Key.AlwaysPromptDelete
} }
if !md.IsDefined("warn_on_delete") { if !md.IsDefined("store", "default_store_name") || cfg.Store.DefaultStoreName == "" {
cfg.WarnOnDelete = defaultConfig().WarnOnDelete cfg.Store.DefaultStoreName = defaultConfig().Store.DefaultStoreName
}
if !md.IsDefined("store", "always_prompt_delete") {
cfg.Store.AlwaysPromptDelete = defaultConfig().Store.AlwaysPromptDelete
} }
if !md.IsDefined("warn_on_overwrite") { if !md.IsDefined("key", "always_prompt_overwrite") {
cfg.WarnOnOverwrite = defaultConfig().WarnOnOverwrite cfg.Key.AlwaysPromptOverwrite = defaultConfig().Key.AlwaysPromptOverwrite
} }
return cfg, nil return cfg, nil

View file

@ -25,10 +25,10 @@ package cmd
import ( import (
"errors" "errors"
"fmt" "fmt"
"os"
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"os"
) )
// delDbCmd represents the set command // delDbCmd represents the set command
@ -52,26 +52,24 @@ func delDb(cmd *cobra.Command, args []string) error {
return fmt.Errorf("cannot delete-db '%s': %v", args[0], err) return fmt.Errorf("cannot delete-db '%s': %v", args[0], err)
} }
force, err := cmd.Flags().GetBool("force") interactive, err := cmd.Flags().GetBool("interactive")
if err != nil { if err != nil {
return fmt.Errorf("cannot delete-db '%s': %v", args[0], err) return fmt.Errorf("cannot delete-db '%s': %v", args[0], err)
} }
if force { if interactive || config.Store.AlwaysPromptDelete {
return executeDeletion(path) message := fmt.Sprintf("delete-db '%s': are you sure? (y/n)", args[0])
} fmt.Println(message)
message := fmt.Sprintf("delete-db '%s': are you sure? (y/n)", args[0]) var confirm string
fmt.Println(message) if _, err := fmt.Scanln(&confirm); err != nil {
return fmt.Errorf("cannot delete-db '%s': %v", args[0], err)
var confirm string }
if _, err := fmt.Scanln(&confirm); err != nil { if strings.ToLower(confirm) != "y" {
return fmt.Errorf("cannot delete-db '%s': %v", args[0], err) return nil
}
} }
if strings.ToLower(confirm) == "y" { return executeDeletion(path)
return executeDeletion(path)
}
return nil
} }
func executeDeletion(path string) error { func executeDeletion(path string) error {
@ -82,6 +80,6 @@ func executeDeletion(path string) error {
} }
func init() { func init() {
delDbCmd.Flags().BoolP("force", "f", false, "Force delete without confirmation") delDbCmd.Flags().BoolP("interactive", "i", false, "Prompt yes/no for each deletion")
rootCmd.AddCommand(delDbCmd) rootCmd.AddCommand(delDbCmd)
} }

View file

@ -45,7 +45,7 @@ var delCmd = &cobra.Command{
func del(cmd *cobra.Command, args []string) error { func del(cmd *cobra.Command, args []string) error {
store := &Store{} store := &Store{}
force, err := cmd.Flags().GetBool("force") interactive, err := cmd.Flags().GetBool("interactive")
if err != nil { if err != nil {
return err return err
} }
@ -71,23 +71,18 @@ func del(cmd *cobra.Command, args []string) error {
return fmt.Errorf("cannot remove: No such key") return fmt.Errorf("cannot remove: No such key")
} }
if !force && config.WarnOnDelete {
var confirm string
quotedTargets := make([]string, 0, len(targets))
for _, target := range targets {
quotedTargets = append(quotedTargets, fmt.Sprintf("%q", target.display))
}
message := fmt.Sprintf("remove %s: are you sure? (y/n)", strings.Join(quotedTargets, ", "))
fmt.Println(message)
if _, err := fmt.Scanln(&confirm); err != nil {
return fmt.Errorf("cannot remove '%s': %v", args[0], err)
}
if strings.ToLower(confirm) != "y" {
return nil
}
}
for _, target := range targets { for _, target := range targets {
if interactive || config.Key.AlwaysPromptDelete {
var confirm string
message := fmt.Sprintf("remove %q: are you sure? (y/n)", target.display)
fmt.Println(message)
if _, err := fmt.Scanln(&confirm); err != nil {
return fmt.Errorf("cannot remove '%s': %v", target.full, err)
}
if strings.ToLower(confirm) != "y" {
continue
}
}
trans := TransactionArgs{ trans := TransactionArgs{
key: target.full, key: target.full,
readonly: false, readonly: false,
@ -112,7 +107,7 @@ func del(cmd *cobra.Command, args []string) error {
} }
func init() { func init() {
delCmd.Flags().BoolP("force", "f", false, "Force delete without confirmation") delCmd.Flags().BoolP("interactive", "i", false, "Prompt yes/no for each deletion")
delCmd.Flags().StringSliceP("glob", "g", nil, "Delete keys matching glob pattern (repeatable)") delCmd.Flags().StringSliceP("glob", "g", nil, "Delete keys matching glob pattern (repeatable)")
delCmd.Flags().String("glob-sep", "", fmt.Sprintf("Characters treated as separators for globbing (default %q)", defaultGlobSeparatorsDisplay())) delCmd.Flags().String("glob-sep", "", fmt.Sprintf("Characters treated as separators for globbing (default %q)", defaultGlobSeparatorsDisplay()))
rootCmd.AddCommand(delCmd) rootCmd.AddCommand(delCmd)

View file

@ -52,7 +52,7 @@ var dumpCmd = &cobra.Command{
func dump(cmd *cobra.Command, args []string) error { func dump(cmd *cobra.Command, args []string) error {
store := &Store{} store := &Store{}
targetDB := "@" + config.DefaultDB targetDB := "@" + config.Store.DefaultStoreName
if len(args) == 1 { if len(args) == 1 {
rawArg := args[0] rawArg := args[0]
dbName, err := store.parseDB(rawArg, false) dbName, err := store.parseDB(rawArg, false)

View file

@ -59,7 +59,7 @@ func ParseKey(raw string, defaults bool) (KeySpec, error) {
key := strings.ToLower(rawKey) key := strings.ToLower(rawKey)
db := strings.ToLower(rawDB) db := strings.ToLower(rawDB)
if db == "" && defaults { if db == "" && defaults {
db = config.DefaultDB db = config.Store.DefaultStoreName
} }
return KeySpec{ return KeySpec{
@ -82,7 +82,7 @@ func (k KeySpec) Full() string {
// Display returns the normalized key reference // Display returns the normalized key reference
// but omits the default database if none was set manually // but omits the default database if none was set manually
func (k KeySpec) Display() string { func (k KeySpec) Display() string {
if k.DB == "" || k.DB == config.DefaultDB { if k.DB == "" || k.DB == config.Store.DefaultStoreName {
return k.Key return k.Key
} }
return fmt.Sprintf("%s@%s", k.Key, k.DB) return fmt.Sprintf("%s@%s", k.Key, k.DB)

View file

@ -42,7 +42,7 @@ var listCmd = &cobra.Command{
func list(cmd *cobra.Command, args []string) error { func list(cmd *cobra.Command, args []string) error {
store := &Store{} store := &Store{}
targetDB := "@" + config.DefaultDB targetDB := "@" + config.Store.DefaultStoreName
if len(args) == 1 { if len(args) == 1 {
rawArg := args[0] rawArg := args[0]
dbName, err := store.parseDB(rawArg, false) dbName, err := store.parseDB(rawArg, false)

View file

@ -92,7 +92,7 @@ func mv(cmd *cobra.Command, args []string) error {
readonly: false, readonly: false,
sync: false, sync: false,
transact: func(tx *badger.Txn, k []byte) error { transact: func(tx *badger.Txn, k []byte) error {
if !force && config.WarnOnOverwrite { if !force && config.Key.AlwaysPromptOverwrite {
if _, err := tx.Get(k); err == nil { if _, err := tx.Get(k); err == nil {
return fmt.Errorf("cannot move '%s': '%s' already exists > run with --force to overwrite", fromSpec.Key, toSpec.Key) return fmt.Errorf("cannot move '%s': '%s' already exists > run with --force to overwrite", fromSpec.Key, toSpec.Key)
} else if err != badger.ErrKeyNotFound { } else if err != badger.ErrKeyNotFound {

View file

@ -46,7 +46,7 @@ var restoreCmd = &cobra.Command{
func restore(cmd *cobra.Command, args []string) error { func restore(cmd *cobra.Command, args []string) error {
store := &Store{} store := &Store{}
dbName := config.DefaultDB dbName := config.Store.DefaultStoreName
if len(args) == 1 { if len(args) == 1 {
parsed, err := store.parseDB(args[0], false) parsed, err := store.parseDB(args[0], false)
if err != nil { if err != nil {

View file

@ -174,7 +174,7 @@ func (s *Store) parseDB(v string, defaults bool) (string, error) {
} }
if db == "" { if db == "" {
if defaults { if defaults {
return config.DefaultDB, nil return config.Store.DefaultStoreName, nil
} }
return "", fmt.Errorf("cannot parse db: bad db format, use DB or @DB") return "", fmt.Errorf("cannot parse db: bad db format, use DB or @DB")
} }
@ -186,7 +186,7 @@ func (s *Store) parseDB(v string, defaults bool) (string, error) {
func (s *Store) open(name string) (*badger.DB, error) { func (s *Store) open(name string) (*badger.DB, error) {
if name == "" { if name == "" {
name = config.DefaultDB name = config.Store.DefaultStoreName
} }
path, err := s.path(name) path, err := s.path(name)
if err != nil { if err != nil {

View file

@ -36,7 +36,7 @@ var versionCmd = &cobra.Command{
Use: "version", Use: "version",
Short: "Display pda! version", Short: "Display pda! version",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if config.DisplayArt { if config.DisplayAsciiArt {
fmt.Print(asciiArt + "\n ") fmt.Print(asciiArt + "\n ")
} }
fmt.Printf("%s\n", version) fmt.Printf("%s\n", version)