use clap::{ArgGroup, Parser};
use llmcc::{run_main, LlmccOptions, QueryDirection};
use llmcc_python::LangPython;
use llmcc_rust::LangRust;
#[derive(Parser, Debug)]
#[command(
name = "llmcc",
about = "llmcc: llm context compiler",
version,
group = ArgGroup::new("inputs").required(true).args(["files", "dirs"])
)]
struct Args {
#[arg(
short = 'f',
long = "file",
value_name = "FILE",
num_args = 1..,
action = clap::ArgAction::Append,
conflicts_with = "dirs"
)]
files: Vec<String>,
#[arg(
short = 'd',
long = "dir",
value_name = "DIR",
num_args = 1..,
action = clap::ArgAction::Append,
conflicts_with = "files"
)]
dirs: Vec<String>,
#[arg(long, value_name = "LANG", default_value = "rust")]
lang: String,
#[arg(long, default_value_t = false)]
print_ir: bool,
#[arg(long, default_value_t = false)]
print_block: bool,
#[arg(long = "design-graph", default_value_t = false)]
design_graph: bool,
#[arg(long, default_value_t = false)]
summary: bool,
#[arg(long, default_value_t = false)]
pagerank: bool,
#[arg(long, value_name = "K", requires = "pagerank")]
top_k: Option<usize>,
#[arg(long, value_name = "NAME")]
query: Option<String>,
#[arg(long, default_value_t = false)]
recursive: bool,
#[arg(long, default_value_t = false, conflicts_with = "dependents")]
depends: bool,
#[arg(long, default_value_t = false, conflicts_with = "depends")]
dependents: bool,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
if args.query.is_none() && (args.depends || args.dependents) {
eprintln!("Warning: --depends/--dependents flags are ignored without --query");
}
if args.pagerank && !args.design_graph {
return Err("--pagerank requires --design-graph".into());
}
let query_direction = if args.dependents {
QueryDirection::Dependents
} else {
QueryDirection::Depends
};
let opts = LlmccOptions {
files: args.files,
dirs: args.dirs,
print_ir: args.print_ir,
print_block: args.print_block,
design_graph: args.design_graph,
pagerank: args.pagerank,
top_k: args.top_k,
query: args.query,
query_direction,
recursive: args.recursive,
summary: args.summary,
};
let result = match args.lang.as_str() {
"rust" => run_main::<LangRust>(&opts),
"python" => run_main::<LangPython>(&opts),
_ => Err(format!("Unknown language: {}", args.lang).into()),
}?;
if let Some(output) = result {
println!("{}", output);
}
Ok(())
}