use std::{
collections::HashMap,
fs::File,
io::{self, Write},
path::PathBuf,
vec,
};
use clap::Parser;
use itertools::Itertools;
use log::{debug, error, info};
use smolguess::{
core::{LanguageDefinitions, LanguageMatch},
repository,
};
#[derive(Parser)]
#[command(author, version, about)]
struct CliArgs {
pub repository: String,
#[clap(short, long, name = "FILENAME")]
pub export: Option<String>,
#[clap(short, long)]
pub verbose: bool,
}
fn main() -> io::Result<()> {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug")).init();
let args: CliArgs = CliArgs::parse();
let mut stopwatch = stopwatch::Stopwatch::new();
stopwatch.start();
let repo_languages: Vec<LanguageMatch> = LanguageDefinitions::default()
.load_builtins()
.identify_files(repository::get_bare_repository_files(PathBuf::from(
args.repository,
)));
let grouped_matches: HashMap<_, _> = repo_languages
.clone()
.into_iter()
.group_by(|matched| matched.language.name.clone())
.into_iter()
.map(|(group, items)| (group, items.collect_vec()))
.collect();
let mut sorted_groups: Vec<_> = grouped_matches.into_iter().collect();
sorted_groups.sort_by(|(_, first), (_, second)| second.len().cmp(&first.len()));
stopwatch.stop();
let json: String = serde_json::to_string_pretty(&sorted_groups)?;
if args.verbose {
debug!("======== JSON DATA ========");
println!("{}", json);
debug!("======== END DATA ========");
debug!("Files found: {}", repo_languages.len());
}
if args.export.is_some() {
let file = PathBuf::from(args.export.as_ref().unwrap());
if !file.is_dir() {
File::create(file)?.write_all(json.as_bytes())?;
} else {
error!(
"The provided path is a directory: '{}'",
args.export.unwrap()
);
}
}
if !sorted_groups.is_empty() {
let default: (String, Vec<LanguageMatch>) = (String::from("Unknown"), vec![]);
println!(
"{}",
sorted_groups.first().unwrap_or_else(|| { &default }).0
);
}
if args.verbose {
info!("Operation completed in: {}", stopwatch)
}
Ok(())
}