From 5a9ec6946f5ac677fb9a9a027a40b23f276ea6cf Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Sat, 31 Oct 2020 21:09:31 -0400 Subject: [PATCH 01/28] begin dependency feature Signed-off-by: Luke-zhang-04 --- src/onefetch/deps.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/onefetch/deps.rs diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs new file mode 100644 index 000000000..d82f88932 --- /dev/null +++ b/src/onefetch/deps.rs @@ -0,0 +1,48 @@ +use { + crate::onefetch::error::*, + std::{ffi::OsStr, fs}, + std::collections::HashMap, +}; + +mod Parsers { + fn npm(contents: &str) -> i32 { + println!(contents) + return 0 + } +} + + +type DependencyParser = fn(&str) -> i32; +let package_managers: HashMap<&str, (&str, DependencyParser)> = [ + ("npm", ("package.json", Parsers.npm)), +].iter().cloned().collect(); + +pub struct Detector {} + +impl Detector { + pub fn get_dep_count(&self, dir: &str) -> Result { + fn is_package_file>(file_name: S) -> bool { + package_managers + .iter() + .any(|&info| file_name.as_ref().starts_with(info[0])) + } + + let mut package_files = fs::read_dir(dir) + .chain_err(|| "Could not read directory")? + .filter_map(std::result::Result::ok) + .map(|entry| entry.path()) + .filter(|entry| { + entry.is_file() + && entry + .file_name() + .map(OsStr::to_string_lossy) + .map(is_package_file) + .unwrap_or_default() + }) + .filter_map(|entry| { + let contents = fs::read_to_string(entry).unwrap_or_default(); + self.analyze(&contents) + }) + .collect::>(); + } +} From 1c65108270c195a79b2997c9dcc4e1d6be93a4ef Mon Sep 17 00:00:00 2001 From: o2sh Date: Sun, 1 Nov 2020 20:19:29 +0100 Subject: [PATCH 02/28] fix get_deps() implementation --WIP --- src/onefetch/dependencies.rs | 72 ++++++++++++++++++++++++++++++++++++ src/onefetch/deps.rs | 48 ------------------------ src/onefetch/mod.rs | 1 + 3 files changed, 73 insertions(+), 48 deletions(-) create mode 100644 src/onefetch/dependencies.rs delete mode 100644 src/onefetch/deps.rs diff --git a/src/onefetch/dependencies.rs b/src/onefetch/dependencies.rs new file mode 100644 index 000000000..f553c3fa9 --- /dev/null +++ b/src/onefetch/dependencies.rs @@ -0,0 +1,72 @@ +use { + crate::onefetch::error::*, + std::collections::HashMap, + std::{ffi::OsStr, fs}, +}; + +pub enum PackageManager { + Npm, +} + +impl std::fmt::Display for PackageManager { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match *self { + PackageManager::Npm => write!(f, "Npm"), + } + } +} + +type DependencyParser = fn(&str) -> Option; + +struct Detector { + package_managers: HashMap, +} + +fn npm(contents: &str) -> Option { + Some(0) +} + +impl Detector { + pub fn new(&self) -> Detector { + let mut package_managers: HashMap = + HashMap::new(); + package_managers.insert(String::from("package.json"), (npm, PackageManager::Npm)); + + Detector { package_managers } + } + + pub fn get_dep_count(&self, dir: &str) -> Result { + fn is_package_file(detector: &Detector, file_name: &str) -> bool { + detector + .package_managers + .iter() + .any(|(package_manager_file_name, _)| { + file_name.starts_with(package_manager_file_name) + }) + } + + let package_files = fs::read_dir(dir) + .chain_err(|| "Could not read directory")? + .filter_map(std::result::Result::ok) + .map(|entry| entry.path()) + .filter(|entry| { + entry.is_file() + && entry + .file_name() + .map(OsStr::to_string_lossy) + .map(|s| is_package_file(&self, s.as_ref())) + .unwrap_or_default() + }) + .map(|entry| { + let (parser, package_manager) = + &self.package_managers[entry.file_name().unwrap().to_str().unwrap()]; + let contents = fs::read_to_string(entry).unwrap_or_default(); + format!("{} ({})", parser(&contents).unwrap(), package_manager) + }) + .collect::>(); + + let output = package_files.join(", "); + + Ok(output) + } +} diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs deleted file mode 100644 index d82f88932..000000000 --- a/src/onefetch/deps.rs +++ /dev/null @@ -1,48 +0,0 @@ -use { - crate::onefetch::error::*, - std::{ffi::OsStr, fs}, - std::collections::HashMap, -}; - -mod Parsers { - fn npm(contents: &str) -> i32 { - println!(contents) - return 0 - } -} - - -type DependencyParser = fn(&str) -> i32; -let package_managers: HashMap<&str, (&str, DependencyParser)> = [ - ("npm", ("package.json", Parsers.npm)), -].iter().cloned().collect(); - -pub struct Detector {} - -impl Detector { - pub fn get_dep_count(&self, dir: &str) -> Result { - fn is_package_file>(file_name: S) -> bool { - package_managers - .iter() - .any(|&info| file_name.as_ref().starts_with(info[0])) - } - - let mut package_files = fs::read_dir(dir) - .chain_err(|| "Could not read directory")? - .filter_map(std::result::Result::ok) - .map(|entry| entry.path()) - .filter(|entry| { - entry.is_file() - && entry - .file_name() - .map(OsStr::to_string_lossy) - .map(is_package_file) - .unwrap_or_default() - }) - .filter_map(|entry| { - let contents = fs::read_to_string(entry).unwrap_or_default(); - self.analyze(&contents) - }) - .collect::>(); - } -} diff --git a/src/onefetch/mod.rs b/src/onefetch/mod.rs index cec1f6aed..65fd283ba 100644 --- a/src/onefetch/mod.rs +++ b/src/onefetch/mod.rs @@ -2,6 +2,7 @@ pub mod ascii_art; pub mod cli; pub mod cli_utils; pub mod commit_info; +pub mod dependencies; pub mod error; pub mod image_backends; pub mod info; From cd63dae64ff5da27089294326bca6c05eb2d8570 Mon Sep 17 00:00:00 2001 From: o2sh Date: Sun, 1 Nov 2020 20:28:32 +0100 Subject: [PATCH 03/28] match on Option after parsing number of deps --- src/onefetch/dependencies.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/onefetch/dependencies.rs b/src/onefetch/dependencies.rs index f553c3fa9..b1c578226 100644 --- a/src/onefetch/dependencies.rs +++ b/src/onefetch/dependencies.rs @@ -57,11 +57,17 @@ impl Detector { .map(|s| is_package_file(&self, s.as_ref())) .unwrap_or_default() }) - .map(|entry| { + .filter_map(|entry| { let (parser, package_manager) = &self.package_managers[entry.file_name().unwrap().to_str().unwrap()]; let contents = fs::read_to_string(entry).unwrap_or_default(); - format!("{} ({})", parser(&contents).unwrap(), package_manager) + + match parser(&contents) { + Some(number_of_deps) => { + Some(format!("{} ({})", number_of_deps, package_manager)) + } + None => None, + } }) .collect::>(); From 596f2cfb92caa5d8a9b97faeea9b3477bf30d5f8 Mon Sep 17 00:00:00 2001 From: o2sh Date: Sun, 1 Nov 2020 20:39:52 +0100 Subject: [PATCH 04/28] rename dependencies --> deps --- src/onefetch/{dependencies.rs => deps.rs} | 0 src/onefetch/mod.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/onefetch/{dependencies.rs => deps.rs} (100%) diff --git a/src/onefetch/dependencies.rs b/src/onefetch/deps.rs similarity index 100% rename from src/onefetch/dependencies.rs rename to src/onefetch/deps.rs diff --git a/src/onefetch/mod.rs b/src/onefetch/mod.rs index 65fd283ba..18de075bb 100644 --- a/src/onefetch/mod.rs +++ b/src/onefetch/mod.rs @@ -2,7 +2,7 @@ pub mod ascii_art; pub mod cli; pub mod cli_utils; pub mod commit_info; -pub mod dependencies; +pub mod depe; pub mod error; pub mod image_backends; pub mod info; From 65819792268ead7ab5f834bdb8827ea4d322e098 Mon Sep 17 00:00:00 2001 From: o2sh Date: Sun, 1 Nov 2020 20:40:44 +0100 Subject: [PATCH 05/28] fix typo --- src/onefetch/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/onefetch/mod.rs b/src/onefetch/mod.rs index 18de075bb..50ca4e761 100644 --- a/src/onefetch/mod.rs +++ b/src/onefetch/mod.rs @@ -2,7 +2,7 @@ pub mod ascii_art; pub mod cli; pub mod cli_utils; pub mod commit_info; -pub mod depe; +pub mod deps; pub mod error; pub mod image_backends; pub mod info; From 230088d5a72010ccf43abea949e136eeb93e839f Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Wed, 4 Nov 2020 07:30:33 -0500 Subject: [PATCH 06/28] editorconfig did stuff Signed-off-by: Luke-zhang-04 --- src/onefetch/cli.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/onefetch/cli.rs b/src/onefetch/cli.rs index 30772b4c1..ae1f879ad 100644 --- a/src/onefetch/cli.rs +++ b/src/onefetch/cli.rs @@ -214,7 +214,7 @@ impl Cli { Arg::with_name("off") .long("off") .help("Only shows the info lines.") - .conflicts_with_all(&["image", "ascii-language", "ascii-input"]), + .conflicts_with_all(&["image", "ascii-language", "ascii-input"]), ).get_matches(); let no_bold = matches.is_present("no-bold"); From 1c627037f007ab217504d39e89bb076749de8960 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Wed, 4 Nov 2020 12:16:51 -0500 Subject: [PATCH 07/28] feat: add dependency insights field Signed-off-by: Luke-zhang-04 --- Cargo.lock | 7 +++++++ Cargo.toml | 3 ++- src/onefetch/deps.rs | 12 +++++++----- src/onefetch/info.rs | 14 +++++++++++++- src/onefetch/info_fields.rs | 3 +++ 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e50cb0044..0ef123891 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -868,6 +868,12 @@ dependencies = [ "rayon", ] +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + [[package]] name = "lazy_static" version = "1.4.0" @@ -1109,6 +1115,7 @@ dependencies = [ "futures", "git2", "image", + "json", "lazy_static", "libc", "more-asserts", diff --git a/Cargo.toml b/Cargo.toml index fc8090ec0..562f87ffc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ priority = "optional" color_quant = "1.1" # Use version required by image colored= "2.0.0" git2 = { version = "0.13.12", default-features = false } +json = "0.12.4" tokei = "12.0.0" askalono = "0.4.3" bytecount = "0.6.0" @@ -46,4 +47,4 @@ more-asserts = "0.2" paste = "1" [features] -fail-on-deprecated = [] \ No newline at end of file +fail-on-deprecated = [] diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs index b1c578226..9facbd7b9 100644 --- a/src/onefetch/deps.rs +++ b/src/onefetch/deps.rs @@ -18,24 +18,26 @@ impl std::fmt::Display for PackageManager { type DependencyParser = fn(&str) -> Option; -struct Detector { +pub struct Detector { package_managers: HashMap, } fn npm(contents: &str) -> Option { - Some(0) + let parsed = json::parse(contents).unwrap(); + + Some(parsed["dependencies"].len() as i32) } impl Detector { - pub fn new(&self) -> Detector { + pub fn new() -> Self { let mut package_managers: HashMap = HashMap::new(); package_managers.insert(String::from("package.json"), (npm, PackageManager::Npm)); - Detector { package_managers } + Self { package_managers } } - pub fn get_dep_count(&self, dir: &str) -> Result { + pub fn get_deps_info(&self, dir: &str) -> Result { fn is_package_file(detector: &Detector, file_name: &str) -> bool { detector .package_managers diff --git a/src/onefetch/info.rs b/src/onefetch/info.rs index 4e352ad2c..088cc3e79 100644 --- a/src/onefetch/info.rs +++ b/src/onefetch/info.rs @@ -1,6 +1,6 @@ use { crate::onefetch::{ - cli::Cli, commit_info::CommitInfo, error::*, language::Language, license::Detector, + cli::Cli, commit_info::CommitInfo, deps, error::*, language::Language, license::Detector, text_color::TextColor, }, colored::{Color, ColoredString, Colorize}, @@ -18,6 +18,7 @@ pub struct Info { creation_date: String, pub dominant_language: Language, languages: Vec<(Language, f64)>, + dependencies: String, authors: Vec<(String, usize, usize)>, last_change: String, repo_url: String, @@ -118,6 +119,15 @@ impl std::fmt::Display for Info { )?; } + if !self.config.disabled_fields.dependencies && !self.dependencies.is_empty() { + writeln!( + f, + "{}{}", + &self.get_formatted_subtitle_label("Dependencies"), + &self.dependencies.color(self.color_set.info), + )?; + } + if !self.config.disabled_fields.authors && !self.authors.is_empty() { let title = if self.authors.len() > 1 { "Authors" @@ -244,6 +254,7 @@ impl Info { let last_change = Info::get_date_of_last_commit(&git_history); let project_license = Detector::new()?.get_project_license(workdir_str); let dominant_language = Language::get_dominant_language(&languages_stats); + let dependencies = deps::Detector::new().get_deps_info(workdir_str).unwrap(); let colors = Info::get_colors( &config.ascii_language, &dominant_language, @@ -261,6 +272,7 @@ impl Info { creation_date: creation_date?, dominant_language, languages: languages_stats, + dependencies, authors, last_change: last_change?, repo_url: repository_url, diff --git a/src/onefetch/info_fields.rs b/src/onefetch/info_fields.rs index 2005e3ff0..6442cf3ab 100644 --- a/src/onefetch/info_fields.rs +++ b/src/onefetch/info_fields.rs @@ -11,6 +11,7 @@ pub struct InfoFieldOn { pub head: bool, pub version: bool, pub created: bool, + pub dependencies: bool, pub languages: bool, pub authors: bool, pub last_change: bool, @@ -30,6 +31,7 @@ pub enum InfoFields { HEAD, Version, Created, + Dependencies, Languages, Authors, LastChange, @@ -57,6 +59,7 @@ pub fn get_disabled_fields(fields_to_hide: Vec) -> Result { InfoFields::HEAD => disabled_fields.head = true, InfoFields::Version => disabled_fields.version = true, InfoFields::Created => disabled_fields.created = true, + InfoFields::Dependencies => disabled_fields.dependencies = true, InfoFields::Languages => disabled_fields.languages = true, InfoFields::Authors => disabled_fields.authors = true, InfoFields::LastChange => disabled_fields.last_change = true, From 582b24609fde4a1a568cb85ee60e475d0ea8ede9 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Wed, 4 Nov 2020 12:30:07 -0500 Subject: [PATCH 08/28] feat: add support for go modules Signed-off-by: Luke-zhang-04 --- src/onefetch/deps.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs index 9facbd7b9..33caad7d7 100644 --- a/src/onefetch/deps.rs +++ b/src/onefetch/deps.rs @@ -1,17 +1,20 @@ use { crate::onefetch::error::*, + regex::Regex, std::collections::HashMap, std::{ffi::OsStr, fs}, }; pub enum PackageManager { Npm, + GoModules, } impl std::fmt::Display for PackageManager { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { PackageManager::Npm => write!(f, "Npm"), + PackageManager::GoModules => write!(f, "Go Modules"), } } } @@ -28,11 +31,21 @@ fn npm(contents: &str) -> Option { Some(parsed["dependencies"].len() as i32) } +fn gomodules(contents: &str) -> Option { + let count = Regex::new(r"v[0-9].").unwrap().find_iter(contents).count(); + + Some(count as i32) +} + impl Detector { pub fn new() -> Self { let mut package_managers: HashMap = HashMap::new(); package_managers.insert(String::from("package.json"), (npm, PackageManager::Npm)); + package_managers.insert( + String::from("go.mod"), + (gomodules, PackageManager::GoModules), + ); Self { package_managers } } From d79f447a47cbc4e4e7d591471cb217807ffc8827 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Wed, 4 Nov 2020 12:52:37 -0500 Subject: [PATCH 09/28] feat: add support for pip Signed-off-by: Luke-zhang-04 --- src/onefetch/deps.rs | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs index 33caad7d7..ca7e4003a 100644 --- a/src/onefetch/deps.rs +++ b/src/onefetch/deps.rs @@ -1,20 +1,21 @@ use { crate::onefetch::error::*, - regex::Regex, std::collections::HashMap, std::{ffi::OsStr, fs}, }; pub enum PackageManager { - Npm, GoModules, + Npm, + Pip, } impl std::fmt::Display for PackageManager { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { - PackageManager::Npm => write!(f, "Npm"), PackageManager::GoModules => write!(f, "Go Modules"), + PackageManager::Npm => write!(f, "Npm"), + PackageManager::Pip => write!(f, "Pip"), } } } @@ -25,26 +26,45 @@ pub struct Detector { package_managers: HashMap, } -fn npm(contents: &str) -> Option { - let parsed = json::parse(contents).unwrap(); +// Package parsers go here. Parsers should take stirng contents and output a i32 +mod package_parsers { + use regex::Regex; - Some(parsed["dependencies"].len() as i32) -} + pub fn gomodules(contents: &str) -> Option { + let count = Regex::new(r"v[0-9]+").unwrap().find_iter(contents).count(); + + Some(count as i32) + } + + pub fn npm(contents: &str) -> Option { + let parsed = json::parse(contents).unwrap(); -fn gomodules(contents: &str) -> Option { - let count = Regex::new(r"v[0-9].").unwrap().find_iter(contents).count(); + Some(parsed["dependencies"].len() as i32) + } + + pub fn pip(contents: &str) -> Option { + let count = Regex::new(r"(^[A-z]+)|(\n[A-z]+)").unwrap().find_iter(contents).count(); - Some(count as i32) + Some(count as i32) + } } impl Detector { pub fn new() -> Self { let mut package_managers: HashMap = HashMap::new(); - package_managers.insert(String::from("package.json"), (npm, PackageManager::Npm)); + package_managers.insert( String::from("go.mod"), - (gomodules, PackageManager::GoModules), + (package_parsers::gomodules, PackageManager::GoModules), + ); + package_managers.insert( + String::from("package.json"), + (package_parsers::npm, PackageManager::Npm), + ); + package_managers.insert( + String::from("requirements.txt"), + (package_parsers::pip, PackageManager::Pip), ); Self { package_managers } From bd98e3a42918e3d9edaef5937bafd3b355075a6f Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Wed, 4 Nov 2020 12:53:39 -0500 Subject: [PATCH 10/28] rust fmt Signed-off-by: Luke-zhang-04 --- src/onefetch/deps.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs index ca7e4003a..a62586ea0 100644 --- a/src/onefetch/deps.rs +++ b/src/onefetch/deps.rs @@ -43,7 +43,10 @@ mod package_parsers { } pub fn pip(contents: &str) -> Option { - let count = Regex::new(r"(^[A-z]+)|(\n[A-z]+)").unwrap().find_iter(contents).count(); + let count = Regex::new(r"(^[A-z]+)|(\n[A-z]+)") + .unwrap() + .find_iter(contents) + .count(); Some(count as i32) } From 23042b48811e54f6b8323c3901cb336b34abac72 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Wed, 4 Nov 2020 15:14:58 -0500 Subject: [PATCH 11/28] rust fmt Signed-off-by: Luke-zhang-04 --- src/onefetch/deps.rs | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs index a62586ea0..178b8f94e 100644 --- a/src/onefetch/deps.rs +++ b/src/onefetch/deps.rs @@ -43,10 +43,7 @@ mod package_parsers { } pub fn pip(contents: &str) -> Option { - let count = Regex::new(r"(^[A-z]+)|(\n[A-z]+)") - .unwrap() - .find_iter(contents) - .count(); + let count = Regex::new(r"(^[A-z]+)|(\n[A-z]+)").unwrap().find_iter(contents).count(); Some(count as i32) } @@ -61,26 +58,19 @@ impl Detector { String::from("go.mod"), (package_parsers::gomodules, PackageManager::GoModules), ); - package_managers.insert( - String::from("package.json"), - (package_parsers::npm, PackageManager::Npm), - ); - package_managers.insert( - String::from("requirements.txt"), - (package_parsers::pip, PackageManager::Pip), - ); + package_managers + .insert(String::from("package.json"), (package_parsers::npm, PackageManager::Npm)); + package_managers + .insert(String::from("requirements.txt"), (package_parsers::pip, PackageManager::Pip)); Self { package_managers } } pub fn get_deps_info(&self, dir: &str) -> Result { fn is_package_file(detector: &Detector, file_name: &str) -> bool { - detector - .package_managers - .iter() - .any(|(package_manager_file_name, _)| { - file_name.starts_with(package_manager_file_name) - }) + detector.package_managers.iter().any(|(package_manager_file_name, _)| { + file_name.starts_with(package_manager_file_name) + }) } let package_files = fs::read_dir(dir) From deefcb53631635fa76d0f331d852b5c18ba3a487 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Wed, 4 Nov 2020 15:22:26 -0500 Subject: [PATCH 12/28] feat: add support for yarn Signed-off-by: Luke-zhang-04 --- src/onefetch/deps.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs index 178b8f94e..9f6299e25 100644 --- a/src/onefetch/deps.rs +++ b/src/onefetch/deps.rs @@ -14,7 +14,13 @@ impl std::fmt::Display for PackageManager { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { PackageManager::GoModules => write!(f, "Go Modules"), - PackageManager::Npm => write!(f, "Npm"), + PackageManager::Npm => { + if std::path::Path::new("./yarn.lock").exists() { + write!(f, "Yarn") + } else { + write!(f, "Npm") + } + } PackageManager::Pip => write!(f, "Pip"), } } From f5ea1f7c4befcd5d0c9983b887761c24a0fc59de Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Wed, 4 Nov 2020 15:57:58 -0500 Subject: [PATCH 13/28] feat: add support for Cargo Signed-off-by: Luke-zhang-04 --- Cargo.lock | 13 +++++++------ Cargo.toml | 1 + src/onefetch/deps.rs | 15 ++++++++++++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b68a4ccc..2a2c8e720 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -956,6 +956,7 @@ dependencies = [ "regex", "strum", "tokei", + "toml", ] [[package]] @@ -1275,18 +1276,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" dependencies = [ "proc-macro2", "quote", @@ -1497,9 +1498,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" dependencies = [ "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 3ee4bb37f..0e09311be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,7 @@ strum = { version = "0.19.5", features = ["derive"] } image = "0.23.11" regex = "1" error-chain = "0.12" +toml = "0.5.7" [target.'cfg(windows)'.dependencies] ansi_term = "0.12" diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs index 9f6299e25..f8be318ef 100644 --- a/src/onefetch/deps.rs +++ b/src/onefetch/deps.rs @@ -5,6 +5,7 @@ use { }; pub enum PackageManager { + Cargo, GoModules, Npm, Pip, @@ -13,6 +14,7 @@ pub enum PackageManager { impl std::fmt::Display for PackageManager { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match *self { + PackageManager::Cargo => write!(f, "Cargo"), PackageManager::GoModules => write!(f, "Go Modules"), PackageManager::Npm => { if std::path::Path::new("./yarn.lock").exists() { @@ -34,7 +36,16 @@ pub struct Detector { // Package parsers go here. Parsers should take stirng contents and output a i32 mod package_parsers { - use regex::Regex; + use { + regex::Regex, + toml::Value, + }; + + pub fn cargo(contents: &str) -> Option { + let parsed = contents.parse::().unwrap(); + + Some(parsed["dependencies"].as_table().unwrap().len() as i32) + } pub fn gomodules(contents: &str) -> Option { let count = Regex::new(r"v[0-9]+").unwrap().find_iter(contents).count(); @@ -60,6 +71,8 @@ impl Detector { let mut package_managers: HashMap = HashMap::new(); + package_managers + .insert(String::from("Cargo.toml"), (package_parsers::cargo, PackageManager::Cargo)); package_managers.insert( String::from("go.mod"), (package_parsers::gomodules, PackageManager::GoModules), From b966cc5125ecf2b66a5028d1278c6716e3c20997 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Wed, 4 Nov 2020 16:00:01 -0500 Subject: [PATCH 14/28] cargo fmt Signed-off-by: Luke-zhang-04 --- src/onefetch/deps.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs index f8be318ef..ba54ce35d 100644 --- a/src/onefetch/deps.rs +++ b/src/onefetch/deps.rs @@ -36,10 +36,7 @@ pub struct Detector { // Package parsers go here. Parsers should take stirng contents and output a i32 mod package_parsers { - use { - regex::Regex, - toml::Value, - }; + use {regex::Regex, toml::Value}; pub fn cargo(contents: &str) -> Option { let parsed = contents.parse::().unwrap(); From 369506c03c3989962f635a1c6c731cafb40991d5 Mon Sep 17 00:00:00 2001 From: o2sh Date: Thu, 5 Nov 2020 14:49:29 +0100 Subject: [PATCH 15/28] split deps into multiple files and replace Option with Result for better error handling --- src/onefetch/deps.rs | 122 --------------------------- src/onefetch/deps/mod.rs | 76 +++++++++++++++++ src/onefetch/deps/package_manager.rs | 23 +++++ src/onefetch/deps/package_parser.rs | 26 ++++++ src/onefetch/error.rs | 3 + src/onefetch/info.rs | 2 +- 6 files changed, 129 insertions(+), 123 deletions(-) delete mode 100644 src/onefetch/deps.rs create mode 100644 src/onefetch/deps/mod.rs create mode 100644 src/onefetch/deps/package_manager.rs create mode 100644 src/onefetch/deps/package_parser.rs diff --git a/src/onefetch/deps.rs b/src/onefetch/deps.rs deleted file mode 100644 index ba54ce35d..000000000 --- a/src/onefetch/deps.rs +++ /dev/null @@ -1,122 +0,0 @@ -use { - crate::onefetch::error::*, - std::collections::HashMap, - std::{ffi::OsStr, fs}, -}; - -pub enum PackageManager { - Cargo, - GoModules, - Npm, - Pip, -} - -impl std::fmt::Display for PackageManager { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match *self { - PackageManager::Cargo => write!(f, "Cargo"), - PackageManager::GoModules => write!(f, "Go Modules"), - PackageManager::Npm => { - if std::path::Path::new("./yarn.lock").exists() { - write!(f, "Yarn") - } else { - write!(f, "Npm") - } - } - PackageManager::Pip => write!(f, "Pip"), - } - } -} - -type DependencyParser = fn(&str) -> Option; - -pub struct Detector { - package_managers: HashMap, -} - -// Package parsers go here. Parsers should take stirng contents and output a i32 -mod package_parsers { - use {regex::Regex, toml::Value}; - - pub fn cargo(contents: &str) -> Option { - let parsed = contents.parse::().unwrap(); - - Some(parsed["dependencies"].as_table().unwrap().len() as i32) - } - - pub fn gomodules(contents: &str) -> Option { - let count = Regex::new(r"v[0-9]+").unwrap().find_iter(contents).count(); - - Some(count as i32) - } - - pub fn npm(contents: &str) -> Option { - let parsed = json::parse(contents).unwrap(); - - Some(parsed["dependencies"].len() as i32) - } - - pub fn pip(contents: &str) -> Option { - let count = Regex::new(r"(^[A-z]+)|(\n[A-z]+)").unwrap().find_iter(contents).count(); - - Some(count as i32) - } -} - -impl Detector { - pub fn new() -> Self { - let mut package_managers: HashMap = - HashMap::new(); - - package_managers - .insert(String::from("Cargo.toml"), (package_parsers::cargo, PackageManager::Cargo)); - package_managers.insert( - String::from("go.mod"), - (package_parsers::gomodules, PackageManager::GoModules), - ); - package_managers - .insert(String::from("package.json"), (package_parsers::npm, PackageManager::Npm)); - package_managers - .insert(String::from("requirements.txt"), (package_parsers::pip, PackageManager::Pip)); - - Self { package_managers } - } - - pub fn get_deps_info(&self, dir: &str) -> Result { - fn is_package_file(detector: &Detector, file_name: &str) -> bool { - detector.package_managers.iter().any(|(package_manager_file_name, _)| { - file_name.starts_with(package_manager_file_name) - }) - } - - let package_files = fs::read_dir(dir) - .chain_err(|| "Could not read directory")? - .filter_map(std::result::Result::ok) - .map(|entry| entry.path()) - .filter(|entry| { - entry.is_file() - && entry - .file_name() - .map(OsStr::to_string_lossy) - .map(|s| is_package_file(&self, s.as_ref())) - .unwrap_or_default() - }) - .filter_map(|entry| { - let (parser, package_manager) = - &self.package_managers[entry.file_name().unwrap().to_str().unwrap()]; - let contents = fs::read_to_string(entry).unwrap_or_default(); - - match parser(&contents) { - Some(number_of_deps) => { - Some(format!("{} ({})", number_of_deps, package_manager)) - } - None => None, - } - }) - .collect::>(); - - let output = package_files.join(", "); - - Ok(output) - } -} diff --git a/src/onefetch/deps/mod.rs b/src/onefetch/deps/mod.rs new file mode 100644 index 000000000..5ff6fd50c --- /dev/null +++ b/src/onefetch/deps/mod.rs @@ -0,0 +1,76 @@ +use { + crate::onefetch::error::*, + std::collections::HashMap, + std::{ffi::OsStr, fs}, +}; + +mod package_manager; +mod package_parser; + +type DependencyParser = fn(&str) -> Result; + +pub struct DependencyDetector { + package_managers: HashMap, +} + +impl DependencyDetector { + pub fn new() -> Self { + let mut package_managers: HashMap< + String, + (DependencyParser, package_manager::PackageManager), + > = HashMap::new(); + + package_managers.insert( + String::from("Cargo.toml"), + (package_parser::cargo, package_manager::PackageManager::Cargo), + ); + package_managers.insert( + String::from("go.mod"), + (package_parser::go_modules, package_manager::PackageManager::GoModules), + ); + package_managers.insert( + String::from("package.json"), + (package_parser::npm, package_manager::PackageManager::Npm), + ); + package_managers.insert( + String::from("requirements.txt"), + (package_parser::pip, package_manager::PackageManager::Pip), + ); + + DependencyDetector { package_managers } + } + + pub fn get_deps_info(&self, dir: &str) -> Result { + fn is_package_file(detector: &DependencyDetector, file_name: &str) -> bool { + detector.package_managers.iter().any(|(package_manager_file_name, _)| { + file_name.starts_with(package_manager_file_name) + }) + } + + let deps = fs::read_dir(dir) + .chain_err(|| "Could not read directory")? + .filter_map(std::result::Result::ok) + .map(|entry| entry.path()) + .filter(|entry| { + entry.is_file() + && entry + .file_name() + .map(OsStr::to_string_lossy) + .map(|s| is_package_file(&self, s.as_ref())) + .unwrap_or_default() + }) + .map(|entry| { + let (parser, package_manager) = + &self.package_managers[entry.file_name().unwrap().to_str().unwrap()]; + let contents = fs::read_to_string(entry)?; + let number_of_deps = parser(&contents)?; + Ok(format!("{} ({})", number_of_deps, package_manager)) + }) + .filter_map(Result::ok) + .collect::>(); + + let output = deps.join(", "); + + Ok(output) + } +} diff --git a/src/onefetch/deps/package_manager.rs b/src/onefetch/deps/package_manager.rs new file mode 100644 index 000000000..647ab80d3 --- /dev/null +++ b/src/onefetch/deps/package_manager.rs @@ -0,0 +1,23 @@ +pub enum PackageManager { + Cargo, + GoModules, + Npm, + Pip, +} + +impl std::fmt::Display for PackageManager { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match *self { + PackageManager::Cargo => write!(f, "Cargo"), + PackageManager::GoModules => write!(f, "Go Modules"), + PackageManager::Npm => { + if std::path::Path::new("./yarn.lock").exists() { + write!(f, "Yarn") + } else { + write!(f, "Npm") + } + } + PackageManager::Pip => write!(f, "Pip"), + } + } +} diff --git a/src/onefetch/deps/package_parser.rs b/src/onefetch/deps/package_parser.rs new file mode 100644 index 000000000..3b900a188 --- /dev/null +++ b/src/onefetch/deps/package_parser.rs @@ -0,0 +1,26 @@ +use crate::onefetch::error::*; +use {regex::Regex, toml::Value}; + +pub fn cargo(contents: &str) -> Result { + let parsed = contents.parse::()?; + + Ok(parsed["dependencies"].as_table().unwrap().len() as i32) +} + +pub fn go_modules(contents: &str) -> Result { + let count = Regex::new(r"v[0-9]+")?.find_iter(contents).count(); + + Ok(count as i32) +} + +pub fn npm(contents: &str) -> Result { + let parsed = json::parse(contents)?; + + Ok(parsed["dependencies"].len() as i32) +} + +pub fn pip(contents: &str) -> Result { + let count = Regex::new(r"(^[A-z]+)|(\n[A-z]+)")?.find_iter(contents).count(); + + Ok(count as i32) +} diff --git a/src/onefetch/error.rs b/src/onefetch/error.rs index ce0537e94..136f04a1d 100644 --- a/src/onefetch/error.rs +++ b/src/onefetch/error.rs @@ -9,6 +9,9 @@ error_chain! { ParseIntError(::std::num::ParseIntError); Image(image::error::ImageError); Utf8(std::string::FromUtf8Error); + Json(json::Error); + Regex(regex::Error); + Toml(toml::de::Error); } } diff --git a/src/onefetch/info.rs b/src/onefetch/info.rs index 1e0b173cb..68e1245cc 100644 --- a/src/onefetch/info.rs +++ b/src/onefetch/info.rs @@ -232,7 +232,7 @@ impl Info { let last_change = Info::get_date_of_last_commit(&git_history); let project_license = Detector::new()?.get_project_license(workdir_str); let dominant_language = Language::get_dominant_language(&languages_stats); - let dependencies = deps::Detector::new().get_deps_info(workdir_str).unwrap(); + let dependencies = deps::DependencyDetector::new().get_deps_info(workdir_str).unwrap(); let colors = Info::get_colors( &config.ascii_language, &dominant_language, From 5bb1e05899962b3edf704d69e6c18caa5c23c8cd Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Thu, 5 Nov 2020 09:34:38 -0500 Subject: [PATCH 16/28] docs: adding a new package manager Signed-off-by: Luke-zhang-04 --- CONTRIBUTING.md | 54 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6b7f61e3c..661daff84 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ -Thank you for your interest in contributing to onefetch! Whether it's a bug report, new feature, correction, or additional +Thank you for your interest in contributing to onefetch! Whether it's a bug report, new feature, correction, or additional documentation, we greatly value feedback and contributions from our community. -Please read through this document before submitting any issues or pull requests to ensure we have all the necessary +Please read through this document before submitting any issues or pull requests to ensure we have all the necessary information to effectively respond to your bug report or contribution. # Contributing Guidelines @@ -17,7 +17,7 @@ information to effectively respond to your bug report or contribution. We welcome you to use the GitHub issue tracker to report bugs or suggest features. -When filing an issue, please check [existing open](https://github.com/o2sh/onefetch/issues), or [recently closed](https://github.com/o2sh/onefetch/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already +When filing an issue, please check [existing open](https://github.com/o2sh/onefetch/issues), or [recently closed](https://github.com/o2sh/onefetch/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: * A reproducible test case or series of steps @@ -42,7 +42,7 @@ To send us a pull request, please: 5. Send us a pull request, answering any default questions in the pull request interface. 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. -GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and +GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). ### Finding contributions to work on @@ -61,10 +61,54 @@ Adding support for a new Language requires adding a new entry in the `define_lan The first item `CSharp` corresponds to the name of the language as defined in tokei. The second item `csharp.ascii` is the name of the file containing the ascii logo, this file has to be placed in the _./resources_ folder (more info below). The third item `C#` is the display name. Then we have the colors used to customize the look of the ascii logo when displayed to the screen. The last item `c#` is required only if the Enum name `CSharp` doesn't match the display name `C#`. +### Adding support for a new package manager + +Any package manager is supported, as long as there is a file you can get the dependencies from. + +To add a new package manager, make sure you follow these steps: +1. in `src/onefetch/deps/package_manager.rs`, add the name of your package manager to the `PackageManager` enum +```rust +pub enum PackageManager { + // ... + Cargo, + // ... +} +``` + +2. in `src/onefetch/deps/package_manager.rs`, add a `writeln` macro call to the `fmt` function +```rust +fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match *self { + // ... + PackageManager::Cargo => write!(f, "Cargo"), + // ... + } +} +``` + +3. in `src/onefetch/deps/package_parser.rs`, add a function whose name corresponds to your manager. This function should take in a `string` as the contents of the package manager file, and return `i32` as the number of dependencies +```rust +pub fn cargo(contents: &str) -> Result { + let parsed = contents.parse::()?; + + Ok(parsed["dependencies"].as_table().unwrap().len() as i32) +} +``` + +4. in `src/onefetch/deps/mod.rs`, in the `new` method of the `DependencyDetector` impl, insert your new package managers information +```rust +package_managers.insert( + String::from("Cargo.toml"), // File name + + // Parser function, then writeln! macro + (package_parser::cargo, package_manager::PackageManager::Cargo), +); +``` + #### Ascii logo ``` -{4} _{1} _ _ +{4} _{1} _ _ {4} _|_{1}(_|/ \ {0} o{4}| {1} _|\_/ From afc7ef086bcf24687735969d69afa12fa9ef090d Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Thu, 5 Nov 2020 09:56:02 -0500 Subject: [PATCH 17/28] change i32 in `package_parsers` to uint Signed-off-by: Luke-zhang-04 --- CONTRIBUTING.md | 6 +++--- src/onefetch/deps/mod.rs | 2 +- src/onefetch/deps/package_parser.rs | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 661daff84..01db5e280 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -86,12 +86,12 @@ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { } ``` -3. in `src/onefetch/deps/package_parser.rs`, add a function whose name corresponds to your manager. This function should take in a `string` as the contents of the package manager file, and return `i32` as the number of dependencies +3. in `src/onefetch/deps/package_parser.rs`, add a function whose name corresponds to your manager. This function should take in a `string` as the contents of the package manager file, and return `usize` as the number of dependencies ```rust -pub fn cargo(contents: &str) -> Result { +pub fn cargo(contents: &str) -> Result { let parsed = contents.parse::()?; - Ok(parsed["dependencies"].as_table().unwrap().len() as i32) + Ok(parsed["dependencies"].as_table().unwrap().len()) } ``` diff --git a/src/onefetch/deps/mod.rs b/src/onefetch/deps/mod.rs index 5ff6fd50c..1908bc2da 100644 --- a/src/onefetch/deps/mod.rs +++ b/src/onefetch/deps/mod.rs @@ -7,7 +7,7 @@ use { mod package_manager; mod package_parser; -type DependencyParser = fn(&str) -> Result; +type DependencyParser = fn(&str) -> Result; pub struct DependencyDetector { package_managers: HashMap, diff --git a/src/onefetch/deps/package_parser.rs b/src/onefetch/deps/package_parser.rs index 3b900a188..501e6b29f 100644 --- a/src/onefetch/deps/package_parser.rs +++ b/src/onefetch/deps/package_parser.rs @@ -1,26 +1,26 @@ use crate::onefetch::error::*; use {regex::Regex, toml::Value}; -pub fn cargo(contents: &str) -> Result { +pub fn cargo(contents: &str) -> Result { let parsed = contents.parse::()?; - Ok(parsed["dependencies"].as_table().unwrap().len() as i32) + Ok(parsed["dependencies"].as_table().unwrap().len()) } -pub fn go_modules(contents: &str) -> Result { +pub fn go_modules(contents: &str) -> Result { let count = Regex::new(r"v[0-9]+")?.find_iter(contents).count(); - Ok(count as i32) + Ok(count) } -pub fn npm(contents: &str) -> Result { +pub fn npm(contents: &str) -> Result { let parsed = json::parse(contents)?; - Ok(parsed["dependencies"].len() as i32) + Ok(parsed["dependencies"].len()) } -pub fn pip(contents: &str) -> Result { +pub fn pip(contents: &str) -> Result { let count = Regex::new(r"(^[A-z]+)|(\n[A-z]+)")?.find_iter(contents).count(); - Ok(count as i32) + Ok(count) } From 9311d49cd4637508c19bccd2c10883fb45b3de84 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Thu, 5 Nov 2020 11:25:56 -0500 Subject: [PATCH 18/28] fix: detect `yarn.lock` with absolute directory Signed-off-by: Luke-zhang-04 --- src/onefetch/deps/mod.rs | 14 ++++++++++++-- src/onefetch/deps/package_manager.rs | 11 ++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/onefetch/deps/mod.rs b/src/onefetch/deps/mod.rs index 1908bc2da..381e98fb2 100644 --- a/src/onefetch/deps/mod.rs +++ b/src/onefetch/deps/mod.rs @@ -60,11 +60,21 @@ impl DependencyDetector { .unwrap_or_default() }) .map(|entry| { - let (parser, package_manager) = + let (parser, found_package_manager) = &self.package_managers[entry.file_name().unwrap().to_str().unwrap()]; let contents = fs::read_to_string(entry)?; let number_of_deps = parser(&contents)?; - Ok(format!("{} ({})", number_of_deps, package_manager)) + let used_package_manager; + + if found_package_manager == &package_manager::PackageManager::Npm + && std::path::Path::new(&format!("{}yarn.lock", dir)).exists() + { + used_package_manager = &package_manager::PackageManager::Yarn; + } else { + used_package_manager = found_package_manager; + } + + Ok(format!("{} ({})", number_of_deps, used_package_manager)) }) .filter_map(Result::ok) .collect::>(); diff --git a/src/onefetch/deps/package_manager.rs b/src/onefetch/deps/package_manager.rs index 647ab80d3..8544880e3 100644 --- a/src/onefetch/deps/package_manager.rs +++ b/src/onefetch/deps/package_manager.rs @@ -1,8 +1,10 @@ +#[derive(PartialEq)] pub enum PackageManager { Cargo, GoModules, Npm, Pip, + Yarn, } impl std::fmt::Display for PackageManager { @@ -10,14 +12,9 @@ impl std::fmt::Display for PackageManager { match *self { PackageManager::Cargo => write!(f, "Cargo"), PackageManager::GoModules => write!(f, "Go Modules"), - PackageManager::Npm => { - if std::path::Path::new("./yarn.lock").exists() { - write!(f, "Yarn") - } else { - write!(f, "Npm") - } - } + PackageManager::Npm => write!(f, "Npm"), PackageManager::Pip => write!(f, "Pip"), + PackageManager::Yarn => write!(f, "Yarn"), } } } From a19ced85921a17a42ad2d76b744ba765f1038341 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Thu, 5 Nov 2020 11:28:46 -0500 Subject: [PATCH 19/28] refactor: simplify regex in package parsers Signed-off-by: Luke-zhang-04 --- src/onefetch/deps/package_parser.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/onefetch/deps/package_parser.rs b/src/onefetch/deps/package_parser.rs index 501e6b29f..6715ccc29 100644 --- a/src/onefetch/deps/package_parser.rs +++ b/src/onefetch/deps/package_parser.rs @@ -20,7 +20,7 @@ pub fn npm(contents: &str) -> Result { } pub fn pip(contents: &str) -> Result { - let count = Regex::new(r"(^[A-z]+)|(\n[A-z]+)")?.find_iter(contents).count(); + let count = Regex::new(r"(^|\n)[A-z]+")?.find_iter(contents).count(); Ok(count) } From d60ecfe3dda5b74531d77aaff6b648eac6be7799 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Thu, 5 Nov 2020 11:31:51 -0500 Subject: [PATCH 20/28] catch dependencies instead of `.unwrap()` Signed-off-by: Luke-zhang-04 --- src/onefetch/info.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/onefetch/info.rs b/src/onefetch/info.rs index 68e1245cc..932d002fa 100644 --- a/src/onefetch/info.rs +++ b/src/onefetch/info.rs @@ -232,7 +232,7 @@ impl Info { let last_change = Info::get_date_of_last_commit(&git_history); let project_license = Detector::new()?.get_project_license(workdir_str); let dominant_language = Language::get_dominant_language(&languages_stats); - let dependencies = deps::DependencyDetector::new().get_deps_info(workdir_str).unwrap(); + let dependencies = deps::DependencyDetector::new().get_deps_info(workdir_str)?; let colors = Info::get_colors( &config.ascii_language, &dominant_language, From 6fdb61d9187308f568833227ac2a8a1c358d66b9 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Thu, 5 Nov 2020 11:44:31 -0500 Subject: [PATCH 21/28] refactor: move `is_package_file` to Detector impl` Signed-off-by: Luke-zhang-04 --- src/onefetch/deps/mod.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/onefetch/deps/mod.rs b/src/onefetch/deps/mod.rs index 381e98fb2..8a2151167 100644 --- a/src/onefetch/deps/mod.rs +++ b/src/onefetch/deps/mod.rs @@ -40,13 +40,13 @@ impl DependencyDetector { DependencyDetector { package_managers } } - pub fn get_deps_info(&self, dir: &str) -> Result { - fn is_package_file(detector: &DependencyDetector, file_name: &str) -> bool { - detector.package_managers.iter().any(|(package_manager_file_name, _)| { - file_name.starts_with(package_manager_file_name) - }) - } + fn is_package_file(&self, file_name: &str) -> bool { + self.package_managers.iter().any(|(package_manager_file_name, _)| { + file_name.starts_with(package_manager_file_name) + }) + } + pub fn get_deps_info(&self, dir: &str) -> Result { let deps = fs::read_dir(dir) .chain_err(|| "Could not read directory")? .filter_map(std::result::Result::ok) @@ -56,7 +56,7 @@ impl DependencyDetector { && entry .file_name() .map(OsStr::to_string_lossy) - .map(|s| is_package_file(&self, s.as_ref())) + .map(|s| self.is_package_file(s.as_ref())) .unwrap_or_default() }) .map(|entry| { From 0b8caa0b52bdd1eddb585ecef8eaa8f8b73d4e88 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Thu, 5 Nov 2020 11:56:17 -0500 Subject: [PATCH 22/28] refactor: use `map.contains_key()` instead of iterating using map.contains_key is easier to understand and probably has better lookup time Signed-off-by: Luke-zhang-04 --- src/onefetch/deps/mod.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/onefetch/deps/mod.rs b/src/onefetch/deps/mod.rs index 8a2151167..ccc122707 100644 --- a/src/onefetch/deps/mod.rs +++ b/src/onefetch/deps/mod.rs @@ -40,12 +40,6 @@ impl DependencyDetector { DependencyDetector { package_managers } } - fn is_package_file(&self, file_name: &str) -> bool { - self.package_managers.iter().any(|(package_manager_file_name, _)| { - file_name.starts_with(package_manager_file_name) - }) - } - pub fn get_deps_info(&self, dir: &str) -> Result { let deps = fs::read_dir(dir) .chain_err(|| "Could not read directory")? @@ -56,7 +50,7 @@ impl DependencyDetector { && entry .file_name() .map(OsStr::to_string_lossy) - .map(|s| self.is_package_file(s.as_ref())) + .map(|s| self.package_managers.contains_key(s.as_ref())) .unwrap_or_default() }) .map(|entry| { From 3d94170377545529a6db0b5c50dfa59c71cca621 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Thu, 5 Nov 2020 12:00:20 -0500 Subject: [PATCH 23/28] add a comment Signed-off-by: Luke-zhang-04 --- src/onefetch/deps/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/onefetch/deps/mod.rs b/src/onefetch/deps/mod.rs index ccc122707..a29d53a94 100644 --- a/src/onefetch/deps/mod.rs +++ b/src/onefetch/deps/mod.rs @@ -60,6 +60,8 @@ impl DependencyDetector { let number_of_deps = parser(&contents)?; let used_package_manager; + // If a yarn.lock file is found and the current package manager + // is NPM, change the package manager to Yarn instead if found_package_manager == &package_manager::PackageManager::Npm && std::path::Path::new(&format!("{}yarn.lock", dir)).exists() { From 88242067d3aa68cbfe4b97c822a7725d71a5b212 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Thu, 5 Nov 2020 12:02:11 -0500 Subject: [PATCH 24/28] make contributing clearer Signed-off-by: Luke-zhang-04 --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 01db5e280..05298d60b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -100,7 +100,7 @@ pub fn cargo(contents: &str) -> Result { package_managers.insert( String::from("Cargo.toml"), // File name - // Parser function, then writeln! macro + // Parser function, then the corresponding element from the PackageManager enum (package_parser::cargo, package_manager::PackageManager::Cargo), ); ``` From 978c9c88e4ac3f1e4e5692d6328807492a8c1979 Mon Sep 17 00:00:00 2001 From: Ossama Hjaji Date: Thu, 5 Nov 2020 22:33:18 +0100 Subject: [PATCH 25/28] Update CONTRIBUTING.md --- CONTRIBUTING.md | 81 +++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 05298d60b..7564b36ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,6 +11,7 @@ information to effectively respond to your bug report or contribution. * [Finding contributions to work on](#finding-contributions-to-work-on) * [Adding support for a new language](#adding-support-for-a-new-language) * [Ascii logo](#ascii-logo) + * [Adding support for a new package manager](#adding-support-for-a-new-package-manager) * [Project-specific notes](#project-specific-notes) ## Reporting Bugs / Feature Requests @@ -61,6 +62,46 @@ Adding support for a new Language requires adding a new entry in the `define_lan The first item `CSharp` corresponds to the name of the language as defined in tokei. The second item `csharp.ascii` is the name of the file containing the ascii logo, this file has to be placed in the _./resources_ folder (more info below). The third item `C#` is the display name. Then we have the colors used to customize the look of the ascii logo when displayed to the screen. The last item `c#` is required only if the Enum name `CSharp` doesn't match the display name `C#`. +#### Ascii logo + +``` +{4} _{1} _ _ +{4} _|_{1}(_|/ \ +{0} o{4}| {1} _|\_/ + +{0} /\ +{0} / \ +{0} | | +{0} |{2}NASA{0}| +{0} | | +{0} | | +{0} | | +{0} ' ` +{0} | | +{0} | | +{0} |______| +{3} '-`'-` . +{3} / . \'\ . .' +{3} ''( .'\.' ' .;' +{3}'.;.;' ;'.;' ..;;' +``` + +Remarks: + - Your ascii logo's dimensions must fall below `25*45` (height\*width). The CI will fail otherwise. + - You can use `{N}` to color the ascii which will utilize the vec! of colors defined in `define_language!` + - Make sure to trim any unnecessary trailing whitespaces + - See example here [Convert image to ASCII art](https://github.com/o2sh/onefetch/wiki/image-to-ascii) + - You must always provide an array of basic colors + - Optionally, you may provide true colors in a second array of colors separated from the first array by a colon + - One last approach allows you to define colors using the Colors structure itself + - Make sure if you use true colors that the number of true colors matches the number of basic colors + - For example, the following are equivalent: +``` + { CSharp, "csharp.ascii", "C#", define_colors!( [Color::Blue, Color::Magenta] ), "c#" }, + { CSharp, "csharp.ascii", "C#", define_colors!( [Color::Blue, Color::Magenta] : [Color::TrueColor{ r:0, g:255, b:255 }, Color::TrueColor{ r:255, g:0, b:255 } ] ), "c#" }, + { CSharp, "csharp.ascii", "C#", define_colors!( Colors { basic_colors: vec![Color::Blue, Color::Magenta] , true_colors: Some(vec![Color::TrueColor{ r:0, g:255, b:255 }, Color::TrueColor{ r:255, g:0, b:255 } ] ) } ), "c#" }, +``` + ### Adding support for a new package manager Any package manager is supported, as long as there is a file you can get the dependencies from. @@ -105,46 +146,6 @@ package_managers.insert( ); ``` -#### Ascii logo - -``` -{4} _{1} _ _ -{4} _|_{1}(_|/ \ -{0} o{4}| {1} _|\_/ - -{0} /\ -{0} / \ -{0} | | -{0} |{2}NASA{0}| -{0} | | -{0} | | -{0} | | -{0} ' ` -{0} | | -{0} | | -{0} |______| -{3} '-`'-` . -{3} / . \'\ . .' -{3} ''( .'\.' ' .;' -{3}'.;.;' ;'.;' ..;;' -``` - -Remarks: - - Your ascii logo's dimensions must fall below `25*45` (height\*width). The CI will fail otherwise. - - You can use `{N}` to color the ascii which will utilize the vec! of colors defined in `define_language!` - - Make sure to trim any unnecessary trailing whitespaces - - See example here [Convert image to ASCII art](https://github.com/o2sh/onefetch/wiki/image-to-ascii) - - You must always provide an array of basic colors - - Optionally, you may provide true colors in a second array of colors separated from the first array by a colon - - One last approach allows you to define colors using the Colors structure itself - - Make sure if you use true colors that the number of true colors matches the number of basic colors - - For example, the following are equivalent: -``` - { CSharp, "csharp.ascii", "C#", define_colors!( [Color::Blue, Color::Magenta] ), "c#" }, - { CSharp, "csharp.ascii", "C#", define_colors!( [Color::Blue, Color::Magenta] : [Color::TrueColor{ r:0, g:255, b:255 }, Color::TrueColor{ r:255, g:0, b:255 } ] ), "c#" }, - { CSharp, "csharp.ascii", "C#", define_colors!( Colors { basic_colors: vec![Color::Blue, Color::Magenta] , true_colors: Some(vec![Color::TrueColor{ r:0, g:255, b:255 }, Color::TrueColor{ r:255, g:0, b:255 } ] ) } ), "c#" }, -``` - ### Project-specific notes - Please ensure your changes are formatted according to `cargo fmt`. From 1d6d95b2d42fffa297a19552c193f7d59220d850 Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Fri, 6 Nov 2020 09:08:34 -0500 Subject: [PATCH 26/28] fix: handle Cargo.toml without dependency field Signed-off-by: Luke-zhang-04 --- src/onefetch/deps/package_parser.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/onefetch/deps/package_parser.rs b/src/onefetch/deps/package_parser.rs index 6715ccc29..6a26f05d1 100644 --- a/src/onefetch/deps/package_parser.rs +++ b/src/onefetch/deps/package_parser.rs @@ -3,8 +3,12 @@ use {regex::Regex, toml::Value}; pub fn cargo(contents: &str) -> Result { let parsed = contents.parse::()?; + let count = parsed.get("dependencies"); - Ok(parsed["dependencies"].as_table().unwrap().len()) + match count { + Some(val) => Ok(val.as_table().unwrap().len()), + None => Ok(0), + } } pub fn go_modules(contents: &str) -> Result { From 26774012f313563bb336f304c50641325871d06b Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Fri, 6 Nov 2020 09:11:22 -0500 Subject: [PATCH 27/28] update CONTRIBUTING.md Signed-off-by: Luke-zhang-04 --- CONTRIBUTING.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7564b36ff..ac4a36cb5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ information to effectively respond to your bug report or contribution. * [Finding contributions to work on](#finding-contributions-to-work-on) * [Adding support for a new language](#adding-support-for-a-new-language) * [Ascii logo](#ascii-logo) - * [Adding support for a new package manager](#adding-support-for-a-new-package-manager) + * [Adding support for a new package manager](#adding-support-for-a-new-package-manager) * [Project-specific notes](#project-specific-notes) ## Reporting Bugs / Feature Requests @@ -127,12 +127,16 @@ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { } ``` -3. in `src/onefetch/deps/package_parser.rs`, add a function whose name corresponds to your manager. This function should take in a `string` as the contents of the package manager file, and return `usize` as the number of dependencies +3. in `src/onefetch/deps/package_parser.rs`, add a function whose name corresponds to your manager. This function should take in a `string` as the contents of the package manager file, and return `usize` as the number of dependencies. You should also make sure you catch any edge cases, such as the absence of a `dependencies` field. ```rust pub fn cargo(contents: &str) -> Result { let parsed = contents.parse::()?; + let count = parsed.get("dependencies"); - Ok(parsed["dependencies"].as_table().unwrap().len()) + match count { + Some(val) => Ok(val.as_table().unwrap().len()), + None => Ok(0), + } } ``` From ba97550c74cd87cff4b86da730ae1137d71e55fc Mon Sep 17 00:00:00 2001 From: Luke-zhang-04 Date: Fri, 6 Nov 2020 10:04:12 -0500 Subject: [PATCH 28/28] fix: check for `=>` in go.mod Signed-off-by: Luke-zhang-04 --- src/onefetch/deps/package_parser.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/onefetch/deps/package_parser.rs b/src/onefetch/deps/package_parser.rs index 6a26f05d1..cd9bc5419 100644 --- a/src/onefetch/deps/package_parser.rs +++ b/src/onefetch/deps/package_parser.rs @@ -12,7 +12,8 @@ pub fn cargo(contents: &str) -> Result { } pub fn go_modules(contents: &str) -> Result { - let count = Regex::new(r"v[0-9]+")?.find_iter(contents).count(); + let count = Regex::new(r"v[0-9]+")?.find_iter(contents).count() + - Regex::new(r"=>")?.find_iter(contents).count(); Ok(count) }