1use super::Command;
2use crate::context::AppContext;
3use crate::task_manager::TaskManager;
4use async_trait::async_trait;
5use std::error::Error;
6
7pub struct TasksCommand {
8 pub delete: Option<String>,
9 pub clean: bool,
10 pub retry: Option<String>,
11 pub edit: bool,
12}
13
14#[async_trait]
15impl Command for TasksCommand {
16 async fn execute(&self, ctx: &AppContext) -> Result<(), Box<dyn Error>> {
17 if self.delete.is_none() && !self.clean && self.retry.is_none() {
19 return Err(
20 "Please specify either --delete <TASK_ID>, --clean, or --retry <TASK_ID>".into(),
21 );
22 }
23
24 let task_manager = TaskManager::with_storage(ctx)?;
25
26 if let Some(ref task_id) = self.delete {
28 println!("Deleting task: {task_id}");
29 task_manager.delete_task(task_id).await?;
30 println!("Task '{task_id}' deleted successfully");
31 }
32
33 if self.clean {
35 println!("Cleaning completed tasks...");
36 let completed_count = task_manager.clean_tasks().await?;
37 println!("Cleanup complete: {completed_count} completed task(s) deleted");
38 }
39
40 if let Some(ref task_id) = self.retry {
42 println!("Retrying task: {task_id}");
43 let new_task_id = task_manager.retry_task(task_id, self.edit, ctx).await?;
44 println!("Task retried successfully. New task ID: {new_task_id}");
45 }
46
47 Ok(())
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54 use crate::test_utils::{NoOpDockerClient, NoOpTskClient};
55 use std::sync::Arc;
56
57 fn create_test_context() -> AppContext {
58 AppContext::builder()
59 .with_docker_client(Arc::new(NoOpDockerClient))
60 .with_tsk_client(Arc::new(NoOpTskClient))
61 .build()
62 }
63
64 #[tokio::test]
65 async fn test_tasks_command_validation_no_options() {
66 let cmd = TasksCommand {
67 delete: None,
68 clean: false,
69 retry: None,
70 edit: false,
71 };
72
73 let ctx = create_test_context();
74 let result = cmd.execute(&ctx).await;
75 assert!(result.is_err());
76 assert!(
77 result
78 .unwrap_err()
79 .to_string()
80 .contains("Please specify either --delete")
81 );
82 }
83}