mod cli;
mod path_filter;
mod repository;
mod writer;
use anyhow::Result;
use tracing::{error, info, info_span};
fn main() -> Result<()> {
tracing_subscriber::fmt::init();
let main_span = info_span!("flatten.main");
let _guard = main_span.enter();
info!("starting repository flattening");
match run() {
Ok(_) => {
info!("repository flattening completed successfully");
Ok(())
}
Err(e) => {
error!(error=%e, "repository flattening failed");
Err(e)
}
}
}
fn run() -> Result<()> {
let span = info_span!("flatten.run");
let _guard = span.enter();
let args = cli::parse_args();
info!(repo_path=%args.repo.display(), output_path=%args.output.display(), "parsed cli arguments");
let repo_context = repository::discover_repository(&args.repo)?;
info!(repo_root=%repo_context.root.display(), "repository discovered");
let wd_info = repository::get_working_dir_info(&repo_context.repo)?;
info!(branch=%wd_info.branch_name, status=%wd_info.status_summary, "working directory analyzed");
let filter_paths = path_filter::resolve_filter_paths(&args.path, &repo_context.root)?;
if !filter_paths.is_empty() {
info!(paths=?filter_paths.iter().map(|p| p.display().to_string()).collect::<Vec<_>>(), "path filters applied");
}
let mut output_writer = writer::create_output_writer(&args.output)?;
info!(output_file=%args.output.display(), "output writer created");
let file_count = repository::walk_and_write_working_dir(
&repo_context.repo,
&filter_paths,
&mut output_writer,
)?;
info!(
files_processed = file_count,
"working directory walking completed"
);
writer::finalize_output(output_writer)?;
info!("output finalized");
println!(
"\n✅ Success! Working directory content flattened to: {} (branch: {}, {})",
args.output.display(),
wd_info.branch_name,
wd_info.status_summary
);
Ok(())
}