cleanlib_client/
ecosystem_detect.rs1pub fn ecosystem_from_path(path: &str) -> Option<&'static str> {
23 let name = path.rsplit(['/', '\\']).next().unwrap_or(path);
24
25 let eco = match name {
27 "package.json" | "package-lock.json" | "npm-shrinkwrap.json" | "yarn.lock"
28 | "pnpm-lock.yaml" => "npm",
29 "requirements.txt" | "Pipfile" | "Pipfile.lock" | "pyproject.toml" | "poetry.lock"
30 | "setup.py" => "pypi",
31 "Cargo.toml" | "Cargo.lock" => "crates",
32 "go.mod" | "go.sum" => "go",
33 "pom.xml" | "build.gradle" | "build.gradle.kts" => "maven",
34 "composer.json" | "composer.lock" => "packagist",
35 "Gemfile" | "Gemfile.lock" => "rubygems",
36 "packages.config" => "nuget",
37 "pubspec.yaml" | "pubspec.lock" => "pub",
38 _ => "",
39 };
40 if !eco.is_empty() {
41 return Some(eco);
42 }
43
44 if name.starts_with("requirements-") && name.ends_with(".txt") {
48 return Some("pypi");
49 }
50 if name.ends_with(".csproj") {
51 return Some("nuget");
52 }
53
54 None
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn canonical_manifests_map_to_their_ecosystem() {
63 let cases = [
64 ("package.json", "npm"),
65 ("package-lock.json", "npm"),
66 ("yarn.lock", "npm"),
67 ("pnpm-lock.yaml", "npm"),
68 ("requirements.txt", "pypi"),
69 ("pyproject.toml", "pypi"),
70 ("Pipfile", "pypi"),
71 ("poetry.lock", "pypi"),
72 ("Cargo.toml", "crates"),
73 ("Cargo.lock", "crates"),
74 ("go.mod", "go"),
75 ("go.sum", "go"),
76 ("pom.xml", "maven"),
77 ("build.gradle", "maven"),
78 ("build.gradle.kts", "maven"),
79 ("composer.json", "packagist"),
80 ("Gemfile", "rubygems"),
81 ("Gemfile.lock", "rubygems"),
82 ("packages.config", "nuget"),
83 ("pubspec.yaml", "pub"),
84 ];
85 for (file, eco) in cases {
86 assert_eq!(ecosystem_from_path(file), Some(eco), "{file}");
87 }
88 }
89
90 #[test]
91 fn inspects_only_the_basename_of_a_full_path() {
92 assert_eq!(ecosystem_from_path("/home/dev/proj/package.json"), Some("npm"));
93 assert_eq!(ecosystem_from_path("./sub/dir/Cargo.toml"), Some("crates"));
94 assert_eq!(ecosystem_from_path(r"C:\proj\go.mod"), Some("go"));
96 }
97
98 #[test]
99 fn patterned_names_are_detected() {
100 assert_eq!(ecosystem_from_path("requirements-dev.txt"), Some("pypi"));
101 assert_eq!(ecosystem_from_path("requirements-test.txt"), Some("pypi"));
102 assert_eq!(ecosystem_from_path("MyApp.csproj"), Some("nuget"));
103 }
104
105 #[test]
106 fn unrecognised_or_ambiguous_returns_none() {
107 assert_eq!(ecosystem_from_path("deps.txt"), None);
110 assert_eq!(ecosystem_from_path("README.md"), None);
111 assert_eq!(ecosystem_from_path("manifest"), None);
112 assert_eq!(ecosystem_from_path(""), None);
113 }
114}