(self, session: &mut ChatSession)
| 31 | |
| 32 | impl LogdumpArgs { |
| 33 | pub async fn execute(self, session: &mut ChatSession) -> Result<ChatState, ChatError> { |
| 34 | execute!( |
| 35 | session.stderr, |
| 36 | StyledText::brand_fg(), |
| 37 | style::Print("Collecting logs...\n"), |
| 38 | StyledText::reset(), |
| 39 | )?; |
| 40 | |
| 41 | let timestamp = Utc::now().format("%Y-%m-%dT%H-%M-%SZ").to_string(); |
| 42 | let zip_filename = format!("q-logs-{}.zip", timestamp); |
| 43 | let zip_path: PathBuf = PathBuf::from(&zip_filename); |
| 44 | let logs_directory = |
| 45 | logs_dir().map_err(|e| ChatError::Custom(format!("Failed to get logs directory: {}", e).into()))?; |
| 46 | |
| 47 | match self.create_log_dump(&zip_path, logs_directory).await { |
| 48 | Ok(log_count) => { |
| 49 | execute!( |
| 50 | session.stderr, |
| 51 | StyledText::success_fg(), |
| 52 | style::Print(format!( |
| 53 | "✓ Successfully created {} with {} log files\n", |
| 54 | zip_filename, log_count |
| 55 | )), |
| 56 | StyledText::reset(), |
| 57 | )?; |
| 58 | }, |
| 59 | Err(e) => { |
| 60 | execute!( |
| 61 | session.stderr, |
| 62 | StyledText::error_fg(), |
| 63 | style::Print(format!("✗ Failed to create log dump: {}\n\n", e)), |
| 64 | StyledText::reset(), |
| 65 | )?; |
| 66 | return Err(ChatError::Custom(format!("Log dump failed: {}", e).into())); |
| 67 | }, |
| 68 | } |
| 69 | |
| 70 | Ok(ChatState::PromptUser { |
| 71 | skip_printing_tools: true, |
| 72 | }) |
| 73 | } |
| 74 | |
| 75 | async fn create_log_dump(&self, zip_path: &Path, logs_dir: PathBuf) -> Result<usize, Box<dyn std::error::Error>> { |
| 76 | let file = std::fs::File::create(zip_path)?; |
nothing calls this directly
no test coverage detected