- commit
- c81e86e3ff5b50d8635993ce3a7df0cfaca2cbb7
- parent
- e6ca1238f49c5f1f807a83d2d3b3b3f8e2cd9550
- author
- Dami <dami.etoile@gmail.com>
| M | cmd/ | 4 | ++-- |
| M | cmd/ | 3 | ++- |
| M | cmd/ | 6 | +++--- |
| M | cmd/ | 20 | +++++++++++++------- |
| M | config/ | 13 | +++++++++++-- |
@@ -17,14 +17,14 @@ var continueCmd = &cobra.Command{
1717 Long: "Resume a previously saved game using its unique name.\nUse 'puzzletea list' to see available saved games.",1818 Args: cobra.ExactArgs(1),1919 RunE: func(cmd *cobra.Command, args []string) error {20- cfg := loadConfig()20+ cfg := loadConfig("")2121 return continueGame(args[0], cfg)2222 },2323 }2424 2525 // continueGame looks up a saved game by name and launches the TUI.2626 func continueGame(name string, cfg *config.Config) error {27- s, err := store.Open(store.DefaultDBPath())27+ s, err := store.Open(cfg.DBPath)2828 if err != nil {2929 return err3030 }@@ -17,7 +17,8 @@ var listCmd = &cobra.Command{
1717 Short: "List saved games",1818 Long: "Display a table of saved games. Use --all to include abandoned games.",1919 RunE: func(cmd *cobra.Command, args []string) error {20- s, err := store.Open(store.DefaultDBPath())20+ cfg := loadConfig(flagConfigPath)21+ s, err := store.Open(cfg.DBPath)2122 if err != nil {2223 return err2324 }@@ -34,7 +34,7 @@ var newCmd = &cobra.Command{
3434 return runNewExport(cmd, args)3535 }3636 37- cfg := loadConfig()37+ cfg := loadConfig("")3838 3939 if flagSetSeed != "" {4040 if len(args) > 0 {@@ -78,7 +78,7 @@ func launchNewGame(gameArg, modeArg, seed string, cfg *config.Config) error {
7878 return fmt.Errorf("failed to spawn game: %w", err)7979 }8080 81- s, err := store.Open(store.DefaultDBPath())81+ s, err := store.Open(cfg.DBPath)8282 if err != nil {8383 return err8484 }@@ -129,7 +129,7 @@ func launchSeededGame(seed string, cfg *config.Config) error {
129129 nameRNG := resolve.RNGFromString("name:" + seed)130130 name := seed + " - " + namegen.GenerateSeeded(nameRNG)131131 132- s, err := store.Open(store.DefaultDBPath())132+ s, err := store.Open(cfg.DBPath)133133 if err != nil {134134 return err135135 }@@ -22,9 +22,10 @@ import (
2222 var Version = "dev"2323 2424 var (25- flagNew string26- flagContinue string27- flagTheme string25+ flagNew string26+ flagContinue string27+ flagTheme string28+ flagConfigPath string2829 // flagSetSeed is declared in new.go and shared across root and new commands.2930 )3031 @@ -35,7 +36,7 @@ var RootCmd = &cobra.Command{
3536 Short: "A terminal-based puzzle game framework",3637 Long: "PuzzleTea is a terminal-based puzzle game framework featuring Nonogram, Nurikabe, Sudoku, Word Search, Hashiwokakero, and Lights Out.",3738 RunE: func(cmd *cobra.Command, args []string) error {38- cfg := loadConfig()39+ cfg := loadConfig(flagConfigPath)3940 4041 if flagSetSeed != "" {4142 if flagNew != "" || flagContinue != "" {@@ -56,7 +57,7 @@ var RootCmd = &cobra.Command{
5657 return continueGame(flagContinue, cfg)5758 }5859 // Default: launch TUI menu.59- s, err := store.Open(store.DefaultDBPath())60+ s, err := store.Open(cfg.DBPath)6061 if err != nil {6162 return err6263 }@@ -72,6 +73,7 @@ func init() {
7273 RootCmd.Flags().StringVar(&flagNew, "new", "", "start a new game (game:mode)")7374 RootCmd.Flags().StringVar(&flagContinue, "continue", "", "resume a saved game by name")7475 RootCmd.Flags().StringVar(&flagSetSeed, "set-seed", "", "seed string for deterministic puzzle selection and generation")76+ RootCmd.PersistentFlags().StringVar(&flagConfigPath, "config", "", "path to config file (default: ~/.puzzletea/config.json)")7577 RootCmd.PersistentFlags().StringVar(&flagTheme, "theme", "", "color theme name (overrides config)")7678 7779 RootCmd.AddCommand(newCmd, continueCmd, listCmd, exportPDFCmd)@@ -79,8 +81,12 @@ func init() {
7981 8082 // loadConfig reads the config file and applies the active theme. The --theme8183 // flag takes precedence over the persisted setting.82-func loadConfig() *config.Config {83- cfg, err := config.Load(config.DefaultPath())84+func loadConfig(configPath string) *config.Config {85+ if configPath == "" {86+ configPath = config.DefaultPath()87+ }88+89+ cfg, err := config.Load(configPath)8490 if err != nil {8591 log.Printf("warning: %v (using defaults)", err)8692 cfg = config.Default()@@ -13,13 +13,22 @@ import (
1313 1414 // Config holds all user-configurable settings.1515 type Config struct {16- Theme string `json:"theme,omitempty"` // theme name; empty = default16+ Theme string `json:"theme,omitempty"` // theme name; empty = default17+ DBPath string `json:"db_path,omitempty"` // database path; empty = ~/.puzzletea/history.db1718 }1819 1920 // Default returns a Config with all settings at their zero values (the2021 // built-in defaults).2122 func Default() *Config {22- return &Config{}23+ return &Config{24+ DBPath: DefaultDBPath(),25+ }26+}27+28+// DefaultDBPath returns the default database path ~/.puzzletea/history.db.29+func DefaultDBPath() string {30+ home, _ := os.UserHomeDir()31+ return filepath.Join(home, ".puzzletea", "history.db")2332 }2433 2534 // DefaultPath returns ~/.puzzletea/config.json.