renovate 0.2.23

A new way to handle Postgres schema migration.
Documentation
use super::{Args, CommandExecutor};
use crate::{utils::load_config, DatabaseRepo, LocalRepo, SchemaLoader, SqlLoader};
use clap_utils::{highlight_text, prelude::*};

#[derive(Parser, Debug, Clone)]
pub struct SchemaPlanCommand {}

#[async_trait]
impl CommandExecutor for SchemaPlanCommand {
    async fn execute(&self, _args: &Args) -> Result<(), Error> {
        generate_plan(false).await?;
        Ok(())
    }
}

pub(super) async fn generate_plan(remote: bool) -> Result<Vec<String>> {
    let config = load_config().await?;
    let db_repo = DatabaseRepo::new(&config);

    let local_schema = if !remote {
        let sql = LocalRepo::new(&config.output.path).load_sql().await?;
        db_repo.normalize(&sql).await?
    } else {
        db_repo.load().await?
    };
    let remote_schema = if !remote {
        db_repo.load().await?
    } else {
        let sql = db_repo.load_sql_string(remote).await?;
        SqlLoader::new(&sql).load().await?
    };
    let plan = local_schema.plan(&remote_schema, true)?;

    if plan.is_empty() {
        println!("No changes detected.");
        return Ok(vec![]);
    }

    println!("The following SQLs will be applied:\n");
    for item in plan.iter() {
        let formatted = sqlformat::format(
            item,
            &Default::default(),
            config.output.format.unwrap_or_default().into(),
        );
        if atty::is(atty::Stream::Stdout) {
            println!("{};", highlight_text(&formatted, "sql", None)?);
        } else {
            println!("{};", formatted);
        }
    }
    Ok(plan)
}