diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-02 09:24:23 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-02 09:24:23 +0300 |
| commit | 6ce9123de04ffff961cbf1da73648679216ff637 (patch) | |
| tree | 7a8c12f3499b0a62471627773fde9588a14c9261 /internal | |
| parent | faee049f51a3e6125a710fae3e713638bd68dd48 (diff) | |
Fix verification gate lint and test issues
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/audio/gemini_provider.go | 10 | ||||
| -rw-r--r-- | internal/audio/provider.go | 2 | ||||
| -rw-r--r-- | internal/audio/provider_test.go | 2 | ||||
| -rw-r--r-- | internal/gui/app.go | 7 | ||||
| -rw-r--r-- | internal/gui/generator.go | 2 | ||||
| -rw-r--r-- | internal/image/nanobanana.go | 2 | ||||
| -rw-r--r-- | internal/image/openai.go | 17 | ||||
| -rw-r--r-- | internal/models/lister.go | 82 | ||||
| -rw-r--r-- | internal/phonetic/fetcher.go | 8 | ||||
| -rw-r--r-- | internal/phonetic/fetcher_test.go | 6 | ||||
| -rw-r--r-- | internal/processor/processor.go | 2 | ||||
| -rw-r--r-- | internal/processor/processor_test.go | 6 | ||||
| -rw-r--r-- | internal/translation/translator.go | 8 | ||||
| -rw-r--r-- | internal/translation/translator_test.go | 4 |
14 files changed, 104 insertions, 54 deletions
diff --git a/internal/audio/gemini_provider.go b/internal/audio/gemini_provider.go index 1d82f2d..5662454 100644 --- a/internal/audio/gemini_provider.go +++ b/internal/audio/gemini_provider.go @@ -33,7 +33,7 @@ var _ Provider = (*GeminiProvider)(nil) func NewGeminiProvider(config *Config) (Provider, error) { normalized := normalizeGeminiConfig(config) if normalized.GoogleAPIKey == "" { - return nil, errors.New("Google API key is required") + return nil, errors.New("google API key is required") } client, err := genai.NewClient(context.Background(), &genai.ClientConfig{ @@ -56,7 +56,7 @@ func (p *GeminiProvider) GenerateAudio(ctx context.Context, text string, outputF return err } if p == nil || p.client == nil || p.config == nil { - return errors.New("Gemini client not initialized") + return errors.New("gemini client not initialized") } prompt := p.buildPrompt(text) @@ -69,7 +69,7 @@ func (p *GeminiProvider) GenerateAudio(ctx context.Context, text string, outputF genai.NewContentFromText(prompt, genai.RoleUser), }, req) if err != nil { - return fmt.Errorf("Gemini API error: %w", err) + return fmt.Errorf("gemini API error: %w", err) } audioData, mimeType, err := extractAudioData(response) @@ -92,7 +92,7 @@ func (p *GeminiProvider) Name() string { // IsAvailable checks if the Google API key is configured. func (p *GeminiProvider) IsAvailable() error { if p == nil || p.config == nil || strings.TrimSpace(p.config.GoogleAPIKey) == "" { - return errors.New("Google API key not configured") + return errors.New("google API key not configured") } return nil @@ -183,7 +183,7 @@ func writeGeminiAudioFile(outputFile string, audioData []byte, mimeType string) ext := strings.ToLower(filepath.Ext(outputFile)) if ext != ".wav" { - return fmt.Errorf("Gemini TTS only supports .wav output files, got %q", outputFile) + return fmt.Errorf("gemini TTS only supports .wav output files, got %q", outputFile) } encoded, err := encodePCMAsWAV(audioData) diff --git a/internal/audio/provider.go b/internal/audio/provider.go index 06ed6d0..b7f6bd9 100644 --- a/internal/audio/provider.go +++ b/internal/audio/provider.go @@ -67,7 +67,7 @@ func NewProvider(config *Config) (Provider, error) { return NewOpenAIProvider(config) case "gemini": if config.GoogleAPIKey == "" { - return nil, fmt.Errorf("Google API key is required") + return nil, fmt.Errorf("google API key is required") } return NewGeminiProvider(config) default: diff --git a/internal/audio/provider_test.go b/internal/audio/provider_test.go index 64fbcc7..c13e823 100644 --- a/internal/audio/provider_test.go +++ b/internal/audio/provider_test.go @@ -98,7 +98,7 @@ func TestNewProvider(t *testing.T) { name: "nil config uses defaults", config: nil, wantErr: true, - errMsg: "Google API key is required", + errMsg: "google API key is required", }, { name: "openai provider without key", diff --git a/internal/gui/app.go b/internal/gui/app.go index a69b178..5d24e6d 100644 --- a/internal/gui/app.go +++ b/internal/gui/app.go @@ -629,8 +629,9 @@ func (a *Application) onSubmit() { return } - // Handle English to Bulgarian translation first if needed - if translationDirection == "en-to-bg" { + // Handle translation first if needed. + switch translationDirection { + case "en-to-bg": a.updateStatus(fmt.Sprintf("Translating '%s' to Bulgarian...", secondaryText)) bulgarian, err := a.translateEnglishToBulgarian(secondaryText) if err != nil { @@ -643,7 +644,7 @@ func (a *Application) onSubmit() { a.currentWord = bulgarian a.saveTranslation() needsTranslation = false - } else if translationDirection == "bg-to-en" { + case "bg-to-en": a.updateStatus(fmt.Sprintf("Translating '%s' to English...", bulgarianText)) english, err := a.translateWord(bulgarianText) if err != nil { diff --git a/internal/gui/generator.go b/internal/gui/generator.go index 45cd7bc..f19f46e 100644 --- a/internal/gui/generator.go +++ b/internal/gui/generator.go @@ -383,7 +383,7 @@ func (a *Application) newImageSearcher() (promptAwareImageClient, error) { config = DefaultConfig() } if config.GoogleAPIKey == "" { - return nil, fmt.Errorf("Google API key is required for image generation") + return nil, fmt.Errorf("google API key is required for image generation") } nanoBananaConfig := &image.NanoBananaConfig{ diff --git a/internal/image/nanobanana.go b/internal/image/nanobanana.go index 7c1ba26..ae67513 100644 --- a/internal/image/nanobanana.go +++ b/internal/image/nanobanana.go @@ -419,7 +419,7 @@ func (c *NanoBananaClient) generateText(ctx context.Context, model, systemPrompt MaxOutputTokens: maxOutputTokens, }) if err != nil { - return "", fmt.Errorf("Gemini API error: %w", err) + return "", fmt.Errorf("gemini API error: %w", err) } text := strings.TrimSpace(resp.Text()) diff --git a/internal/image/openai.go b/internal/image/openai.go index 79fbe38..7673b7d 100644 --- a/internal/image/openai.go +++ b/internal/image/openai.go @@ -207,16 +207,17 @@ func (c *OpenAIClient) Download(ctx context.Context, url string) (io.ReadCloser, // GetAttribution returns the required attribution text func (c *OpenAIClient) GetAttribution(result *SearchResult) string { - attribution := fmt.Sprintf("Image generated by OpenAI DALL-E\n\n") - attribution += fmt.Sprintf("Model: %s\n", c.model) - attribution += fmt.Sprintf("Size: %s\n", c.size) + var attribution strings.Builder + attribution.WriteString("Image generated by OpenAI DALL-E\n\n") + fmt.Fprintf(&attribution, "Model: %s\n", c.model) + fmt.Fprintf(&attribution, "Size: %s\n", c.size) if c.model == "dall-e-3" { - attribution += fmt.Sprintf("Quality: %s\n", c.quality) - attribution += fmt.Sprintf("Style: %s\n", c.style) + fmt.Fprintf(&attribution, "Quality: %s\n", c.quality) + fmt.Fprintf(&attribution, "Style: %s\n", c.style) } - attribution += fmt.Sprintf("\nPrompt used:\n%s\n", c.lastPrompt) - attribution += fmt.Sprintf("\nGenerated at: %s\n", time.Now().Format("2006-01-02 15:04:05")) - return attribution + fmt.Fprintf(&attribution, "\nPrompt used:\n%s\n", c.lastPrompt) + fmt.Fprintf(&attribution, "\nGenerated at: %s\n", time.Now().Format("2006-01-02 15:04:05")) + return attribution.String() } // Name returns the name of the provider diff --git a/internal/models/lister.go b/internal/models/lister.go index c798dc6..ca3d3a2 100644 --- a/internal/models/lister.go +++ b/internal/models/lister.go @@ -66,7 +66,9 @@ func (l *Lister) ListAvailableModels() error { return fmt.Errorf("no API keys found. Set OPENAI_API_KEY and/or GOOGLE_API_KEY environment variable(s) or configure them in .totalrecall.yaml") } - fmt.Fprintln(l.out, "Available Models:") + if err := l.writeLine("Available Models:"); err != nil { + return err + } printedSection := false if l.openAIKey != "" { @@ -78,7 +80,9 @@ func (l *Lister) ListAvailableModels() error { if l.geminiKey != "" { if printedSection { - fmt.Fprintln(l.out) + if err := l.writeLine(""); err != nil { + return err + } } if err := l.printGeminiModels(); err != nil { return err @@ -118,26 +122,42 @@ func (l *Lister) printOpenAIModels() error { sort.Strings(imageModels) sort.Strings(chatModels) - fmt.Fprintln(l.out, "OpenAI Models:") - fmt.Fprintln(l.out, " Text-to-Speech (TTS) Models:") + if err := l.writeLine("OpenAI Models:"); err != nil { + return err + } + if err := l.writeLine(" Text-to-Speech (TTS) Models:"); err != nil { + return err + } if len(ttsModels) == 0 { - fmt.Fprintln(l.out, " No TTS models found") + if err := l.writeLine(" No TTS models found"); err != nil { + return err + } } else { for _, model := range ttsModels { - fmt.Fprintf(l.out, " %s\n", model) + if err := l.writeLine(" " + model); err != nil { + return err + } } } - fmt.Fprintln(l.out, " Image Generation Models:") + if err := l.writeLine(" Image Generation Models:"); err != nil { + return err + } if len(imageModels) == 0 { - fmt.Fprintln(l.out, " No image models found") + if err := l.writeLine(" No image models found"); err != nil { + return err + } } else { for _, model := range imageModels { - fmt.Fprintf(l.out, " %s\n", model) + if err := l.writeLine(" " + model); err != nil { + return err + } } } - fmt.Fprintln(l.out, " Chat/Translation Models (for Bulgarian translation):") + if err := l.writeLine(" Chat/Translation Models (for Bulgarian translation):"); err != nil { + return err + } if len(chatModels) > 10 { // Show only relevant models relevantModels := []string{} @@ -147,12 +167,18 @@ func (l *Lister) printOpenAIModels() error { } } for _, model := range relevantModels { - fmt.Fprintf(l.out, " %s\n", model) + if err := l.writeLine(" " + model); err != nil { + return err + } + } + if err := l.writeFormatted(" ... and %d more models\n", len(chatModels)-len(relevantModels)); err != nil { + return err } - fmt.Fprintf(l.out, " ... and %d more models\n", len(chatModels)-len(relevantModels)) } else { for _, model := range chatModels { - fmt.Fprintf(l.out, " %s\n", model) + if err := l.writeLine(" " + model); err != nil { + return err + } } } @@ -164,7 +190,7 @@ func (l *Lister) printGeminiModels() error { return fmt.Errorf("failed to initialize Gemini client: %w", l.geminiInitErr) } if l.geminiClient == nil { - return fmt.Errorf("Gemini client not initialized") + return fmt.Errorf("gemini client not initialized") } ctx := context.Background() @@ -189,14 +215,36 @@ func (l *Lister) printGeminiModels() error { sort.Strings(geminiModels) - fmt.Fprintln(l.out, "Gemini Models:") + if err := l.writeLine("Gemini Models:"); err != nil { + return err + } if len(geminiModels) == 0 { - fmt.Fprintln(l.out, " No Gemini models found") + if err := l.writeLine(" No Gemini models found"); err != nil { + return err + } return nil } for _, model := range geminiModels { - fmt.Fprintf(l.out, " %s\n", model) + if err := l.writeLine(" " + model); err != nil { + return err + } + } + + return nil +} + +func (l *Lister) writeLine(text string) error { + if _, err := fmt.Fprintln(l.out, text); err != nil { + return fmt.Errorf("write model list output: %w", err) + } + + return nil +} + +func (l *Lister) writeFormatted(format string, args ...any) error { + if _, err := fmt.Fprintf(l.out, format, args...); err != nil { + return fmt.Errorf("write model list output: %w", err) } return nil diff --git a/internal/phonetic/fetcher.go b/internal/phonetic/fetcher.go index e6f9694..5d39fc3 100644 --- a/internal/phonetic/fetcher.go +++ b/internal/phonetic/fetcher.go @@ -88,7 +88,7 @@ var fetchGeminiPhonetic = func(ctx context.Context, client *genai.Client, word s MaxOutputTokens: phoneticMaxTokens, }) if err != nil { - return "", fmt.Errorf("Gemini API error: %w", err) + return "", fmt.Errorf("gemini API error: %w", err) } phoneticInfo := strings.TrimSpace(resp.Text()) @@ -181,13 +181,13 @@ func (f *Fetcher) fetchWithOpenAI(ctx context.Context, word string) (string, err func (f *Fetcher) fetchWithGemini(ctx context.Context, word string) (string, error) { if f.googleAPIKey == "" { - return "", fmt.Errorf("Google API key not configured") + return "", fmt.Errorf("google API key not configured") } if f.geminiInitErr != nil { - return "", fmt.Errorf("Gemini client initialization failed: %w", f.geminiInitErr) + return "", fmt.Errorf("gemini client initialization failed: %w", f.geminiInitErr) } if f.geminiClient == nil { - return "", fmt.Errorf("Gemini client not initialized") + return "", fmt.Errorf("gemini client not initialized") } return fetchGeminiPhonetic(ctx, f.geminiClient, word) diff --git a/internal/phonetic/fetcher_test.go b/internal/phonetic/fetcher_test.go index c577d5d..7fa74e8 100644 --- a/internal/phonetic/fetcher_test.go +++ b/internal/phonetic/fetcher_test.go @@ -45,8 +45,8 @@ func TestFetchAndSave_NoGoogleAPIKey(t *testing.T) { t.Fatal("expected error for missing Google API key") } - if err.Error() != "Google API key not configured" { - t.Fatalf("expected Google API key error, got %v", err) + if err.Error() != "google API key not configured" { + t.Fatalf("expected google API key error, got %v", err) } } @@ -205,7 +205,7 @@ func TestFetchAndSave_GeminiInitFailure(t *testing.T) { t.Fatal("expected Gemini init failure") } - if err.Error() != "Gemini client initialization failed: context canceled" { + if err.Error() != "gemini client initialization failed: context canceled" { t.Fatalf("unexpected Gemini init error: %v", err) } } diff --git a/internal/processor/processor.go b/internal/processor/processor.go index 036fa79..8536b98 100644 --- a/internal/processor/processor.go +++ b/internal/processor/processor.go @@ -793,7 +793,7 @@ func (p *Processor) newNanoBananaImageSearcher() (image.ImageSearcher, error) { } if nanoBananaConfig.APIKey == "" { - return nil, fmt.Errorf("Google API key is required for image generation") + return nil, fmt.Errorf("google API key is required for image generation") } return newNanoBananaImageClient(nanoBananaConfig), nil diff --git a/internal/processor/processor_test.go b/internal/processor/processor_test.go index b746a84..e75fa8d 100644 --- a/internal/processor/processor_test.go +++ b/internal/processor/processor_test.go @@ -212,7 +212,7 @@ func TestNewProcessor_ExplicitGeminiTranslationProvider(t *testing.T) { if err == nil { t.Fatal("Expected error for missing Google API key") } - if err.Error() != "Google API key not found" { + if err.Error() != "google API key not found" { t.Fatalf("Expected Gemini provider error, got: %v", err) } } @@ -1248,8 +1248,8 @@ func TestNewImageSearcherConfiguredNanoBananaRequiresGoogleAPIKey(t *testing.T) if err == nil { t.Fatal("expected error when Google API key is missing for Nano Banana") } - if got := err.Error(); got != "Google API key is required for image generation" { - t.Fatalf("newImageSearcher() error = %q, want %q", got, "Google API key is required for image generation") + if got := err.Error(); got != "google API key is required for image generation" { + t.Fatalf("newImageSearcher() error = %q, want %q", got, "google API key is required for image generation") } } diff --git a/internal/translation/translator.go b/internal/translation/translator.go index 09a1e67..b2e997e 100644 --- a/internal/translation/translator.go +++ b/internal/translation/translator.go @@ -172,13 +172,13 @@ func (t *Translator) translateWithOpenAI(prompt string) (string, error) { func (t *Translator) translateWithGemini(prompt string) (string, error) { if t.googleAPIKey == "" { - return "", fmt.Errorf("Google API key not found") + return "", fmt.Errorf("google API key not found") } if t.geminiInitErr != nil { - return "", fmt.Errorf("Gemini client initialization failed: %w", t.geminiInitErr) + return "", fmt.Errorf("gemini client initialization failed: %w", t.geminiInitErr) } if t.geminiClient == nil { - return "", fmt.Errorf("Gemini client not initialized") + return "", fmt.Errorf("gemini client not initialized") } ctx, cancel := context.WithTimeout(context.Background(), translationTimeout) @@ -192,7 +192,7 @@ func (t *Translator) translateWithGemini(prompt string) (string, error) { MaxOutputTokens: translationMaxTokens, }) if err != nil { - return "", fmt.Errorf("Gemini API error: %w", err) + return "", fmt.Errorf("gemini API error: %w", err) } translation := strings.TrimSpace(resp.Text()) diff --git a/internal/translation/translator_test.go b/internal/translation/translator_test.go index 49f1f15..f73079c 100644 --- a/internal/translation/translator_test.go +++ b/internal/translation/translator_test.go @@ -89,8 +89,8 @@ func TestTranslateWord_ExplicitGeminiRequiresGoogleAPIKey(t *testing.T) { if err == nil { t.Fatal("Expected error for missing Google API key") } - if err.Error() != "Google API key not found" { - t.Fatalf("Expected 'Google API key not found' error, got: %v", err) + if err.Error() != "google API key not found" { + t.Fatalf("Expected 'google API key not found' error, got: %v", err) } } |
