diff --git a/Cargo.lock b/Cargo.lock index ef6c318..a11ea51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,6 +111,7 @@ dependencies = [ "colored", "ignore", "nom", + "regex", "term-table", ] @@ -238,9 +239,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", diff --git a/Cargo.toml b/Cargo.toml index ee6b9a6..aecd12f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,5 @@ clap = { version = "4.5.1", features = ["cargo"] } colored = "2.1.0" ignore = "0.4.22" nom = "7.1.3" +regex = "1.10.4" term-table = "1.3.2" diff --git a/README.md b/README.md index 4efd15f..f05c3fd 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ code-peek [FLAGS] [OPTIONS] [ARGS] - _-a, --all_: Display all available information. - _-g, --group_: Group the results by file extension or programming language. - _-t, --git_: Get Git information (number of commits) for each file. +- _--skip-lockfiles_: Skips lockfiles in analysis. ### Options diff --git a/src/cli.rs b/src/cli.rs index 0a66e28..49c5443 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -17,6 +17,7 @@ pub struct DisplayOptions { pub group: bool, pub git: bool, pub all: bool, + pub skip_lockfiles: bool, } pub fn run_cli() -> Result { @@ -37,6 +38,7 @@ pub fn run_cli() -> Result { ) .arg(arg!([all] -a --all "Display all available information").required(false)) .arg(arg!([group] -g --group "Group the results by its extension").required(false)) + .arg(arg!(--"skip-lockfiles" "Skips lockfiles in analysis").long("skip-lockfiles").required(false)) .arg(arg!([git] -t --git "Get git info - how many commits were made to each file").required(false)) .arg( arg!([match] @@ -59,6 +61,10 @@ pub fn run_cli() -> Result { let all = matches.get_one::("all").unwrap().to_owned(); let group = all || matches.get_one::("group").unwrap().to_owned(); let git = all || matches.get_one::("git").unwrap().to_owned(); + let skip_lockfiles = matches + .get_one::("skip-lockfiles") + .unwrap() + .to_owned(); let exclude = if let Some(globs) = matches.get_one::("exclude") { globs @@ -81,7 +87,12 @@ pub fn run_cli() -> Result { let cli = Cli { dir: dir.to_string(), num, - display_options: DisplayOptions { all, group, git }, + display_options: DisplayOptions { + all, + group, + git, + skip_lockfiles, + }, exclude, matches, }; diff --git a/src/display.rs b/src/display.rs index 29b7330..8386d0f 100644 --- a/src/display.rs +++ b/src/display.rs @@ -38,11 +38,10 @@ pub fn display_info( let mut grouped_files: HashMap> = HashMap::new(); for file in files.iter() { - if let Some(x) = grouped_files.get_mut(&file.clone().get_file_type()) { - x.push(file.clone()); - } else { - grouped_files.insert(file.clone().get_file_type(), vec![file.clone()]); - } + grouped_files + .entry(file.file_type) + .or_insert_with(|| Vec::new()) + .push(file.to_owned()); } println!( "{} {}\n", diff --git a/src/file.rs b/src/file.rs index 598ff0a..a8b6eee 100644 --- a/src/file.rs +++ b/src/file.rs @@ -5,6 +5,7 @@ use std::{ }; use ignore::{DirEntry, WalkBuilder}; +use regex::Regex; #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)] pub enum FileType { @@ -27,6 +28,7 @@ pub enum FileType { JavaScript, Julia, JupyterNotebook, + Lockfile, Lua, Markdown, Mojo, @@ -34,8 +36,8 @@ pub enum FileType { Python, Rust, SQL, - Svelte, SVG, + Svelte, Swift, TOML, TypeScript, @@ -52,16 +54,24 @@ pub struct File { pub path: String, pub loc: usize, pub extension: OsString, + pub file_type: FileType, pub commits: Option, } impl File { - pub fn get_file_type(&self) -> FileType { + pub fn add_file_type(&mut self) { if self.name.ends_with("svelte.ts") || self.name.ends_with("svelte.js") { - return FileType::Svelte; + self.file_type = FileType::Svelte; + return; + } + + let lockfile_regex = Regex::new("(pnpm-lock|package-lock|project.assets|packages.lock|npm-shrinkwrap|go|elm-package).(json|yaml|yml|sum)").unwrap(); + if lockfile_regex.is_match(self.name.as_str()) { + self.file_type = FileType::Lockfile; + return; } - match self.extension.to_str() { + self.file_type = match self.extension.to_str() { Some("js" | "cjs" | "mjs" | "jsx") => FileType::JavaScript, Some("ts" | "cts" | "mts" | "tsx") => FileType::TypeScript, Some("json" | "jsonb" | "jsonc") => FileType::JSON, @@ -78,6 +88,7 @@ impl File { Some("gql" | "graphql" | "graphqls") => FileType::GraphQL, Some("ex" | "exs") => FileType::Elixir, Some("zig") => FileType::Zig, + Some("lock") => FileType::Lockfile, Some("gleam") => FileType::Gleam, Some("swift") => FileType::Swift, Some("c" | "ec" | "idc" | "pdc") => FileType::C, @@ -115,7 +126,11 @@ impl Display for FileType { } } -pub fn get_files(dir: &str, overrides: ignore::overrides::Override) -> Vec { +pub fn get_files( + dir: &str, + overrides: ignore::overrides::Override, + skip_lockfiles: &bool, +) -> Vec { let mut files: Vec = Vec::new(); for result in WalkBuilder::new(dir) @@ -128,7 +143,11 @@ pub fn get_files(dir: &str, overrides: ignore::overrides::Override) -> Vec if entry.path().to_str().unwrap().contains(".git/") { continue; } - if let Some(file) = get_file_info(&entry, dir) { + if let Some(mut file) = get_file_info(&entry, dir) { + file.add_file_type(); + if *skip_lockfiles && file.file_type == FileType::Lockfile { + continue; + } files.push(file) } } @@ -162,6 +181,7 @@ fn get_file_info(entry: &DirEntry, dir: &str) -> Option { extension, loc: lines, commits: None, + file_type: FileType::Other, }); } @@ -174,14 +194,40 @@ mod tests { #[test] fn file_type() { - let file = File { + let mut file = File { name: String::from("foo.rs"), path: String::from("foo.rs"), loc: 12, extension: OsString::from("rs"), commits: None, + file_type: FileType::Other, + }; + file.add_file_type(); + + assert_eq!(file.file_type, FileType::Rust); + + let mut file = File { + name: String::from("Cargo.lock"), + path: String::from("Cargo.lock"), + loc: 12, + extension: OsString::from("lock"), + commits: None, + file_type: FileType::Other, + }; + file.add_file_type(); + + assert_eq!(file.file_type, FileType::Lockfile); + + let mut file = File { + name: String::from("pnpm-lock.yaml"), + path: String::from("pnpm-lock.yaml"), + loc: 12, + extension: OsString::from("yaml"), + commits: None, + file_type: FileType::Other, }; + file.add_file_type(); - assert_eq!(file.get_file_type(), FileType::Rust) + assert_eq!(file.file_type, FileType::Lockfile) } } diff --git a/src/main.rs b/src/main.rs index e44e09a..199e4ad 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,7 @@ fn main() { } let overrides = builder.build().unwrap(); - let mut files = get_files(dir, overrides); + let mut files = get_files(dir, overrides, &cli.display_options.skip_lockfiles); let total_commits = if cli.display_options.git || cli.display_options.all { add_git_info(&mut files, dir)