diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-06 10:58:58 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-06 10:58:58 +0300 |
| commit | 23160bce9a18a70080a85dda6e9c654499aba7f7 (patch) | |
| tree | ec0f9930233aef96a221980310073081679bb4bb /cmd | |
| parent | 95dd36d28d18615ad3f8dd7122a404850dcb39f8 (diff) | |
refactor: remove Viper coupling from processor package (DIP)
Resolve all Viper config values once at startup in cmd/totalrecall/main.go
via the new newProcessorConfig() helper. The exported processor.Config struct
replaces the internal viperConfig type, and NewProcessor now accepts *Config
instead of querying Viper internally. The processor package no longer imports
Viper at all. Tests are updated to pass Config values directly, eliminating
the viper.Set/Reset boilerplate that coupled tests to the global singleton.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/totalrecall/main.go | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/cmd/totalrecall/main.go b/cmd/totalrecall/main.go index a3523ce..9e64897 100644 --- a/cmd/totalrecall/main.go +++ b/cmd/totalrecall/main.go @@ -4,8 +4,10 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/spf13/cobra" + "github.com/spf13/viper" "codeberg.org/snonux/totalrecall/internal/archive" "codeberg.org/snonux/totalrecall/internal/cli" @@ -16,6 +18,48 @@ import ( "codeberg.org/snonux/totalrecall/internal/story" ) +// newProcessorConfig reads all Viper-sourced settings in a single pass and +// returns a fully-resolved processor.Config. Centralising all Viper access +// here means the processor package is free of any Viper dependency, which +// improves testability and removes tight coupling to the global config singleton. +func newProcessorConfig() *processor.Config { + return &processor.Config{ + // Translation & phonetic + TranslationProvider: strings.TrimSpace(viper.GetString("translation.provider")), + PhoneticProvider: strings.TrimSpace(viper.GetString("phonetic.provider")), + TranslationGeminiModel: viper.GetString("translation.gemini_model"), + + // Audio + AudioProvider: strings.ToLower(strings.TrimSpace(viper.GetString("audio.provider"))), + AudioFormat: strings.ToLower(strings.TrimSpace(viper.GetString("audio.format"))), + AudioFormatSet: viper.IsSet("audio.format"), + GeminiTTSModel: strings.TrimSpace(viper.GetString("audio.gemini_tts_model")), + GeminiVoice: strings.TrimSpace(viper.GetString("audio.gemini_voice")), + OpenAIVoice: strings.TrimSpace(viper.GetString("audio.openai_voice")), + OpenAIModel: viper.GetString("audio.openai_model"), + OpenAIModelSet: viper.IsSet("audio.openai_model"), + OpenAISpeed: viper.GetFloat64("audio.openai_speed"), + OpenAISpeedSet: viper.IsSet("audio.openai_speed"), + OpenAIInstruction: viper.GetString("audio.openai_instruction"), + OpenAIInstructionSet: viper.IsSet("audio.openai_instruction"), + + // Image + ImageProvider: strings.ToLower(strings.TrimSpace(viper.GetString("image.provider"))), + ImageOpenAIModel: viper.GetString("image.openai_model"), + ImageOpenAIModelSet: viper.IsSet("image.openai_model"), + ImageOpenAISize: viper.GetString("image.openai_size"), + ImageOpenAISizeSet: viper.IsSet("image.openai_size"), + ImageOpenAIQuality: viper.GetString("image.openai_quality"), + ImageOpenAIQualitySet: viper.IsSet("image.openai_quality"), + ImageOpenAIStyle: viper.GetString("image.openai_style"), + ImageOpenAIStyleSet: viper.IsSet("image.openai_style"), + ImageNanoBananaModel: strings.TrimSpace(viper.GetString("image.nanobanana_model")), + ImageNanoBananaModelSet: viper.IsSet("image.nanobanana_model"), + ImageNanoBananaTextModel: strings.TrimSpace(viper.GetString("image.nanobanana_text_model")), + ImageNanoBananaTextModelSet: viper.IsSet("image.nanobanana_text_model"), + } +} + func main() { // Create flags instance flags := cli.NewFlags() @@ -83,8 +127,9 @@ func runCommand(cmd *cobra.Command, args []string, flags *cli.Flags) error { fmt.Printf("Note: Using image size 1024x1024 for DALL-E 3 (use --openai-image-size to override)\n") } - // Create processor - proc := processor.NewProcessor(flags) + // Resolve all Viper config values once here so the processor never touches + // the global Viper singleton directly (Dependency Inversion Principle). + proc := processor.NewProcessor(flags, newProcessorConfig()) // Handle batch processing if flags.BatchFile != "" { |
