use std::path::PathBuf;
use anyhow::Result;
use clap::{ArgAction, Parser, ValueHint};
mod run_impl;
mod sub_diff;
#[derive(Parser, Debug, Clone)]
#[command(name = "ocloc", version, about = "Fast, reliable lines-of-code counter", long_about = None)]
pub struct Args {
#[command(subcommand)]
pub cmd: Option<Subcommand>,
#[arg(value_name = "PATH", default_value = ".", value_hint = ValueHint::AnyPath)]
pub path: PathBuf,
#[arg(long = "ext", value_name = "LIST")]
pub extensions: Option<String>,
#[arg(long = "ignore-file", value_name = "PATH", value_hint = ValueHint::FilePath)]
pub ignore_file: Option<PathBuf>,
#[arg(long = "json", action = ArgAction::SetTrue, conflicts_with = "csv")]
pub json: bool,
#[arg(long = "csv", action = ArgAction::SetTrue, conflicts_with = "json")]
pub csv: bool,
#[arg(long = "follow-symlinks", action = ArgAction::SetTrue)]
pub follow_symlinks: bool,
#[arg(long = "min-size", value_name = "BYTES")]
pub min_size: Option<u64>,
#[arg(long = "max-size", value_name = "BYTES")]
pub max_size: Option<u64>,
#[arg(long = "threads", value_name = "N", default_value_t = 0)]
pub threads: usize,
#[arg(long = "verbose", short = 'v', action = ArgAction::Count)]
pub verbose: u8,
#[arg(long = "progress", action = ArgAction::SetTrue)]
pub progress: bool,
#[arg(long = "skip-empty", action = ArgAction::SetTrue)]
pub skip_empty: bool,
#[arg(long = "mmap-large", value_name = "BYTES")]
pub mmap_large: Option<u64>,
#[arg(long = "no-mmap", action = ArgAction::SetTrue)]
pub no_mmap: bool,
#[arg(long = "ultra", action = ArgAction::SetTrue)]
pub ultra: bool,
}
pub fn run() -> Result<()> {
let args = Args::parse();
if let Some(cmd) = &args.cmd {
match cmd {
Subcommand::Diff(diff_args) => return sub_diff::run_diff(diff_args),
}
}
run_impl::run_with_args(args)
}
#[derive(clap::Subcommand, Debug, Clone)]
pub enum Subcommand {
Diff(DiffArgs),
}
#[derive(clap::Args, Debug, Clone)]
pub struct DiffArgs {
#[arg(long)]
pub base: Option<String>,
#[arg(long)]
pub head: Option<String>,
#[arg(long = "merge-base")]
pub merge_base: Option<String>,
#[arg(long = "staged", action = ArgAction::SetTrue)]
pub staged: bool,
#[arg(long = "working-tree", action = ArgAction::SetTrue)]
pub working_tree: bool,
#[arg(long = "json", action = ArgAction::SetTrue, conflicts_with = "csv")]
pub json: bool,
#[arg(long = "csv", action = ArgAction::SetTrue, conflicts_with = "json")]
pub csv: bool,
#[arg(long = "markdown", action = ArgAction::SetTrue)]
pub markdown: bool,
#[arg(long = "by-file", action = ArgAction::SetTrue)]
pub by_file: bool,
#[arg(long = "summary-only", action = ArgAction::SetTrue)]
pub summary_only: bool,
#[arg(long = "max-code-added")]
pub max_code_added: Option<usize>,
#[arg(long = "max-code-added-lang")]
pub max_code_added_lang: Vec<String>,
#[arg(long = "max-total-changed")]
pub max_total_changed: Option<usize>,
#[arg(long = "max-files")]
pub max_files: Option<usize>,
#[arg(long = "fail-on-threshold", action = ArgAction::SetTrue)]
pub fail_on_threshold: bool,
#[arg(long = "ext", value_name = "LIST")]
pub extensions: Option<String>,
}