Skip to content

Commit ff10ec8

Browse files
committed
chore(ui,docs): show full errors and update codebase docs
Avoid truncating operation errors in progress UI and refresh developer docs for recent list/download behavior.
1 parent 1d955c0 commit ff10ec8

3 files changed

Lines changed: 16 additions & 29 deletions

File tree

cmd/import.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -645,9 +645,6 @@ Fonts are installed using their Font IDs. Missing fonts are skipped with a warni
645645
status.Failed += result.Failed
646646
GetLogger().Error("Failed to process font %s: %v", fontGroup.FontName, err)
647647
errorMsg := err.Error()
648-
if len(errorMsg) > 100 {
649-
errorMsg = errorMsg[:97] + "..."
650-
}
651648
send(components.ItemUpdateMsg{
652649
Index: itemIndex,
653650
Status: "failed",

docs/development/codebase.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,12 @@ This document provides a comprehensive overview of the FontGet codebase, explain
140140
- Default scope is "all" (shows fonts from both user and machine scopes)
141141
- Displays columns: Name, Font ID, License, Categories, Type, Scope, Source
142142
- **Font ID Filtering**: Query parameter can match either font family names (e.g., "Roboto") or Font IDs (e.g., "google.roboto")
143-
- **Performance Optimizations**: Early type filtering (filters by extension before metadata extraction) and cached lowercased strings for faster filtering
143+
- **Performance Optimizations**:
144+
- Early type filtering (filters by extension before metadata extraction)
145+
- Concurrent metadata extraction for faster scans on large font directories
146+
- Precomputed case-insensitive sort keys to avoid repeated `strings.ToLower()` in sort comparators
147+
- Avoids holding the spinner open for fast operations (no artificial 2.5s delay when spinner clears the line)
148+
- Disables spinner when `--debug` is enabled to prevent carriage-return UI rendering from mangling debug output
144149

145150
**Key Functions**:
146151
- `listCmd.RunE`: Main listing execution
@@ -580,13 +585,19 @@ This document provides a comprehensive overview of the FontGet codebase, explain
580585
- `font_matches.go`: Font matching logic for installed fonts to repository entries
581586
- `metadata.go`: Font metadata handling
582587
- `archive.go`: Archive operations
588+
- `download_headers.go`: HTTP response header parsing/inference helpers for downloads (e.g., detecting ZIP archives served behind `.ttf` URLs)
583589
- `types.go`: Type definitions
584590

585591
**Key Features**:
586592
- **Font Matching**: Optimized index-based matching of installed fonts to repository entries
587593
- **Font ID Resolution**: Resolves Font IDs (e.g., "google.roboto") to font names
588594
- **Source Priority**: Handles multiple repository matches using predefined source priority order
589595
- **Nerd Fonts Support**: Special handling for Nerd Fonts naming conventions and variants
596+
- **Robust Download/Archive Handling**:
597+
- Supported archives: ZIP, TAR.XZ, TAR.GZ, 7Z
598+
- Archive detection uses extension, HTTP headers (Content-Type / Content-Disposition), and file magic bytes (final truth)
599+
- Prevents archives from being mis-installed as `.ttf` when upstream naming is misleading (notably Font Squirrel)
600+
- **7Z extraction** uses external `7zz`/`7z` when available on PATH; otherwise extraction fails with a clear error
590601

591602
**Status**: ✅ Active - Core repository system
592603

@@ -630,6 +641,7 @@ This document provides a comprehensive overview of the FontGet codebase, explain
630641
- **Centralized styling**: `InitStyles()` applies theme colors across commands
631642
- **Unified table API**: Shared headers and column conventions
632643
- **Spinners**: Both simple blocking (`RunSpinner`) and full Bubble Tea model (`NewSpinnerModel`) paths, with theme-based spinner colors
644+
- Spinner model enforces a minimum display time only when showing a completion message; fast operations that clear the line return immediately
633645

634646
**Status**: ✅ Active - UI system with theme support
635647

@@ -642,6 +654,7 @@ This document provides a comprehensive overview of the FontGet codebase, explain
642654

643655
**Key Features**:
644656
- **Consistent Formatting**: Standardized `[INFO]`, `[WARNING]`, `[ERROR]` prefixes
657+
- **Debug Mode Helpers**: `IsDebugOutputEnabled()` supports disabling interactive UI elements (e.g., spinners) when debug output must stay readable
645658
- **Operation Details Display**: `DisplayFontOperationDetails()` shows formatted installation/removal details
646659
- **Download Size Tracking**: Integrated file size display in verbose output
647660
- **Status Reporting**: Unified status report display for operations

internal/components/progress_bar.go

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -428,32 +428,9 @@ func (m ProgressBarModel) View() string {
428428
// Show "Skipped... already installed" (no scope info for cleaner output)
429429
statusText = "Skipped... already installed"
430430
case "failed":
431-
// Show brief error message in error color (if available), otherwise show generic message
431+
// Show full error message in error color (if available), otherwise show generic message
432432
if item.ErrorMessage != "" {
433-
// Extract brief error - take first sentence or reasonable length
434-
errorMsg := item.ErrorMessage
435-
// Remove filename prefix if present (e.g., "Roboto-Regular.ttf could not..." -> "could not...")
436-
// Look for common patterns like ".ttf could" or ".otf could"
437-
if idx := strings.Index(errorMsg, " could"); idx > 0 {
438-
errorMsg = errorMsg[idx+1:] // Keep the space before "could"
439-
}
440-
// Try to get first sentence (up to ". "), but do NOT truncate on bare "." since that
441-
// breaks URLs (e.g. "https://fonts.google.com/specimen/Roboto" -> "https://www").
442-
if idx := strings.Index(errorMsg, ". "); idx > 0 {
443-
errorMsg = errorMsg[:idx]
444-
} else if len(errorMsg) > 220 {
445-
// Only truncate if extremely long (120+ chars), and try to break at word boundary
446-
errorMsg = errorMsg[:220]
447-
if lastSpace := strings.LastIndex(errorMsg, " "); lastSpace > 180 {
448-
errorMsg = errorMsg[:lastSpace]
449-
}
450-
}
451-
// Capitalize first letter to match other status messages
452-
if len(errorMsg) > 0 {
453-
errorMsg = strings.ToUpper(string(errorMsg[0])) + errorMsg[1:]
454-
}
455-
// Apply error color styling (no bold) - ErrorText already has the right color
456-
statusText = ui.ErrorText.Render(errorMsg)
433+
statusText = ui.ErrorText.Render(item.ErrorMessage)
457434
} else {
458435
// Fallback to generic message
459436
statusText = "Installation failed"

0 commit comments

Comments
 (0)