tsk/commands/
tasks.rs

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        // Ensure at least one option is provided
18        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        // Handle delete option
27        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        // Handle clean option
34        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        // Handle retry option
41        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}