package_parser/pkgs/python/
pyconda.rs1use serde_yaml::from_str;
2use serde_yaml::Value;
3
4use crate::error::SourcePkgError;
5use crate::pkgs::common::model::{Package, PackageManifest};
6
7use crate::pkgs::pyrequirements::PyRequirements;
8
9use std::fs::File;
10use std::io::Read;
11use std::path::Path;
12
13pub struct PyConda {}
14
15impl PyConda {
16 pub fn new() -> Self {
17 Self {}
18 }
19
20 fn convert_to_pure_yaml(content: &str) -> String {
21 let mut newlines = vec![];
22 for line in content.lines() {
23 if line.starts_with('{') {
24 continue;
25 }
26 newlines.push(line);
27 }
28
29 newlines.join("\n")
30 }
31
32 fn parse(path: impl AsRef<Path>) -> Result<Package, SourcePkgError> {
33 let mut file = File::open(path)?;
34 let mut content = String::new();
35 file.read_to_string(&mut content)?;
36 let content = Self::convert_to_pure_yaml(&content);
37 let root: Value = from_str(&content)?;
38 let package_name = &root["package"]["name"].as_str();
39 let package_license = &root["about"]["license"].as_str();
40 let requirements_section = &root["requirements"]["run"].as_sequence().map(|seq| {
41 let mut requirements = vec![];
42 for s in seq {
43 if s.is_string() {
44 requirements.push(s.as_str().unwrap());
45 }
46 }
47
48 requirements.join("\n")
49 });
50
51 let requirements = match requirements_section {
52 Some(requirements) => requirements.to_string(),
53 None => "".to_string(),
54 };
55
56 let requirements =
57 PyRequirements::parse_requirement_content(&requirements).unwrap_or_default();
58
59 let package = Package {
60 name: package_name.unwrap_or("").to_string(),
61 declared_license: package_license.unwrap_or("").to_string(),
62 dependencies: requirements,
63 ..Default::default()
64 };
65
66 Ok(package)
67 }
68}
69
70#[async_trait::async_trait]
71impl PackageManifest for PyConda {
72 fn get_name(&self) -> String {
73 "pypi".to_string()
74 }
75
76 async fn recognize(&self, path: &Path) -> Result<Package, SourcePkgError> {
77 Self::parse(path)
78 }
79
80 fn file_name_patterns(&self) -> &'static [&'static str] {
81 &["conda.yaml", "conda*.yaml"]
82 }
83}
84
85