bluesky viewer in the terminal
at main 3.0 kB view raw
1package main 2 3import ( 4 "context" 5 "database/sql" 6 "fmt" 7 "os" 8 9 "github.com/stormlightlabs/skypanel/cli/internal/config" 10 "github.com/stormlightlabs/skypanel/cli/internal/store" 11 "github.com/stormlightlabs/skypanel/cli/internal/ui" 12 "github.com/urfave/cli/v3" 13) 14 15func SetupAction(ctx context.Context, cmd *cli.Command) error { 16 17 ui.Titleln("Setup: Initializing persistence layer") 18 fmt.Println() 19 20 configDir, err := config.GetConfigDir() 21 if err != nil { 22 return fmt.Errorf("failed to get config directory: %w", err) 23 } 24 25 dbPath, err := config.GetCacheDB() 26 if err != nil { 27 return fmt.Errorf("failed to get database path: %w", err) 28 } 29 30 ui.Infoln("Config directory: %s", configDir) 31 ui.Infoln("Database path: %s", dbPath) 32 fmt.Println() 33 34 if _, err := os.Stat(configDir); os.IsNotExist(err) { 35 ui.Infoln("Creating config directory...") 36 if err := os.MkdirAll(configDir, 0700); err != nil { 37 logger.Error("Failed to create config directory", "error", err) 38 return err 39 } 40 ui.Successln("Config directory created") 41 } else { 42 ui.Successln("Config directory exists") 43 } 44 45 dbExists := true 46 if _, err := os.Stat(dbPath); os.IsNotExist(err) { 47 dbExists = false 48 ui.Infoln("Database does not exist, will be created") 49 } else { 50 ui.Successln("Database file exists") 51 } 52 53 fmt.Println() 54 55 db, err := sql.Open("sqlite3", dbPath) 56 if err != nil { 57 logger.Error("Failed to open database", "error", err) 58 return err 59 } 60 defer db.Close() 61 62 statusBefore, err := store.GetMigrationStatus(db) 63 if err != nil && !dbExists { 64 logger.Debug("Migration status check returned error (expected for new database)", "error", err) 65 statusBefore = &store.MigrationStatus{CurrentVersion: 0, LatestVersion: 0, PendingCount: 0} 66 } else if err != nil { 67 logger.Error("Failed to check migration status", "error", err) 68 return err 69 } 70 71 if statusBefore.IsUpToDate && dbExists { 72 ui.Successln("Database is up to date (v%d)", statusBefore.CurrentVersion) 73 return nil 74 } 75 76 ui.Infoln("Running migrations...") 77 if err := store.RunMigrations(db); err != nil { 78 logger.Error("Failed to run migrations", "error", err) 79 return err 80 } 81 82 statusAfter, err := store.GetMigrationStatus(db) 83 if err != nil { 84 logger.Error("Failed to verify migration status", "error", err) 85 return err 86 } 87 88 fmt.Println() 89 ui.Successln("Setup complete!") 90 ui.Infoln("Database version: v%d", statusAfter.CurrentVersion) 91 ui.Infoln("Migrations applied: %d", statusAfter.CurrentVersion-statusBefore.CurrentVersion) 92 93 return nil 94} 95 96func SetupCommand() *cli.Command { 97 return &cli.Command{ 98 Name: "setup", 99 Usage: "Initialize the persistence layer (database and config)", 100 Description: `Initialize the skycli persistence layer by creating: 101 - Config directory at ~/.skycli 102 - SQLite database at ~/.skycli/cache.db 103 - Running all database migrations 104 105 This command is idempotent and safe to run multiple times. 106 It will show the current state and only make necessary changes.`, 107 Action: SetupAction, 108 } 109}