mod abc;
mod cache;
mod clike;
mod csharp;
mod dart;
mod directives;
mod dump;
mod fork_point;
mod git_changes;
#[cfg(test)]
mod git_changes_tests;
mod golang;
mod inlinable;
mod javalang;
mod model;
mod modulesize;
mod mr_scope;
#[cfg(test)]
mod mr_scope_tests;
mod never_used;
mod output;
mod paths;
mod phplang;
mod pipeline;
mod pylang;
mod repo_state;
mod run;
mod rustlang;
mod scan_scope;
#[cfg(test)]
mod scan_scope_tests;
mod scope_model;
mod skip;
mod sollang;
mod srcbuf;
mod ziglang;
mod untracked_scan;
#[cfg(test)]
mod test_repo;
mod used_once;
mod walker;
use std::process::ExitCode;
use clap::Parser as ClapParser;
#[derive(ClapParser)]
#[command(
name = "abcop",
version,
about = "Must-have ABC complexity gate for AI development. Ruby, Rust, Python, Go, JS/TS, C/C++, PHP, Java, C#, Swift, Zig, Dart, Solidity, ObjC"
)]
pub(crate) struct Cli {
pub(crate) paths: Vec<String>,
#[arg(long, value_parser = ["text", "json", "jsonl"], default_value = "text")]
pub(crate) format: String,
#[arg(long, default_value_t = 17.0)]
pub(crate) max_abc: f64,
#[arg(long, default_value_t = modulesize::MAX_ABC)]
pub(crate) max_module_abc: f64,
#[arg(long, value_parser = ["abc", "used-once", "never-used"])]
pub(crate) only: Option<String>,
#[arg(long)]
pub(crate) mr: bool,
#[arg(long, conflicts_with_all = ["mr", "full", "everything"])]
pub(crate) uncommitted: bool,
#[arg(long, conflicts_with_all = ["mr", "everything"])]
pub(crate) full: bool,
#[arg(long, conflicts_with_all = ["mr", "full"])]
pub(crate) everything: bool,
#[arg(long)]
pub(crate) no_cache: bool,
#[arg(long)]
pub(crate) sort_by_score: bool,
#[arg(long, hide = true)]
dump_tree: bool,
}
fn main() -> ExitCode {
unsafe {
libc::signal(libc::SIGPIPE, libc::SIG_DFL);
}
let cli = Cli::parse();
if cli.dump_tree {
return run_dump_tree(&cli.paths);
}
run::ScanRun::from(&cli).execute()
}
fn run_dump_tree(paths: &[String]) -> ExitCode {
let Some(path) = paths.first() else {
eprintln!("--dump-tree requires a file path");
return ExitCode::from(2);
};
match dump::dump_tree(path) {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("{e}");
ExitCode::from(2)
}
}
}