From ba6bf2f34cff2ab67493c38088879f947075e0b9 Mon Sep 17 00:00:00 2001 From: arnef Date: Fri, 14 Aug 2026 21:00:15 +0200 Subject: [PATCH] feat: allow overriding the output directory via GODEEZ_OUTPUT_DIR The output directory used to be fixed at ~/Music/GoDeez. config.Load now honours GODEEZ_OUTPUT_DIR when set, with a leading ~ expanded by hand since the shell only does that for unquoted arguments, not for values read out of the environment. Falls back to the previous default when unset. --- README.md | 8 ++++++++ internal/config/config.go | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0cb5a9e..4a9f8f8 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,14 @@ export DEEZER_MOBILE_GW_KEY="your_gateway_key" # exactly 16 characters Downloaded files are saved to `~/Music/GoDeez`. The download database (`.tracks.db`) is stored in the same directory as your music. +To use a different location, set `GODEEZ_OUTPUT_DIR`: + +```bash +export GODEEZ_OUTPUT_DIR="/path/to/your/music" +``` + +A leading `~` is expanded to your home directory. + > **Upgrading from v1.3.0?** The `~/.godeez` directory and `config.toml` are no longer used. Set the `DEEZER_ARL` environment variable instead. Your existing database will be migrated automatically on first run. ## Usage diff --git a/internal/config/config.go b/internal/config/config.go index 211f98b..b667a57 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,6 +1,7 @@ // Package config resolves where godeez reads its session from and writes its -// downloads to. There is no config file: the output directory is fixed and -// the only setting is the DEEZER_ARL environment variable, which exists as an +// downloads to. There is no config file: the output directory defaults to +// ~/Music/GoDeez but can be overridden with GODEEZ_OUTPUT_DIR, and the only +// other setting is the DEEZER_ARL environment variable, which exists as an // escape hatch for users who would rather not store credentials in the system // keyring. package config @@ -9,6 +10,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/mathismqn/godeez/internal/fsutil" ) @@ -27,12 +29,11 @@ type Config struct { func Load() (*Config, error) { arl := os.Getenv("DEEZER_ARL") - homeDir, err := os.UserHomeDir() + outputDir, err := resolveOutputDir() if err != nil { - return nil, fmt.Errorf("failed to get home directory: %w", err) + return nil, err } - outputDir := filepath.Join(homeDir, "Music", "GoDeez") if err := fsutil.EnsureDir(outputDir); err != nil { return nil, fmt.Errorf("failed to create output directory: %w", err) } @@ -42,3 +43,29 @@ func Load() (*Config, error) { OutputDir: outputDir, }, nil } + +// resolveOutputDir honours GODEEZ_OUTPUT_DIR when set, falling back to +// ~/Music/GoDeez otherwise. +// +// A leading "~" is expanded by hand because the shell only does that for +// unquoted arguments, not for values read out of the environment, so users +// setting this in a profile file would otherwise end up with a literal "~" +// directory. +func resolveOutputDir() (string, error) { + homeDir, err := os.UserHomeDir() + if err != nil { + return "", fmt.Errorf("failed to get home directory: %w", err) + } + + if dir := strings.TrimSpace(os.Getenv("GODEEZ_OUTPUT_DIR")); dir != "" { + if dir == "~" { + return homeDir, nil + } + if rest, ok := strings.CutPrefix(dir, "~/"); ok { + return filepath.Join(homeDir, rest), nil + } + return dir, nil + } + + return filepath.Join(homeDir, "Music", "GoDeez"), nil +}