ricecoder_research/dependency_analyzer/
version_analyzer.rs

1//! Version analysis for dependencies
2
3use super::{VersionConflict, VersionUpdate};
4use crate::models::Dependency;
5
6/// Analyzes dependency versions for conflicts and updates
7#[derive(Debug)]
8pub struct VersionAnalyzer;
9
10impl VersionAnalyzer {
11    /// Creates a new VersionAnalyzer
12    pub fn new() -> Self {
13        VersionAnalyzer
14    }
15
16    /// Finds version conflicts in dependencies
17    pub fn find_conflicts(&self, dependencies: &[Dependency]) -> Vec<VersionConflict> {
18        let mut conflicts = Vec::new();
19        let mut version_map: std::collections::HashMap<String, Vec<String>> =
20            std::collections::HashMap::new();
21
22        // Group dependencies by name
23        for dep in dependencies {
24            version_map
25                .entry(dep.name.clone())
26                .or_default()
27                .push(dep.version.clone());
28        }
29
30        // Find conflicts (same dependency with different versions)
31        for (name, versions) in version_map {
32            if versions.len() > 1 {
33                // Remove duplicates and check if there are actual conflicts
34                let mut unique_versions = versions;
35                unique_versions.sort();
36                unique_versions.dedup();
37
38                if unique_versions.len() > 1 {
39                    conflicts.push(VersionConflict {
40                        dependency_name: name,
41                        versions: unique_versions.clone(),
42                        description: format!(
43                            "Multiple versions found: {}",
44                            unique_versions.join(", ")
45                        ),
46                    });
47                }
48            }
49        }
50
51        conflicts
52    }
53
54    /// Suggests version updates for dependencies
55    pub fn suggest_updates(&self, _dependencies: &[Dependency]) -> Vec<VersionUpdate> {
56        // This is a placeholder implementation
57        // In a real implementation, this would check against package registries
58        // for newer versions and suggest updates
59        Vec::new()
60    }
61}
62
63impl Default for VersionAnalyzer {
64    fn default() -> Self {
65        Self::new()
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn test_version_analyzer_creation() {
75        let analyzer = VersionAnalyzer::new();
76        assert!(true);
77    }
78
79    #[test]
80    fn test_version_analyzer_no_conflicts() {
81        let analyzer = VersionAnalyzer::new();
82        let deps = vec![
83            Dependency {
84                name: "serde".to_string(),
85                version: "1.0.0".to_string(),
86                constraints: None,
87                is_dev: false,
88            },
89            Dependency {
90                name: "tokio".to_string(),
91                version: "1.0.0".to_string(),
92                constraints: None,
93                is_dev: false,
94            },
95        ];
96
97        let conflicts = analyzer.find_conflicts(&deps);
98        assert!(conflicts.is_empty());
99    }
100
101    #[test]
102    fn test_version_analyzer_finds_conflicts() {
103        let analyzer = VersionAnalyzer::new();
104        let deps = vec![
105            Dependency {
106                name: "serde".to_string(),
107                version: "1.0.0".to_string(),
108                constraints: None,
109                is_dev: false,
110            },
111            Dependency {
112                name: "serde".to_string(),
113                version: "2.0.0".to_string(),
114                constraints: None,
115                is_dev: false,
116            },
117        ];
118
119        let conflicts = analyzer.find_conflicts(&deps);
120        assert_eq!(conflicts.len(), 1);
121        assert_eq!(conflicts[0].dependency_name, "serde");
122        assert_eq!(conflicts[0].versions.len(), 2);
123    }
124
125    #[test]
126    fn test_version_analyzer_default() {
127        let analyzer = VersionAnalyzer::default();
128        assert!(true);
129    }
130}