Skip to main content

driven/cli/
analyze.rs

1//! Analyze command - analyze codebase for context
2
3use crate::{Result, context::ProjectScanner};
4use std::path::Path;
5
6/// Analyze command handler
7#[derive(Debug)]
8pub struct AnalyzeCommand;
9
10impl AnalyzeCommand {
11    /// Run analysis
12    pub fn run(project_root: &Path) -> Result<()> {
13        let spinner = super::create_spinner("Analyzing project structure...");
14
15        let scanner = ProjectScanner::new();
16        let result = scanner.scan(project_root)?;
17
18        spinner.finish_and_clear();
19
20        // Display results
21        println!("📊 Project Analysis:");
22        println!();
23
24        println!("  Languages:");
25        for lang in &result.languages {
26            println!("    - {}", lang);
27        }
28
29        println!();
30        println!("  Frameworks:");
31        for framework in &result.frameworks {
32            println!("    - {}", framework);
33        }
34
35        println!();
36        println!("  Statistics:");
37        let total_files: usize = result.file_counts.values().sum();
38        println!("    - Files: {}", total_files);
39        println!("    - Directories: {}", result.key_directories.len());
40
41        if !result.config_files.is_empty() {
42            println!();
43            println!("  Config files found:");
44            for config in result.config_files.iter().take(10) {
45                println!("    - {}", config);
46            }
47            if result.config_files.len() > 10 {
48                println!("    ... and {} more", result.config_files.len() - 10);
49            }
50        }
51
52        Ok(())
53    }
54
55    /// Generate context rules from analysis
56    pub fn generate_context(project_root: &Path, output: &Path) -> Result<()> {
57        use crate::context::ContextProvider;
58
59        let spinner = super::create_spinner("Analyzing and generating context...");
60
61        let provider = ContextProvider::new();
62        let context = provider.generate(project_root)?;
63
64        spinner.finish_and_clear();
65
66        // Write context to output
67        std::fs::write(output, context)
68            .map_err(|e| crate::DrivenError::Context(format!("Failed to write context: {}", e)))?;
69
70        super::print_success(&format!("Generated context rules: {}", output.display()));
71
72        Ok(())
73    }
74
75    /// Index codebase for fast lookups
76    pub fn index(project_root: &Path) -> Result<()> {
77        use crate::context::CodebaseIndexer;
78
79        let spinner = super::create_spinner("Indexing codebase...");
80
81        let indexer = CodebaseIndexer::new();
82        let index = indexer.index(project_root)?;
83
84        // Save index
85        let index_path = project_root.join(".driven/index.bin");
86        if let Some(parent) = index_path.parent() {
87            std::fs::create_dir_all(parent).map_err(|e| {
88                crate::DrivenError::Context(format!("Failed to create directory: {}", e))
89            })?;
90        }
91
92        index.save(&index_path)?;
93
94        spinner.finish_and_clear();
95
96        super::print_success(&format!(
97            "Indexed {} files ({} bytes)",
98            index.file_count(),
99            index.size_bytes()
100        ));
101
102        Ok(())
103    }
104}