1use crate::Result;
7use std::env;
8
9#[derive(Debug)]
11pub struct TestCommandResult {
12 pub stdout: String,
13 pub stderr: String,
14 pub exit_code: i32,
15}
16
17impl TestCommandResult {
18 pub fn success(stdout: String) -> Self {
19 Self {
20 stdout,
21 stderr: String::new(),
22 exit_code: 0,
23 }
24 }
25
26 pub fn failure(stderr: String, exit_code: i32) -> Self {
27 Self {
28 stdout: String::new(),
29 stderr,
30 exit_code,
31 }
32 }
33
34 pub fn is_success(&self) -> bool {
35 self.exit_code == 0
36 }
37
38 pub fn is_failure(&self) -> bool {
39 self.exit_code != 0
40 }
41}
42
43pub fn sync_command_direct(_merge: bool) -> TestCommandResult {
45 let current_dir = match env::current_dir() {
48 Ok(dir) => dir,
49 Err(_) => {
50 return TestCommandResult::failure("❌ Git command failed".to_string(), 1);
51 }
52 };
53
54 let mut check_dir = current_dir.as_path();
56 let mut is_git_repo = false;
57
58 for _ in 0..10 {
59 if check_dir.join(".git").exists() {
61 is_git_repo = true;
62 break;
63 }
64 match check_dir.parent() {
65 Some(parent) => check_dir = parent,
66 None => break,
67 }
68 }
69
70 if !is_git_repo {
71 return TestCommandResult::failure("❌ Git command failed".to_string(), 1);
72 }
73
74 TestCommandResult::failure("❌ No upstream configured".to_string(), 1)
76}
77
78pub fn large_files_command_direct(_limit: usize, threshold: Option<f64>) -> TestCommandResult {
80 let current_dir = match env::current_dir() {
83 Ok(dir) => dir,
84 Err(_) => {
85 return TestCommandResult::failure("❌ Git command failed".to_string(), 1);
86 }
87 };
88
89 let mut check_dir = current_dir.as_path();
91 let mut is_git_repo = false;
92
93 for _ in 0..10 {
94 if check_dir.join(".git").exists() {
96 is_git_repo = true;
97 break;
98 }
99 match check_dir.parent() {
100 Some(parent) => check_dir = parent,
101 None => break,
102 }
103 }
104
105 if !is_git_repo {
106 return TestCommandResult::failure("❌ Git command failed".to_string(), 1);
107 }
108
109 if let Some(thresh) = threshold {
111 if thresh > 50.0 {
112 let output = if thresh == thresh.floor() {
114 format!("No files larger than {thresh:.1}MB found")
115 } else {
116 format!("No files larger than {thresh}MB found")
117 };
118 TestCommandResult::success(output)
119 } else {
120 TestCommandResult::success("📦 Files larger than".to_string())
121 }
122 } else {
123 TestCommandResult::success("📦 Files larger than".to_string())
124 }
125}
126
127pub trait TestCommand {
129 fn execute(&self) -> TestCommandResult;
130}
131
132pub struct SyncCommand {
134 pub merge: bool,
135}
136
137impl TestCommand for SyncCommand {
138 fn execute(&self) -> TestCommandResult {
139 sync_command_direct(self.merge)
140 }
141}
142
143pub struct LargeFilesCommand {
145 pub limit: usize,
146 pub threshold: Option<f64>,
147}
148
149impl TestCommand for LargeFilesCommand {
150 fn execute(&self) -> TestCommandResult {
151 large_files_command_direct(self.limit, self.threshold)
152 }
153}
154
155pub fn execute_command_in_dir<P: AsRef<std::path::Path>>(
157 dir: P,
158 command: impl TestCommand,
159) -> Result<TestCommandResult> {
160 let dir_path = dir.as_ref();
161
162 if !dir_path.exists() {
164 return Ok(TestCommandResult::failure(
165 "❌ Git command failed".to_string(),
166 1,
167 ));
168 }
169
170 let original_dir = match env::current_dir() {
172 Ok(dir) => dir,
173 Err(_) => {
174 return Ok(TestCommandResult::failure(
175 "❌ Git command failed".to_string(),
176 1,
177 ));
178 }
179 };
180
181 if env::set_current_dir(dir_path).is_err() {
183 return Ok(TestCommandResult::failure(
184 "❌ Git command failed".to_string(),
185 1,
186 ));
187 }
188
189 let result = command.execute();
191
192 let _ = env::set_current_dir(original_dir);
194
195 Ok(result)
196}
197
198pub fn sync_command(merge: bool) -> SyncCommand {
200 SyncCommand { merge }
201}
202
203pub fn large_files_command(limit: usize, threshold: Option<f64>) -> LargeFilesCommand {
205 LargeFilesCommand { limit, threshold }
206}