dev_prune/adapters/
pnpm.rs1use super::{BloatDir, EnforcePolicy, PackageManager, dir_size, enforce_two_tier, run_command};
7use anyhow::Result;
8use std::path::Path;
9
10pub struct Pnpm;
12
13impl PackageManager for Pnpm {
14 fn name(&self) -> &'static str {
16 "pnpm"
17 }
18
19 fn detect(&self, project_dir: &Path) -> bool {
21 project_dir.join("pnpm-lock.yaml").exists()
22 }
23
24 fn bloat_dirs(&self, project_dir: &Path) -> Vec<BloatDir> {
26 let node_modules = project_dir.join("node_modules");
27 if node_modules.exists() {
28 let size = dir_size(&node_modules);
29 vec![BloatDir {
30 name: "node_modules".to_string(),
31 path: node_modules,
32 size_bytes: size,
33 }]
34 } else {
35 vec![]
36 }
37 }
38
39 fn enforce_lockfile(&self, project_dir: &Path, policy: EnforcePolicy) -> Result<()> {
47 let lockfile = project_dir.join("pnpm-lock.yaml");
48 enforce_two_tier(
49 &lockfile,
50 "pnpm",
51 &["install", "--lockfile-only", "--frozen-lockfile"],
52 &["install", "--lockfile-only"],
53 project_dir,
54 policy,
55 )
56 }
57
58 fn restore(&self, project_dir: &Path) -> Result<()> {
60 run_command("pnpm", &["install", "--frozen-lockfile"], project_dir)
61 }
62
63 fn lockfiles(&self) -> &'static [&'static str] {
64 &["pnpm-lock.yaml"]
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use std::fs;
72 use tempfile::tempdir;
73
74 #[test]
75 fn test_name() {
76 assert_eq!(Pnpm.name(), "pnpm");
77 }
78
79 #[test]
80 fn test_detect_positive() {
81 let dir = tempdir().unwrap();
82 fs::File::create(dir.path().join("pnpm-lock.yaml")).unwrap();
83 assert!(Pnpm.detect(dir.path()));
84 }
85
86 #[test]
87 fn test_detect_negative() {
88 let dir = tempdir().unwrap();
89 assert!(!Pnpm.detect(dir.path()));
90 }
91
92 #[test]
93 fn test_bloat_dirs_present() {
94 let dir = tempdir().unwrap();
95 fs::create_dir(dir.path().join("node_modules")).unwrap();
96 let bloat = Pnpm.bloat_dirs(dir.path());
97 assert_eq!(bloat.len(), 1);
98 assert_eq!(bloat[0].path, dir.path().join("node_modules"));
99 }
100
101 #[test]
102 fn test_bloat_dirs_absent() {
103 let dir = tempdir().unwrap();
104 let bloat = Pnpm.bloat_dirs(dir.path());
105 assert!(bloat.is_empty());
106 }
107}