add support for multiple parsers per package manager
@@ -3,19 +3,19 @@ use std::collections::HashMap;
use {regex::Regex, strum::EnumIter, toml::Value, yaml_rust::YamlLoader};
macro_rules! define_package_managers {
- ($( { $name:ident, $display:literal, $file:literal, $parser:expr } ),* ,) => {
+ ($( { $name:ident, $display:literal, [$(($file:literal, $parser:expr))+] } ),+ ,) => {
#[derive(PartialEq, EnumIter)]
pub enum PackageManager {
$(
$name ,
- )*
+ )+
}
impl std::fmt::Display for PackageManager {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
- $( PackageManager::$name => write!(f, $display), )*
+ $( PackageManager::$name => write!(f, $display), )+
}
}
}
@@ -26,7 +26,11 @@ macro_rules! define_package_managers {
(fn(&str) -> Result<usize>, PackageManager)
> = HashMap::new();
- $( package_managers.insert(String::from($file), ($parser, PackageManager::$name)); )*
+ $(
+ $(
+ package_managers.insert(String::from($file), ($parser, PackageManager::$name));
+ )+
+ )+
package_managers
}
@@ -35,11 +39,11 @@ macro_rules! define_package_managers {
}
define_package_managers! {
- { Cargo, "cargo", "Cargo.toml", cargo },
- { GoModules, "go modules", "go.mod", go_modules },
- { Npm, "npm", "package.json", npm },
- { Pip, "pip", "requirements.txt", pip },
- { Pub, "pub", "pubspec.yaml", pub_packages },
+ { Cargo, "cargo", [ ("Cargo.toml", cargo) ] },
+ { GoModules, "go modules", [ ("go.mod", go_modules) ] },
+ { Npm, "npm", [ ("package.json", npm) ] },
+ { Pip, "pip", [ ("requirements.txt", pip_requirement) ("pyproject.toml", pip_pyproject) ("Pipfile", pip_pipfile) ] },
+ { Pub, "pub", [ ("pubspec.yaml", pub_packages) ] },
}
fn cargo(contents: &str) -> Result<usize> {
@@ -79,12 +83,34 @@ fn npm(contents: &str) -> Result<usize> {
Ok(parsed["dependencies"].len())
}
-fn pip(contents: &str) -> Result<usize> {
+fn pip_requirement(contents: &str) -> Result<usize> {
let count = Regex::new(r"(^|\n)[A-z]+")?.find_iter(contents).count();
Ok(count)
}
+fn pip_pyproject(contents: &str) -> Result<usize> {
+ let parsed = contents.parse::<Value>()?;
+ let count = parsed
+ .get("tool")
+ .and_then(|tool| tool.get("poetry"))
+ .and_then(|poetry| poetry.get("dependencies"));
+ match count {
+ Some(val) => Ok(val.as_table().unwrap().len()),
+ None => Ok(0),
+ }
+}
+
+fn pip_pipfile(contents: &str) -> Result<usize> {
+ let parsed = contents.parse::<Value>()?;
+ let count = parsed.get("packages");
+
+ match count {
+ Some(val) => Ok(val.as_table().unwrap().len()),
+ None => Ok(0),
+ }
+}
+
fn pub_packages(contents: &str) -> Result<usize> {
match YamlLoader::load_from_str(contents) {
Ok(parsed) => match &parsed[0]["dependencies"].as_hash() {
