audb-cli 0.1.11

Command-line interface for AuDB database application framework
//! AuDB Command Line Interface
//!
//! The `au` command provides tools for managing AuDB projects:
//! - `au init` - Initialize a new project
//! - `au generate` - Generate code from gold files
//! - `au check` - Validate gold files
//! - `au dev` - Watch and regenerate on changes
//! - `au deploy` - Deploy the application
//!
//! Run `au --help` for more information.

mod commands;

use anyhow::Result;
use clap::{Parser, Subcommand};

/// AuDB - Compile-time database application framework
#[derive(Parser)]
#[command(name = "au")]
#[command(version, about, long_about = None)]
#[command(author = "AuDB Contributors")]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Initialize a new AuDB project
    Init {
        /// Project name
        name: String,

        /// Template to use (server, library, cli, minimal)
        #[arg(short, long, default_value = "server")]
        template: String,

        /// Skip Git initialization
        #[arg(long)]
        no_git: bool,
    },

    /// Generate code from gold files
    Generate {
        /// Gold files directory
        #[arg(short, long, default_value = "./gold")]
        gold_dir: String,

        /// Output directory for generated code
        #[arg(short, long, default_value = "./src/generated")]
        output_dir: String,
    },

    /// Validate gold files without generating code
    Check {
        /// Gold files directory
        #[arg(short, long, default_value = "./gold")]
        gold_dir: String,
    },

    /// Watch gold files and regenerate on changes
    Dev {
        /// Gold files directory
        #[arg(short, long, default_value = "./gold")]
        gold_dir: String,

        /// Output directory for generated code
        #[arg(short, long, default_value = "./src/generated")]
        output_dir: String,
    },

    /// Deploy the application
    Deploy {
        #[command(subcommand)]
        command: Option<DeploySubcommand>,

        /// Deployment target (docker, systemd, daemon, local)
        #[arg(short, long)]
        target: Option<String>,

        /// Override port
        #[arg(short, long)]
        port: Option<u16>,

        /// Environment variable (can be used multiple times: -e KEY=VALUE)
        #[arg(short, long)]
        env: Vec<String>,

        /// Volume mapping (can be used multiple times: -v HOST:CONTAINER)
        #[arg(short, long)]
        volume: Vec<String>,

        /// Force rebuild (Docker: no cache)
        #[arg(long)]
        force_rebuild: bool,

        /// Use docker-compose instead of direct Docker API
        #[arg(long)]
        compose: bool,
    },
}

#[derive(Subcommand)]
enum DeploySubcommand {
    /// Start/deploy the application (default)
    Start,
    /// Check deployment status
    Status,
    /// Stop the deployment
    Stop,
    /// View deployment logs
    Logs,
    /// Restart the deployment
    Restart,
}

#[tokio::main]
async fn main() -> Result<()> {
    // Initialize logger
    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();

    let cli = Cli::parse();

    match cli.command {
        Commands::Init {
            name,
            template,
            no_git,
        } => {
            commands::init::run(&name, &template, !no_git).await?;
        }
        Commands::Generate {
            gold_dir,
            output_dir,
        } => {
            commands::generate::run(&gold_dir, &output_dir)?;
        }
        Commands::Check { gold_dir } => {
            commands::check::run(&gold_dir)?;
        }
        Commands::Dev {
            gold_dir,
            output_dir,
        } => {
            commands::dev::run(&gold_dir, &output_dir)?;
        }
        Commands::Deploy {
            command,
            target,
            port,
            env,
            volume,
            force_rebuild,
            compose,
        } => {
            let deploy_cmd = match command {
                Some(DeploySubcommand::Start) | None => commands::deploy::DeployCommand::Start,
                Some(DeploySubcommand::Status) => commands::deploy::DeployCommand::Status,
                Some(DeploySubcommand::Stop) => commands::deploy::DeployCommand::Stop,
                Some(DeploySubcommand::Logs) => commands::deploy::DeployCommand::Logs,
                Some(DeploySubcommand::Restart) => commands::deploy::DeployCommand::Restart,
            };

            let options = commands::deploy::DeployOptions {
                target,
                port,
                env,
                volume,
                force_rebuild,
                compose,
            };

            commands::deploy::run(deploy_cmd, options).await?;
        }
    }

    Ok(())
}