dev_prune/adapters/
maven.rs1use super::{BloatDir, EnforcePolicy, PackageManager, dir_size};
19use anyhow::{Result, anyhow};
20use std::fs;
21use std::path::Path;
22
23pub struct Maven;
25
26impl PackageManager for Maven {
27 fn name(&self) -> &'static str {
28 "maven"
29 }
30
31 fn detect(&self, path: &Path) -> bool {
32 path.join("pom.xml").exists()
33 }
34
35 fn bloat_dirs(&self, path: &Path) -> Vec<BloatDir> {
36 let mut dirs = Vec::new();
37 let target = path.join("target");
38 if target.exists() {
39 dirs.push(BloatDir {
40 name: "target".to_string(),
41 path: target.clone(),
42 size_bytes: dir_size(&target),
43 shared_bytes: 0,
44 });
45 }
46 dirs
47 }
48
49 fn enforce_lockfile(&self, path: &Path, _policy: EnforcePolicy) -> Result<()> {
54 let pom = path.join("pom.xml");
55 let content = fs::read_to_string(&pom).map_err(|e| {
56 anyhow!("`pom.xml` could not be read ({e}) — nothing to rebuild `target/` from.")
57 })?;
58 if !content.contains("<project") {
59 return Err(anyhow!(
60 "`pom.xml` does not look like a Maven manifest (no `<project` element) — \
61 refusing to treat `target/` as rebuildable from it."
62 ));
63 }
64 Ok(())
65 }
66
67 fn restore(&self, _path: &Path, _timeout: std::time::Duration) -> Result<()> {
68 println!("Maven target/ will regenerate on the next `mvn package` (or `mvn compile`)");
69 Ok(())
70 }
71
72 fn lockfiles(&self) -> &'static [&'static str] {
73 &["pom.xml"]
74 }
75
76 fn opt_in(&self) -> bool {
77 true
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84 use tempfile::tempdir;
85
86 #[test]
87 fn detects_on_pom_xml_only() {
88 let dir = tempdir().unwrap();
89 assert!(!Maven.detect(dir.path()));
90 fs::write(dir.path().join("pom.xml"), "<project/>").unwrap();
91 assert!(Maven.detect(dir.path()));
92 }
93
94 #[test]
95 fn claims_target_when_present() {
96 let dir = tempdir().unwrap();
97 assert!(Maven.bloat_dirs(dir.path()).is_empty());
98 fs::create_dir(dir.path().join("target")).unwrap();
99 let dirs = Maven.bloat_dirs(dir.path());
100 assert_eq!(dirs.len(), 1);
101 assert_eq!(dirs[0].name, "target");
102 }
103
104 #[test]
105 fn a_missing_or_bogus_manifest_is_refused() {
106 let dir = tempdir().unwrap();
107 assert!(
108 Maven
109 .enforce_lockfile(dir.path(), EnforcePolicy::default())
110 .is_err()
111 );
112 fs::write(dir.path().join("pom.xml"), "not xml at all").unwrap();
113 assert!(
114 Maven
115 .enforce_lockfile(dir.path(), EnforcePolicy::default())
116 .is_err()
117 );
118 fs::write(dir.path().join("pom.xml"), "<project></project>").unwrap();
119 assert!(
120 Maven
121 .enforce_lockfile(dir.path(), EnforcePolicy::default())
122 .is_ok()
123 );
124 }
125
126 #[test]
127 fn maven_is_opt_in() {
128 assert!(Maven.opt_in());
129 }
130}