1use super::{BloatDir, EnforcePolicy, PackageManager, dir_size, enforce_two_tier, run_command};
7use anyhow::Result;
8use std::path::Path;
9
10pub struct Go;
12
13impl PackageManager for Go {
14 fn name(&self) -> &'static str {
15 "go"
16 }
17
18 fn detect(&self, path: &Path) -> bool {
19 path.join("go.mod").exists()
20 }
21
22 fn bloat_dirs(&self, path: &Path) -> Vec<BloatDir> {
23 let mut dirs = Vec::new();
24 let vendor_path = path.join("vendor");
25 if vendor_path.exists() {
26 dirs.push(BloatDir {
27 name: "vendor".to_string(),
28 path: vendor_path.clone(),
29 size_bytes: dir_size(&vendor_path),
30 });
31 }
32 dirs
33 }
34
35 fn enforce_lockfile(&self, path: &Path, policy: EnforcePolicy) -> Result<()> {
41 enforce_two_tier(
42 &path.join("go.sum"),
43 "go",
44 &["mod", "download"],
45 &["mod", "tidy"],
46 path,
47 policy,
48 )
49 }
50
51 fn restore(&self, path: &Path) -> Result<()> {
52 if path.join("vendor").exists() {
53 run_command("go", &["mod", "vendor"], path)
54 } else {
55 run_command("go", &["mod", "download"], path)
56 }
57 }
58
59 fn lockfiles(&self) -> &'static [&'static str] {
60 &["go.sum"]
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67 use std::fs;
68 use std::fs::File;
69 use tempfile::tempdir;
70
71 #[test]
72 fn test_name() {
73 let adapter = Go;
74 assert_eq!(adapter.name(), "go");
75 }
76
77 #[test]
78 fn test_detect_positive() {
79 let dir = tempdir().unwrap();
80 File::create(dir.path().join("go.mod")).unwrap();
81
82 let adapter = Go;
83 assert!(adapter.detect(dir.path()));
84 }
85
86 #[test]
87 fn test_detect_negative() {
88 let dir = tempdir().unwrap();
89
90 let adapter = Go;
91 assert!(!adapter.detect(dir.path()));
92 }
93
94 #[test]
95 fn test_bloat_dirs_present() {
96 let dir = tempdir().unwrap();
97 fs::create_dir(dir.path().join("vendor")).unwrap();
98
99 let adapter = Go;
100 let dirs = adapter.bloat_dirs(dir.path());
101 assert_eq!(dirs.len(), 1);
102 assert_eq!(dirs[0].name, "vendor");
103 }
104
105 #[test]
106 fn test_bloat_dirs_absent() {
107 let dir = tempdir().unwrap();
108
109 let adapter = Go;
110 let dirs = adapter.bloat_dirs(dir.path());
111 assert!(dirs.is_empty());
112 }
113}