dev_prune/adapters/
pipenv.rs1use super::{
13 BloatDir, EnforcePolicy, PackageManager, dir_size, enforce_two_tier, run_command_with_timeout,
14};
15use anyhow::Result;
16use std::path::Path;
17
18pub struct Pipenv;
20
21impl PackageManager for Pipenv {
22 fn name(&self) -> &'static str {
23 "pipenv"
24 }
25
26 fn detect(&self, path: &Path) -> bool {
27 path.join("Pipfile").exists()
28 }
29
30 fn bloat_dirs(&self, path: &Path) -> Vec<BloatDir> {
31 let venv = path.join(".venv");
32 if !venv.is_dir() {
33 return Vec::new();
34 }
35 vec![BloatDir {
36 name: ".venv".to_string(),
37 path: venv.clone(),
38 size_bytes: dir_size(&venv),
39 shared_bytes: 0,
40 }]
41 }
42
43 fn enforce_lockfile(&self, path: &Path, policy: EnforcePolicy) -> Result<()> {
47 enforce_two_tier(
48 &path.join("Pipfile.lock"),
49 "pipenv",
50 &["verify"],
51 &["lock"],
52 path,
53 policy,
54 )
55 }
56
57 fn restore(&self, path: &Path, timeout: std::time::Duration) -> Result<()> {
61 run_command_with_timeout("pipenv", &["install", "--deploy"], path, timeout)
62 }
63
64 fn lockfiles(&self) -> &'static [&'static str] {
65 &["Pipfile.lock"]
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use std::fs;
73 use tempfile::tempdir;
74
75 #[test]
76 fn detects_on_the_pipfile() {
77 let dir = tempdir().unwrap();
78 assert!(!Pipenv.detect(dir.path()));
79 fs::write(dir.path().join("Pipfile"), "[packages]\n").unwrap();
80 assert!(Pipenv.detect(dir.path()));
81 }
82
83 #[test]
84 fn claims_only_an_in_project_environment() {
85 let dir = tempdir().unwrap();
86 fs::write(dir.path().join("Pipfile"), "").unwrap();
87 assert!(Pipenv.bloat_dirs(dir.path()).is_empty());
88 fs::create_dir(dir.path().join(".venv")).unwrap();
89 let dirs = Pipenv.bloat_dirs(dir.path());
90 assert_eq!(dirs.len(), 1);
91 assert_eq!(dirs[0].name, ".venv");
92 }
93}