#![allow(missing_docs)]
mod agent;
mod locignore;
mod cli;
mod config;
mod counter;
mod display;
mod export;
mod extractors;
mod language;
mod models;
use agent::OutputMode;
use clap::Parser;
use colored::Colorize;
use std::process;
fn main() {
let mut args = cli::Args::parse();
if args.func_analysis {
args.functions = true;
}
let (mode, detected_agent) =
agent::resolve_output_mode(args.format, args.json, args.quiet);
let config = match counter::ScanConfig::from_args(&args) {
Ok(c) => c,
Err(e) => {
eprintln!("{} {}", "[ERROR]".red().bold(), e);
process::exit(1);
}
};
let result = match counter::run_scan(&config) {
Ok(r) => r,
Err(e) => {
eprintln!("{} {}", "[ERROR]".red().bold(), e);
process::exit(1);
}
};
match mode {
OutputMode::Json => {
if args.func_analysis {
eprintln!(
"{} --func-analysis is not supported with JSON output; \
use -f to embed function data in the JSON",
"[WARN]".yellow().bold()
);
}
if let Err(e) =
export::json::print_json_stats(&result, config.extract_functions)
{
eprintln!("{} {}", "[ERROR]".red().bold(), e);
process::exit(1);
}
agent::print_hints(
mode,
args.detailed,
args.tree,
args.functions,
args.func_analysis,
args.export.is_some(),
detected_agent.as_deref(),
);
}
OutputMode::Agent => {
display::display_agent_tsv(
&result,
&config.target_dir,
args.detailed,
args.tree,
config.extract_functions,
config.warn_size,
);
if args.func_analysis {
display::display_agent_function_analysis(&result, &config.target_dir);
}
agent::print_hints(
mode,
args.detailed,
args.tree,
args.functions,
args.func_analysis,
args.export.is_some(),
detected_agent.as_deref(),
);
}
OutputMode::Quiet => {
display::display_quiet(&result, &config.target_dir);
agent::print_hints(
mode,
args.detailed,
args.tree,
args.functions,
args.func_analysis,
args.export.is_some(),
detected_agent.as_deref(),
);
}
OutputMode::Human => {
display::display_results(
&result,
&config.target_dir,
args.detailed,
args.binary,
args.tree,
config.warn_size,
config.extract_functions,
);
if args.func_analysis {
display::display_function_analysis(&result, &config.target_dir);
}
agent::print_hints(
mode,
args.detailed,
args.tree,
args.functions,
args.func_analysis,
args.export.is_some(),
detected_agent.as_deref(),
);
}
}
if let Some(ref output_file) = args.export {
if let Err(e) = export::export(&result, output_file, config.extract_functions) {
eprintln!("{} {}", "[ERROR]".red().bold(), e);
process::exit(1);
}
}
}