package_parser/pkgs/dart/
pubspec_lock.rs1use maplit::hashset;
2use packageurl::PackageUrl;
3use crate::types::{DependentPackage, Relation};
4use serde::Deserialize;
5
6use crate::error::SourcePkgError;
7use crate::pkgs::common::model::Package;
8
9use std::collections::HashMap;
10use std::fs::File;
11use std::path::Path;
12
13#[derive(Debug, Deserialize)]
14struct LockPackage {
15 dependency: String,
16 version: String,
17}
18
19#[derive(Debug, Deserialize)]
20struct PubspecLock {
21 #[serde(default)]
22 packages: HashMap<String, LockPackage>,
23}
24
25pub fn parse(path: impl AsRef<Path>) -> Result<Package, SourcePkgError> {
26 let mut file = File::open(path)?;
27
28 let lock: PubspecLock = serde_yaml::from_reader(&mut file)?;
29
30 let mut dependencies = vec![];
31
32 for (name, package) in lock.packages {
33 dependencies.push(DependentPackage {
34 purl: PackageUrl::new("pub", name)
35 .unwrap()
36 .with_version(&package.version)
37 .to_string(),
38 requirement: package.version,
39 scope: package.dependency.strip_prefix("direct ").unwrap_or_default()
40 .into(),
41 is_runtime: package.dependency != "direct dev",
42 is_optional: false,
43 is_resolved: true,
44 relation: if package.dependency.starts_with("direct") {
45 hashset! {Relation::Direct}
46 } else {
47 hashset! {Relation::Indirect}
48 },
49 ..Default::default()
50 });
51 }
52
53 let package = Package {
54 dependencies,
55 ..Default::default()
56 };
57
58 Ok(package)
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn test_parse_pubspec_lock() {
67 let filepath = Path::new(concat!(
68 env!("CARGO_MANIFEST_DIR"),
69 "/testdata/pubspec/locks/stock-pubspec.lock"
70 ));
71
72 let p = parse(filepath).unwrap();
73 println!("{:?}", p);
74 }
75}