mod types;
mod snapshot;
mod scanner;
mod formatters;
mod diff;
use clap::{Parser, Subcommand, CommandFactory};
use snapshot::run_snapshot;
use diff::run_diff;
#[derive(Parser, Debug)]
#[command(
name = "ygg",
author,
version,
about = "✨ Yggdrasil CLI — the god-tree of your codebase.",
long_about = "Flatten your project into an AI-ready snapshot codex — index + contents in one command."
)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
#[command(flatten)]
pub args: Args,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
Diff {
#[arg(required = true)]
from: Vec<String>,
#[arg(required = true)]
to: Vec<String>,
#[arg(long)]
align_tags: bool,
},
}
#[derive(clap::Args, Debug)]
pub struct Args {
#[arg(default_value = ".")]
pub dir: String,
#[arg(long, num_args = 0.., value_delimiter = ' ')]
pub show: Vec<String>,
#[arg(long)]
pub contents: bool,
#[arg(long)]
pub md: bool,
#[arg(long, num_args = 1.., value_delimiter = ' ')]
pub only: Vec<String>,
#[arg(long)]
pub no_lines: bool,
#[arg(long, num_args = 1.., value_delimiter = ' ')]
pub ignore: Vec<String>,
#[arg(long, alias = "blacklist", num_args = 0..=1)]
pub black: Option<Option<String>>,
#[arg(long, alias = "manifest", num_args = 0..=1)]
pub white: Option<Option<String>>,
#[arg(long, num_args = 0..=1)]
pub whited: Option<Option<String>>,
#[arg(long, short = 'p', num_args = 0..=1)]
pub printed: Option<Option<String>>,
#[arg(long)]
pub out: Option<String>,
#[arg(long)]
pub align_tags: bool,
}
pub mod cli {
pub use super::{Cli, Args, Commands};
}
fn main() {
let cli = Cli::parse();
if std::env::args().len() == 1 {
Cli::command().print_help().unwrap();
println!();
return;
}
match cli.command {
Some(Commands::Diff { from, to, align_tags }) => {
run_diff(from, to, align_tags);
}
None => {
run_snapshot(cli.args);
}
}
}