diff --git a/cmd/gohoarder/commands/serve.go b/cmd/gohoarder/commands/serve.go index 7aa0525..b8bd33f 100644 --- a/cmd/gohoarder/commands/serve.go +++ b/cmd/gohoarder/commands/serve.go @@ -1,3 +1,4 @@ +// Package commands hosts the cobra commands wired into the gohoarder CLI. package commands import ( @@ -35,11 +36,11 @@ func runServe(cmd *cobra.Command, args []string) error { } // Initialize logger - if err := logger.Init(logger.Config{ + if logErr := logger.Init(logger.Config{ Level: cfg.Logging.Level, Format: cfg.Logging.Format, - }); err != nil { - return fmt.Errorf("failed to initialize logger: %w", err) + }); logErr != nil { + return fmt.Errorf("failed to initialize logger: %w", logErr) } log.Info(). diff --git a/cmd/gohoarder/commands/version.go b/cmd/gohoarder/commands/version.go index 52dffc7..d01f442 100644 --- a/cmd/gohoarder/commands/version.go +++ b/cmd/gohoarder/commands/version.go @@ -23,16 +23,16 @@ var VersionCmd = &cobra.Command{ if jsonOutput { data, err := json.MarshalIndent(info, "", " ") if err != nil { - fmt.Fprintf(cmd.OutOrStderr(), "Error: %v\n", err) + _, _ = fmt.Fprintf(cmd.OutOrStderr(), "Error: %v\n", err) return } - fmt.Fprintln(cmd.OutOrStdout(), string(data)) + _, _ = fmt.Fprintln(cmd.OutOrStdout(), string(data)) } else { - fmt.Fprintf(cmd.OutOrStdout(), "GoHoarder %s\n", info.Version) - fmt.Fprintf(cmd.OutOrStdout(), "Git Commit: %s\n", info.GitCommit) - fmt.Fprintf(cmd.OutOrStdout(), "Built: %s\n", info.BuildTime) - fmt.Fprintf(cmd.OutOrStdout(), "Go Version: %s\n", info.GoVersion) - fmt.Fprintf(cmd.OutOrStdout(), "Platform: %s\n", info.Platform) + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "GoHoarder %s\n", info.Version) + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Git Commit: %s\n", info.GitCommit) + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Built: %s\n", info.BuildTime) + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Go Version: %s\n", info.GoVersion) + _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Platform: %s\n", info.Platform) } }, } diff --git a/cmd/migrate/main.go b/cmd/migrate/main.go index f45ea7b..9502d51 100644 --- a/cmd/migrate/main.go +++ b/cmd/migrate/main.go @@ -25,10 +25,10 @@ import ( type MigrationConfig struct { Driver string DSN string - Timeout time.Duration Action string // migrate, rollback, rollback-to, list TargetID string // For rollback-to LogLevel string + Timeout time.Duration } func main() { @@ -97,7 +97,7 @@ func RunMigration(cfg MigrationConfig) error { if err != nil { return fmt.Errorf("failed to get sql.DB: %w", err) } - defer sqlDB.Close() + defer func() { _ = sqlDB.Close() }() // Wait for database to be ready if err := waitForDB(ctx, sqlDB, 60*time.Second); err != nil { diff --git a/frontend/src/components/Dashboard.spec.ts b/frontend/src/components/Dashboard.spec.ts index 73adafe..d9c2e09 100644 --- a/frontend/src/components/Dashboard.spec.ts +++ b/frontend/src/components/Dashboard.spec.ts @@ -3,10 +3,12 @@ import { mount } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import Dashboard from './Dashboard.vue' import { usePackageStore } from '../stores/packages' +import { useRealtimeStore, __resetRealtimeSingleton } from '../stores/realtime' describe('Dashboard.vue', () => { beforeEach(() => { setActivePinia(createPinia()) + __resetRealtimeSingleton() // Mock the fetch functions to prevent actual API calls const store = usePackageStore() vi.spyOn(store, 'fetchStats').mockResolvedValue() @@ -213,4 +215,33 @@ describe('Dashboard.vue', () => { expect(wrapper.text()).toContain('0') expect(wrapper.text()).toContain('0 B') }) + + it('renders realtime lastStats over polled stats when present', async () => { + const wrapper = mount(Dashboard) + const store = usePackageStore() + const rt = useRealtimeStore() + + store.loading = false + store.stats = { + registry: '', + total_packages: 10, + total_size: 1024, + max_cache_size: 10737418240, + total_downloads: 5, + scanned_packages: 0, + vulnerable_packages: 0, + blocked_packages: 0, + } + rt.lastStats = { + total_packages: 999, + total_size: 2048, + total_downloads: 777, + scanned_packages: 0, + } + await wrapper.vm.$nextTick() + + // Realtime values should be visible (override polled values). + expect(wrapper.text()).toContain('999') + expect(wrapper.text()).toContain('777') + }) }) diff --git a/frontend/src/components/Dashboard.vue b/frontend/src/components/Dashboard.vue index 7281ecc..c51e3ae 100644 --- a/frontend/src/components/Dashboard.vue +++ b/frontend/src/components/Dashboard.vue @@ -1,6 +1,23 @@