use std::path::PathBuf;
use clap::Args;
use walkdir::WalkDir;
use lip::indexer::{language::Language, Tier1Indexer};
use lip::schema::{Action, OwnedDelta, OwnedEventStream};
use crate::output;
#[derive(Args)]
pub struct IndexArgs {
#[arg(default_value = ".")]
pub path: PathBuf,
#[arg(long)]
pub language: Option<String>,
#[arg(long)]
pub json: bool,
#[arg(long, default_value_t = 0)]
pub limit: usize,
}
pub async fn run(args: IndexArgs) -> anyhow::Result<()> {
let mut indexer = Tier1Indexer::new();
let mut deltas = vec![];
let mut count = 0usize;
let lang_hint = args.language.as_deref().unwrap_or("");
for entry in WalkDir::new(&args.path)
.follow_links(false)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| e.file_type().is_file())
{
let path = entry.path();
let abs = match path.canonicalize() {
Ok(p) => p,
Err(_) => continue,
};
let uri = format!("file://{}", abs.display());
let lang = Language::detect(&uri, lang_hint);
if lang == Language::Unknown {
continue;
}
let source = match std::fs::read_to_string(&abs) {
Ok(s) => s,
Err(_) => continue,
};
let doc = indexer.index_file(&uri, &source, lang);
if args.json {
let delta = OwnedDelta {
action: Action::Upsert,
commit_hash: doc.content_hash.clone(),
document: Some(doc),
symbol: None,
slice: None,
};
deltas.push(delta);
} else {
let sym_count = doc.symbols.len();
println!("{uri} ({sym_count} symbols, lang={})", lang.as_str());
}
count += 1;
if args.limit > 0 && count >= args.limit {
break;
}
}
if args.json {
let stream = OwnedEventStream::new(concat!("lip-cli/", env!("CARGO_PKG_VERSION")), deltas);
output::print_json(&stream)?;
} else {
println!("\nIndexed {count} files.");
}
Ok(())
}