dev_prune/adapters/
bundler.rs1use super::{
17 BloatDir, EnforcePolicy, PackageManager, dir_size, enforce_two_tier, run_command_with_timeout,
18};
19use anyhow::Result;
20use std::path::{Path, PathBuf};
21
22pub struct Bundler;
24
25fn vendor_bundle(path: &Path) -> PathBuf {
27 path.join("vendor").join("bundle")
28}
29
30impl PackageManager for Bundler {
31 fn name(&self) -> &'static str {
32 "bundler"
33 }
34
35 fn detect(&self, path: &Path) -> bool {
36 path.join("Gemfile").exists()
37 }
38
39 fn bloat_dirs(&self, path: &Path) -> Vec<BloatDir> {
40 let bundle = vendor_bundle(path);
41 if !bundle.is_dir() {
42 return Vec::new();
43 }
44 vec![BloatDir {
45 name: "vendor/bundle".to_string(),
46 path: bundle.clone(),
47 size_bytes: dir_size(&bundle),
48 shared_bytes: 0,
49 }]
50 }
51
52 fn enforce_lockfile(&self, path: &Path, policy: EnforcePolicy) -> Result<()> {
58 enforce_two_tier(
59 &path.join("Gemfile.lock"),
60 "bundle",
61 &["lock", "--check"],
62 &["lock"],
63 path,
64 policy,
65 )
66 }
67
68 fn restore(&self, path: &Path, timeout: std::time::Duration) -> Result<()> {
69 run_command_with_timeout("bundle", &["install"], path, timeout)
70 }
71
72 fn lockfiles(&self) -> &'static [&'static str] {
73 &["Gemfile.lock"]
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use std::fs;
81 use tempfile::tempdir;
82
83 #[test]
84 fn detects_on_the_gemfile() {
85 let dir = tempdir().unwrap();
86 assert!(!Bundler.detect(dir.path()));
87 fs::write(dir.path().join("Gemfile"), "source :rubygems").unwrap();
88 assert!(Bundler.detect(dir.path()));
89 }
90
91 #[test]
92 fn claims_only_a_vendored_bundle() {
93 let dir = tempdir().unwrap();
94 fs::write(dir.path().join("Gemfile"), "").unwrap();
95 assert!(Bundler.bloat_dirs(dir.path()).is_empty());
96 fs::create_dir_all(vendor_bundle(dir.path())).unwrap();
97 let dirs = Bundler.bloat_dirs(dir.path());
98 assert_eq!(dirs.len(), 1);
99 assert_eq!(dirs[0].name, "vendor/bundle");
100 }
101
102 #[test]
103 fn never_claims_the_bundle_config_directory() {
104 let dir = tempdir().unwrap();
105 fs::create_dir(dir.path().join(".bundle")).unwrap();
106 assert!(Bundler.bloat_dirs(dir.path()).is_empty());
107 }
108}