devcat 0.1.5

A micro-version control system for your AI development loop.
use clap::{Args, Parser};
use std::path::PathBuf;
mod apply;
mod cat;
mod clean;
mod config;
mod diff;
mod error;
mod history;
mod inspect;
mod log_cmd;
mod module;
mod patch;
mod prune;
mod revert;
mod save;
mod split;
mod trace;
mod utils;
mod watch;

use log::{debug, LevelFilter};

pub use error::Result;

#[derive(Parser, Debug)]
#[command(
    name = "devcat",
    version = "0.1.5",
    about = "A self-contained snapshot and context tool for your development loop.",
    long_about = "devcat creates filesystem-based snapshots of your work, allowing you to diff, view, and revert to specific checkpoints in any directory."
)]
struct Cli {
    #[command(flatten)]
    cat_args: cat::CatArgs,

    #[command(subcommand)]
    command: Option<Commands>,

    #[arg(short, long, global = true, action = clap::ArgAction::Count)]
    verbose: u8,
}

#[derive(Args, Debug, Clone)]
pub struct OutputArgs {
    #[arg(short, long, global = true)]
    pub output: Option<PathBuf>,
}

#[derive(Args, Debug, Clone)]
pub struct ExcludeArgs {
    #[arg(short = 'e', long)]
    pub exclude: Vec<String>,
}

#[derive(Parser, Debug)]
enum Commands {
    Save(save::SaveArgs),
    Revert(revert::RevertArgs),
    Log(log_cmd::LogArgs),
    Diff(diff::DiffArgs),
    Module(module::ModuleArgs),
    Trace(trace::TraceArgs),
    Clean(clean::CleanArgs),
    Prune(prune::PruneArgs),
    Inspect(inspect::InspectArgs),
    Watch(watch::WatchArgs),
    Split(split::SplitArgs),
    Patch(patch::PatchArgs),
    Apply(apply::ApplyArgs),
}

fn main() {
    let cli = Cli::parse();

    let log_level = match cli.verbose {
        0 => LevelFilter::Warn,
        1 => LevelFilter::Info,
        _ => LevelFilter::Debug,
    };
    env_logger::Builder::new().filter_level(log_level).init();

    debug!("CLI arguments parsed successfully.");

    let result = match cli.command {
        Some(Commands::Save(args)) => save::run(args),
        Some(Commands::Revert(args)) => revert::run(args),
        Some(Commands::Log(args)) => log_cmd::run(args),
        Some(Commands::Diff(args)) => diff::run(args),
        Some(Commands::Module(args)) => module::run(args),
        Some(Commands::Trace(args)) => trace::run(args),
        Some(Commands::Clean(args)) => clean::run(args),
        Some(Commands::Prune(args)) => prune::run(args),
        Some(Commands::Inspect(args)) => inspect::run(args),
        Some(Commands::Watch(args)) => watch::run(args),
        Some(Commands::Split(args)) => split::run(args),
        Some(Commands::Patch(args)) => patch::run(args),
        Some(Commands::Apply(args)) => apply::run(args),
        None => cat::run(cli.cat_args),
    };

    if let Err(e) = result {
        log::error!("{}", e);
        std::process::exit(1);
    }
}