ralph_workflow/cli/reducer/
apply.rs1use super::state::CliState;
7use crate::config::{Config, ReviewDepth, Verbosity};
8
9pub fn apply_cli_state_to_config(cli_state: &CliState, config: &mut Config) {
23 if cli_state.debug_mode {
26 config.verbosity = Verbosity::Debug;
27 } else if cli_state.full_mode {
28 config.verbosity = Verbosity::Full;
29 } else if cli_state.quiet_mode {
30 config.verbosity = Verbosity::Quiet;
31 } else if let Some(level) = cli_state.verbosity {
32 config.verbosity = Verbosity::from(level);
33 }
34
35 let current_developer_iters = config.developer_iters;
38 let current_reviewer_reviews = config.reviewer_reviews;
39
40 config.developer_iters = cli_state.resolved_developer_iters(current_developer_iters);
41 config.reviewer_reviews = cli_state.resolved_reviewer_reviews(current_reviewer_reviews);
42
43 if let Some(ref agent) = cli_state.developer_agent {
45 config.developer_agent = Some(agent.clone());
46 }
47 if let Some(ref agent) = cli_state.reviewer_agent {
48 config.reviewer_agent = Some(agent.clone());
49 }
50
51 if let Some(ref model) = cli_state.developer_model {
53 config.developer_model = Some(model.clone());
54 }
55 if let Some(ref model) = cli_state.reviewer_model {
56 config.reviewer_model = Some(model.clone());
57 }
58 if let Some(ref provider) = cli_state.developer_provider {
59 config.developer_provider = Some(provider.clone());
60 }
61 if let Some(ref provider) = cli_state.reviewer_provider {
62 config.reviewer_provider = Some(provider.clone());
63 }
64 if let Some(ref parser) = cli_state.reviewer_json_parser {
65 config.reviewer_json_parser = Some(parser.clone());
66 }
67
68 if let Some(isolation_mode) = cli_state.isolation_mode {
71 config.isolation_mode = isolation_mode;
72 }
73
74 if let Some(ref depth) = cli_state.review_depth {
76 if let Some(parsed) = ReviewDepth::from_str(depth) {
77 config.review_depth = parsed;
78 }
79 }
81
82 if let Some(ref name) = cli_state.git_user_name {
84 config.git_user_name = Some(name.clone());
85 }
86 if let Some(ref email) = cli_state.git_user_email {
87 config.git_user_email = Some(email.clone());
88 }
89
90 if cli_state.streaming_metrics {
92 config.show_streaming_metrics = true;
93 }
94
95 if let Some(ref preset) = cli_state.agent_preset {
98 match preset.as_str() {
99 "default" => {
100 }
102 "opencode" => {
103 config.developer_agent = Some("opencode".to_string());
104 config.reviewer_agent = Some("opencode".to_string());
105 }
106 _ => {
107 }
109 }
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116 use crate::config::types::{BehavioralFlags, FeatureFlags};
117
118 fn create_test_config() -> Config {
119 Config {
120 developer_agent: None,
121 reviewer_agent: None,
122 developer_cmd: None,
123 reviewer_cmd: None,
124 commit_cmd: None,
125 developer_model: None,
126 reviewer_model: None,
127 developer_provider: None,
128 reviewer_provider: None,
129 reviewer_json_parser: None,
130 features: FeatureFlags {
131 checkpoint_enabled: true,
132 force_universal_prompt: false,
133 },
134 developer_iters: 5,
135 reviewer_reviews: 2,
136 fast_check_cmd: None,
137 full_check_cmd: None,
138 behavior: BehavioralFlags {
139 interactive: true,
140 auto_detect_stack: true,
141 strict_validation: false,
142 },
143 prompt_path: std::path::PathBuf::from(".agent/last_prompt.txt"),
144 user_templates_dir: None,
145 developer_context: 1,
146 reviewer_context: 0,
147 verbosity: Verbosity::Verbose,
148 review_depth: ReviewDepth::Standard,
149 isolation_mode: true,
150 git_user_name: None,
151 git_user_email: None,
152 show_streaming_metrics: false,
153 review_format_retries: 5,
154 max_dev_continuations: Some(2),
155 max_xsd_retries: Some(10),
156 max_same_agent_retries: Some(2),
157 }
158 }
159
160 #[test]
161 fn test_apply_verbosity_debug() {
162 let cli_state = CliState {
163 debug_mode: true,
164 ..Default::default()
165 };
166
167 let mut config = create_test_config();
168 apply_cli_state_to_config(&cli_state, &mut config);
169
170 assert_eq!(config.verbosity, Verbosity::Debug);
171 }
172
173 #[test]
174 fn test_apply_verbosity_full() {
175 let cli_state = CliState {
176 full_mode: true,
177 ..Default::default()
178 };
179
180 let mut config = create_test_config();
181 apply_cli_state_to_config(&cli_state, &mut config);
182
183 assert_eq!(config.verbosity, Verbosity::Full);
184 }
185
186 #[test]
187 fn test_apply_verbosity_quiet() {
188 let cli_state = CliState {
189 quiet_mode: true,
190 ..Default::default()
191 };
192
193 let mut config = create_test_config();
194 apply_cli_state_to_config(&cli_state, &mut config);
195
196 assert_eq!(config.verbosity, Verbosity::Quiet);
197 }
198
199 #[test]
200 fn test_apply_verbosity_explicit() {
201 let cli_state = CliState {
202 verbosity: Some(3),
203 ..Default::default()
204 };
205
206 let mut config = create_test_config();
207 apply_cli_state_to_config(&cli_state, &mut config);
208
209 assert_eq!(config.verbosity, Verbosity::Full); }
211
212 #[test]
213 fn test_apply_iters_from_preset() {
214 use super::super::state::PresetType;
215
216 let cli_state = CliState {
217 preset_applied: Some(PresetType::Long),
218 ..Default::default()
219 };
220
221 let mut config = create_test_config();
222 config.developer_iters = 5;
223 config.reviewer_reviews = 2;
224
225 apply_cli_state_to_config(&cli_state, &mut config);
226
227 assert_eq!(config.developer_iters, 15);
228 assert_eq!(config.reviewer_reviews, 10);
229 }
230
231 #[test]
232 fn test_apply_iters_explicit_override_preset() {
233 use super::super::state::PresetType;
234
235 let cli_state = CliState {
236 preset_applied: Some(PresetType::Quick), developer_iters: Some(7), reviewer_reviews: Some(3), ..Default::default()
240 };
241
242 let mut config = create_test_config();
243 apply_cli_state_to_config(&cli_state, &mut config);
244
245 assert_eq!(config.developer_iters, 7);
247 assert_eq!(config.reviewer_reviews, 3);
248 }
249
250 #[test]
251 fn test_apply_developer_agent() {
252 let cli_state = CliState {
253 developer_agent: Some("claude".to_string()),
254 ..Default::default()
255 };
256
257 let mut config = create_test_config();
258 apply_cli_state_to_config(&cli_state, &mut config);
259
260 assert_eq!(config.developer_agent, Some("claude".to_string()));
261 }
262
263 #[test]
264 fn test_apply_reviewer_agent() {
265 let cli_state = CliState {
266 reviewer_agent: Some("gpt".to_string()),
267 ..Default::default()
268 };
269
270 let mut config = create_test_config();
271 apply_cli_state_to_config(&cli_state, &mut config);
272
273 assert_eq!(config.reviewer_agent, Some("gpt".to_string()));
274 }
275
276 #[test]
277 fn test_apply_isolation_mode_disabled() {
278 let cli_state = CliState {
279 isolation_mode: Some(false),
280 ..Default::default()
281 };
282
283 let mut config = create_test_config();
284 config.isolation_mode = true;
285
286 apply_cli_state_to_config(&cli_state, &mut config);
287
288 assert!(!config.isolation_mode);
289 }
290
291 #[test]
292 fn test_apply_review_depth() {
293 let cli_state = CliState {
294 review_depth: Some("comprehensive".to_string()),
295 ..Default::default()
296 };
297
298 let mut config = create_test_config();
299 apply_cli_state_to_config(&cli_state, &mut config);
300
301 assert_eq!(config.review_depth, ReviewDepth::Comprehensive);
302 }
303
304 #[test]
305 fn test_apply_git_identity() {
306 let cli_state = CliState {
307 git_user_name: Some("John Doe".to_string()),
308 git_user_email: Some("john@example.com".to_string()),
309 ..Default::default()
310 };
311
312 let mut config = create_test_config();
313 apply_cli_state_to_config(&cli_state, &mut config);
314
315 assert_eq!(config.git_user_name, Some("John Doe".to_string()));
316 assert_eq!(config.git_user_email, Some("john@example.com".to_string()));
317 }
318
319 #[test]
320 fn test_apply_streaming_metrics() {
321 let cli_state = CliState {
322 streaming_metrics: true,
323 ..Default::default()
324 };
325
326 let mut config = create_test_config();
327 apply_cli_state_to_config(&cli_state, &mut config);
328
329 assert!(config.show_streaming_metrics);
330 }
331
332 #[test]
333 fn test_apply_agent_preset_opencode() {
334 let cli_state = CliState {
335 agent_preset: Some("opencode".to_string()),
336 ..Default::default()
337 };
338
339 let mut config = create_test_config();
340 apply_cli_state_to_config(&cli_state, &mut config);
341
342 assert_eq!(config.developer_agent, Some("opencode".to_string()));
343 assert_eq!(config.reviewer_agent, Some("opencode".to_string()));
344 }
345
346 #[test]
347 fn test_apply_agent_preset_default() {
348 let cli_state = CliState {
349 agent_preset: Some("default".to_string()),
350 ..Default::default()
351 };
352
353 let mut config = create_test_config();
354 config.developer_agent = Some("existing-dev".to_string());
355 config.reviewer_agent = Some("existing-rev".to_string());
356
357 apply_cli_state_to_config(&cli_state, &mut config);
358
359 assert_eq!(config.developer_agent, Some("existing-dev".to_string()));
361 assert_eq!(config.reviewer_agent, Some("existing-rev".to_string()));
362 }
363
364 #[test]
365 fn test_apply_preserves_unrelated_config_fields() {
366 let cli_state = CliState {
367 developer_agent: Some("new-agent".to_string()),
368 ..Default::default()
369 };
370
371 let mut config = create_test_config();
372 config.isolation_mode = true;
373 config.review_depth = ReviewDepth::Comprehensive;
374
375 apply_cli_state_to_config(&cli_state, &mut config);
376
377 assert_eq!(config.developer_agent, Some("new-agent".to_string()));
379 assert!(config.isolation_mode);
380 assert_eq!(config.review_depth, ReviewDepth::Comprehensive);
381 }
382}