dev_prune/adapters/
gradle.rs1use super::{BloatDir, EnforcePolicy, PackageManager, dir_size};
18use anyhow::{Result, anyhow};
19use std::path::Path;
20
21const GRADLE_MANIFESTS: [&str; 4] = [
23 "build.gradle",
24 "build.gradle.kts",
25 "settings.gradle",
26 "settings.gradle.kts",
27];
28
29pub struct Gradle;
31
32fn has_manifest(path: &Path) -> bool {
33 GRADLE_MANIFESTS.iter().any(|m| path.join(m).exists())
34}
35
36impl PackageManager for Gradle {
37 fn name(&self) -> &'static str {
38 "gradle"
39 }
40
41 fn detect(&self, path: &Path) -> bool {
42 has_manifest(path)
43 }
44
45 fn bloat_dirs(&self, path: &Path) -> Vec<BloatDir> {
46 let mut dirs = Vec::new();
47 for name in ["build", ".gradle"] {
48 let dir = path.join(name);
49 if dir.is_dir() {
50 dirs.push(BloatDir {
51 name: name.to_string(),
52 path: dir.clone(),
53 size_bytes: dir_size(&dir),
54 shared_bytes: 0,
55 });
56 }
57 }
58 dirs
59 }
60
61 fn enforce_lockfile(&self, path: &Path, _policy: EnforcePolicy) -> Result<()> {
65 if !has_manifest(path) {
66 return Err(anyhow!(
67 "no Gradle manifest (build.gradle[.kts] / settings.gradle[.kts]) — \
68 nothing to rebuild `build/` from."
69 ));
70 }
71 Ok(())
72 }
73
74 fn restore(&self, path: &Path, _timeout: std::time::Duration) -> Result<()> {
75 let wrapper = if cfg!(windows) {
76 "gradlew.bat"
77 } else {
78 "gradlew"
79 };
80 let cmd = if path.join(wrapper).exists() {
81 "./gradlew build"
82 } else {
83 "gradle build"
84 };
85 println!("Gradle build/ will regenerate on the next `{cmd}`");
86 Ok(())
87 }
88
89 fn opt_in(&self) -> bool {
90 true
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97 use std::fs;
98 use tempfile::tempdir;
99
100 #[test]
101 fn detects_on_any_gradle_manifest() {
102 let dir = tempdir().unwrap();
103 assert!(!Gradle.detect(dir.path()));
104 fs::write(dir.path().join("build.gradle.kts"), "").unwrap();
105 assert!(Gradle.detect(dir.path()));
106 }
107
108 #[test]
109 fn claims_build_and_project_local_gradle_dir() {
110 let dir = tempdir().unwrap();
111 fs::create_dir(dir.path().join("build")).unwrap();
112 fs::create_dir(dir.path().join(".gradle")).unwrap();
113 let names: Vec<String> = Gradle
114 .bloat_dirs(dir.path())
115 .into_iter()
116 .map(|b| b.name)
117 .collect();
118 assert_eq!(names, vec!["build", ".gradle"]);
119 }
120
121 #[test]
122 fn a_vanished_manifest_is_refused() {
123 let dir = tempdir().unwrap();
124 assert!(
125 Gradle
126 .enforce_lockfile(dir.path(), EnforcePolicy::default())
127 .is_err()
128 );
129 fs::write(dir.path().join("settings.gradle"), "").unwrap();
130 assert!(
131 Gradle
132 .enforce_lockfile(dir.path(), EnforcePolicy::default())
133 .is_ok()
134 );
135 }
136
137 #[test]
138 fn gradle_is_opt_in() {
139 assert!(Gradle.opt_in());
140 }
141}