syncable_cli/analyzer/context/
analysis.rs

1use crate::analyzer::{
2    AnalysisConfig, BuildScript, DetectedLanguage, DetectedTechnology, EntryPoint, EnvVar, Port,
3    ProjectType,
4};
5use crate::error::Result;
6use std::collections::{HashMap, HashSet};
7use std::path::Path;
8
9use super::file_analyzers::{docker, env, makefile};
10use super::language_analyzers::{go, javascript, jvm, python, rust};
11use super::microservices;
12use super::project_type;
13use super::tech_specific;
14
15/// Project context information
16pub struct ProjectContext {
17    pub entry_points: Vec<EntryPoint>,
18    pub ports: Vec<Port>,
19    pub environment_variables: Vec<EnvVar>,
20    pub project_type: ProjectType,
21    pub build_scripts: Vec<BuildScript>,
22}
23
24/// Analyzes project context including entry points, ports, and environment variables
25pub fn analyze_context(
26    project_root: &Path,
27    languages: &[DetectedLanguage],
28    technologies: &[DetectedTechnology],
29    config: &AnalysisConfig,
30) -> Result<ProjectContext> {
31    log::info!("Analyzing project context");
32
33    let mut entry_points = Vec::new();
34    let mut ports = HashSet::new();
35    let mut env_vars = HashMap::new();
36    let mut build_scripts = Vec::new();
37
38    // Analyze based on detected languages
39    for language in languages {
40        match language.name.as_str() {
41            "JavaScript" | "TypeScript" => {
42                javascript::analyze_node_project(project_root, &mut entry_points, &mut ports, &mut env_vars, &mut build_scripts, config)?;
43            }
44            "Python" => {
45                python::analyze_python_project(project_root, &mut entry_points, &mut ports, &mut env_vars, &mut build_scripts, config)?;
46            }
47            "Rust" => {
48                rust::analyze_rust_project(project_root, &mut entry_points, &mut ports, &mut env_vars, &mut build_scripts, config)?;
49            }
50            "Go" => {
51                go::analyze_go_project(project_root, &mut entry_points, &mut ports, &mut env_vars, &mut build_scripts, config)?;
52            }
53            "Java" | "Kotlin" => {
54                jvm::analyze_jvm_project(project_root, &mut ports, &mut env_vars, &mut build_scripts, config)?;
55            }
56            _ => {}
57        }
58    }
59
60    // Analyze common configuration files
61    docker::analyze_docker_files(project_root, &mut ports, &mut env_vars)?;
62    env::analyze_env_files(project_root, &mut env_vars)?;
63    makefile::analyze_makefile(project_root, &mut build_scripts)?;
64
65    // Technology-specific analysis
66    for technology in technologies {
67        tech_specific::analyze_technology_specifics(technology, project_root, &mut entry_points, &mut ports)?;
68    }
69
70    // Detect microservices structure
71    let microservices = microservices::detect_microservices_structure(project_root)?;
72
73    // Determine project type
74    let ports_vec: Vec<Port> = ports.iter().cloned().collect();
75    let project_type = project_type::determine_project_type_with_structure(
76        languages,
77        technologies,
78        &entry_points,
79        &ports_vec,
80        &microservices,
81    );
82
83    // Convert collections to vectors
84    let ports: Vec<Port> = ports.into_iter().collect();
85    let environment_variables: Vec<EnvVar> = env_vars
86        .into_iter()
87        .map(|(name, (default, required, desc))| EnvVar {
88            name,
89            default_value: default,
90            required,
91            description: desc,
92        })
93        .collect();
94
95    Ok(ProjectContext {
96        entry_points,
97        ports,
98        environment_variables,
99        project_type,
100        build_scripts,
101    })
102}