From 33e774d078cb5563c968185b4bd78dbc323f7f89 Mon Sep 17 00:00:00 2001 From: Mathis Maquenne <124215603+mathismqn@users.noreply.github.com> Date: Mon, 23 Jun 2025 20:24:45 -0400 Subject: [PATCH] refactor: simplify homeDir and appConfig usage --- cmd/download.go | 17 +++++++++++++++-- cmd/root.go | 17 +++-------------- cmd/watch_run.go | 13 +++++++++++++ internal/config/config.go | 13 +++++++------ internal/watcher/autostart.go | 10 +++++----- internal/watcher/install_mac.go | 4 ++-- internal/watcher/watcher.go | 3 +-- 7 files changed, 46 insertions(+), 31 deletions(-) diff --git a/cmd/download.go b/cmd/download.go index d857ab8..46fc4bf 100644 --- a/cmd/download.go +++ b/cmd/download.go @@ -6,11 +6,15 @@ import ( "fmt" "time" + "github.com/mathismqn/godeez/internal/config" "github.com/mathismqn/godeez/internal/downloader" "github.com/spf13/cobra" ) -var opts downloader.Options +var ( + opts downloader.Options + cfgPath string +) var downloadCmd = &cobra.Command{ Use: "download", @@ -20,6 +24,7 @@ var downloadCmd = &cobra.Command{ func init() { RootCmd.AddCommand(downloadCmd) + downloadCmd.PersistentFlags().StringVar(&cfgPath, "config", "", "config file (default ~/.godeez/config.toml)") downloadCmd.PersistentFlags().StringVarP(&opts.Quality, "quality", "q", "best", "download quality [mp3_128, mp3_320, flac, best]") downloadCmd.PersistentFlags().DurationVarP(&opts.Timeout, "timeout", "t", 2*time.Minute, "timeout for each download (e.g. 10s, 1m, 2m30s)") downloadCmd.PersistentFlags().BoolVar(&opts.BPM, "bpm", false, "fetch BPM/key and add to file tags") @@ -42,12 +47,20 @@ func newDownloadCmd(resourceType string) *cobra.Command { Short: fmt.Sprintf("Download songs from %s %s", article, resourceType), Args: cobra.ExactArgs(1), PreRunE: func(cmd *cobra.Command, args []string) error { + appConfig, err := config.New(cfgPath) + if err != nil { + return err + } + cmd.SetContext(context.WithValue(cmd.Context(), "appConfig", appConfig)) + return opts.Validate() }, RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - dl := downloader.New(appConfig, resourceType) + appConfigVal := ctx.Value("appConfig") + appConfig, _ := appConfigVal.(*config.Config) + dl := downloader.New(appConfig, resourceType) if err := dl.Run(ctx, opts, args[0]); err != nil { if errors.Is(err, context.Canceled) { return nil diff --git a/cmd/root.go b/cmd/root.go index 350568e..a618f68 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,35 +4,24 @@ import ( "fmt" "os" - "github.com/mathismqn/godeez/internal/config" "github.com/mathismqn/godeez/internal/watcher" "github.com/spf13/cobra" ) -var ( - cfgPath string - appConfig *config.Config -) - var RootCmd = &cobra.Command{ Use: "godeez", Short: "GoDeez is a tool to download music from Deezer", SilenceUsage: true, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - var err error - appConfig, err = config.New(cfgPath) + homeDir, err := os.UserHomeDir() if err != nil { - return err + return fmt.Errorf("failed to get home directory: %w", err) } - if err := watcher.EnsureAutostart(); err != nil { + if err := watcher.EnsureAutostart(homeDir); err != nil { fmt.Fprintf(os.Stderr, "Warning: failed to install autostart for watcher: %v\n", err) } return nil }, } - -func init() { - RootCmd.PersistentFlags().StringVar(&cfgPath, "config", "", "config file (default ~/.godeez/config.toml)") -} diff --git a/cmd/watch_run.go b/cmd/watch_run.go index b3177db..6acbc64 100644 --- a/cmd/watch_run.go +++ b/cmd/watch_run.go @@ -1,6 +1,9 @@ package cmd import ( + "context" + + "github.com/mathismqn/godeez/internal/config" "github.com/mathismqn/godeez/internal/watcher" "github.com/spf13/cobra" ) @@ -9,8 +12,18 @@ var watchRunCmd = &cobra.Command{ Use: "run", Short: "Start the background playlist watcher", Hidden: true, + PreRun: func(cmd *cobra.Command, args []string) { + appConfig, err := config.New("") + if err != nil { + return + } + cmd.SetContext(context.WithValue(cmd.Context(), "appConfig", appConfig)) + }, Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() + appConfigVal := ctx.Value("appConfig") + appConfig, _ := appConfigVal.(*config.Config) + w := watcher.New(appConfig) w.Run(ctx, opts) }, diff --git a/internal/config/config.go b/internal/config/config.go index 72e09b4..a57b8bb 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -15,6 +15,7 @@ type Config struct { ArlCookie string `mapstructure:"arl_cookie"` SecretKey string `mapstructure:"secret_key"` OutputDir string `mapstructure:"output_dir"` + HomeDir string } func New(cfgPath string) (*Config, error) { @@ -49,11 +50,11 @@ func New(cfgPath string) (*Config, error) { return nil, fmt.Errorf("failed to read config file: %w", err) } - var cfg Config - if err := viper.Unmarshal(&cfg); err != nil { + cfg := &Config{HomeDir: homeDir} + if err := viper.Unmarshal(cfg); err != nil { return nil, fmt.Errorf("failed to parse config: %w", err) } - if err := cfg.Validate(homeDir); err != nil { + if err := cfg.Validate(); err != nil { return nil, fmt.Errorf("invalid config: %w", err) } @@ -61,10 +62,10 @@ func New(cfgPath string) (*Config, error) { return nil, err } - return &cfg, nil + return cfg, nil } -func (c *Config) Validate(homeDir string) error { +func (c *Config) Validate() error { if c.ArlCookie == "" { return fmt.Errorf("arl_cookie is not set") } @@ -75,7 +76,7 @@ func (c *Config) Validate(homeDir string) error { return fmt.Errorf("secret_key must be 16 bytes long") } if c.OutputDir == "" { - c.OutputDir = filepath.Join(homeDir, "Music", "GoDeez") + c.OutputDir = filepath.Join(c.HomeDir, "Music", "GoDeez") } return nil diff --git a/internal/watcher/autostart.go b/internal/watcher/autostart.go index dad1ae4..b9eb69f 100644 --- a/internal/watcher/autostart.go +++ b/internal/watcher/autostart.go @@ -7,18 +7,18 @@ import ( "strings" ) -func EnsureAutostart() error { - if isAutostartInstalled() || isTemporaryExecutable() { +func EnsureAutostart(homeDir string) error { + if isAutostartInstalled(homeDir) || isTemporaryExecutable() { return nil } - return installAutostart() + return installAutostart(homeDir) } -func isAutostartInstalled() bool { +func isAutostartInstalled(homeDir string) bool { switch runtime.GOOS { case "darwin": - path := filepath.Join(os.Getenv("HOME"), "Library", "LaunchAgents", "com.godeez.watch.plist") + path := filepath.Join(homeDir, "Library", "LaunchAgents", "com.godeez.watch.plist") _, err := os.Stat(path) return err == nil diff --git a/internal/watcher/install_mac.go b/internal/watcher/install_mac.go index 440e4ce..a159af2 100644 --- a/internal/watcher/install_mac.go +++ b/internal/watcher/install_mac.go @@ -9,7 +9,7 @@ import ( "path/filepath" ) -func installAutostart() error { +func installAutostart(homeDir string) error { exe, err := os.Executable() if err != nil { return err @@ -39,7 +39,7 @@ func installAutostart() error { `, exe) - path := filepath.Join(os.Getenv("HOME"), "Library", "LaunchAgents", "com.godeez.watch.plist") + path := filepath.Join(homeDir, "Library", "LaunchAgents", "com.godeez.watch.plist") if err := os.WriteFile(path, []byte(plist), 0644); err != nil { return err } diff --git a/internal/watcher/watcher.go b/internal/watcher/watcher.go index b922a18..c156db7 100644 --- a/internal/watcher/watcher.go +++ b/internal/watcher/watcher.go @@ -20,8 +20,7 @@ type Watcher struct { } func New(appConfig *config.Config) *Watcher { - homeDir, _ := os.UserHomeDir() - logFile := filepath.Join(homeDir, ".godeez", "watcher.log") + logFile := filepath.Join(appConfig.HomeDir, ".godeez", "watcher.log") file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { log.Fatalf("Failed to open log file: %v\n", err)