drizzle_cli/commands/
status.rs

1//! Status command implementation
2//!
3//! Shows migration status (applied vs pending).
4
5use crate::config::DrizzleConfig;
6use crate::error::CliError;
7use crate::output;
8
9/// Run the status command
10pub fn run(config: &DrizzleConfig, db_name: Option<&str>) -> Result<(), CliError> {
11    use drizzle_migrations::journal::Journal;
12
13    let db = config.database(db_name)?;
14
15    println!("{}", output::heading("Migration Status"));
16    println!();
17
18    if !config.is_single_database() {
19        let name = db_name.unwrap_or("(default)");
20        println!("  {}: {}", output::label("Database"), name);
21        println!();
22    }
23
24    let out_dir = db.migrations_dir();
25    let journal_path = db.journal_path();
26
27    // Check if migrations directory exists
28    if !out_dir.exists() {
29        println!("  {}", output::warning("No migrations directory found."));
30        println!("  Run 'drizzle generate' to create your first migration.");
31        return Ok(());
32    }
33
34    // Load journal
35    let journal = if journal_path.exists() {
36        Journal::load(&journal_path).map_err(|e| CliError::IoError(e.to_string()))?
37    } else {
38        println!("  {}", output::warning("No migrations journal found."));
39        println!("  Run 'drizzle generate' to create your first migration.");
40        return Ok(());
41    };
42
43    if journal.entries.is_empty() {
44        println!("  {}", output::warning("No migrations found."));
45        return Ok(());
46    }
47
48    // Display migration entries
49    println!("  {} migration(s) in journal:\n", journal.entries.len());
50
51    for (i, entry) in journal.entries.iter().enumerate() {
52        // Migration is in {out}/{tag}/migration.sql
53        let migration_path = out_dir.join(&entry.tag).join("migration.sql");
54        let snapshot_path = out_dir.join(&entry.tag).join("snapshot.json");
55
56        let sql_exists = migration_path.exists();
57        let snapshot_exists = snapshot_path.exists();
58
59        let status_icon = if sql_exists && snapshot_exists {
60            output::success("✓")
61        } else if sql_exists {
62            output::warning("○")
63        } else {
64            output::error("✗")
65        };
66        let idx_display = output::muted(&format!("{:3}.", i + 1));
67
68        println!("  {} {} {}", idx_display, status_icon, entry.tag);
69
70        if !sql_exists {
71            println!("      {}", output::error("Migration file missing!"));
72        }
73        if !snapshot_exists && sql_exists {
74            println!("      {}", output::warning("Snapshot file missing"));
75        }
76    }
77
78    println!();
79    println!(
80        "  {}: {}",
81        output::muted("Migrations directory"),
82        out_dir.display()
83    );
84    println!(
85        "  {}: {}",
86        output::muted("Schema files"),
87        db.schema_display()
88    );
89
90    Ok(())
91}