Skip to content

Commit 83e1c02

Browse files
Alex HolmbergAlex Holmberg
authored andcommitted
feat: added further refactor
1 parent 30aae9d commit 83e1c02

35 files changed

Lines changed: 2021 additions & 4179 deletions

examples/check_vulnerabilities.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use syncable_cli::analyzer::dependency_parser::{DependencyParser};
2-
use syncable_cli::analyzer::vulnerability_checker::VulnerabilityChecker;
2+
use syncable_cli::analyzer::vulnerability::VulnerabilityChecker;
33
use std::path::Path;
44

55
#[tokio::main]

examples/debug_java_vulnerabilities.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use env_logger;
22
use log::{info, error};
33
use syncable_cli::analyzer::dependency_parser::{DependencyParser, Language};
4-
use syncable_cli::analyzer::vulnerability_checker::VulnerabilityChecker;
4+
use syncable_cli::analyzer::vulnerability::VulnerabilityChecker;
55
use std::path::Path;
66
use std::env;
77

src/analyzer/dependency_parser.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::analyzer::{AnalysisConfig, DetectedLanguage, DependencyMap};
2-
use crate::analyzer::vulnerability_checker::{VulnerabilityChecker, VulnerabilityInfo};
2+
use crate::analyzer::vulnerability::{VulnerabilityChecker, VulnerabilityInfo};
33
use crate::error::{Result, AnalysisError};
44
use serde::{Deserialize, Serialize};
55
use std::collections::HashMap;
@@ -147,11 +147,11 @@ impl DependencyParser {
147147
Vulnerability {
148148
id: vuln_info.id.clone(),
149149
severity: match vuln_info.severity {
150-
crate::analyzer::vulnerability_checker::VulnerabilitySeverity::Critical => VulnerabilitySeverity::Critical,
151-
crate::analyzer::vulnerability_checker::VulnerabilitySeverity::High => VulnerabilitySeverity::High,
152-
crate::analyzer::vulnerability_checker::VulnerabilitySeverity::Medium => VulnerabilitySeverity::Medium,
153-
crate::analyzer::vulnerability_checker::VulnerabilitySeverity::Low => VulnerabilitySeverity::Low,
154-
crate::analyzer::vulnerability_checker::VulnerabilitySeverity::Info => VulnerabilitySeverity::Info,
150+
crate::analyzer::vulnerability::VulnerabilitySeverity::Critical => VulnerabilitySeverity::Critical,
151+
crate::analyzer::vulnerability::VulnerabilitySeverity::High => VulnerabilitySeverity::High,
152+
crate::analyzer::vulnerability::VulnerabilitySeverity::Medium => VulnerabilitySeverity::Medium,
153+
crate::analyzer::vulnerability::VulnerabilitySeverity::Low => VulnerabilitySeverity::Low,
154+
crate::analyzer::vulnerability::VulnerabilitySeverity::Info => VulnerabilitySeverity::Info,
155155
},
156156
description: vuln_info.description.clone(),
157157
fixed_in: vuln_info.patched_versions.clone(),

src/analyzer/mod.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,18 @@ pub mod framework_detector;
1717
pub mod frameworks;
1818
pub mod language_detector;
1919
pub mod context;
20-
pub mod vulnerability_checker;
20+
pub mod vulnerability;
2121
pub mod security_analyzer;
2222
pub mod security;
23-
pub mod tool_installer;
24-
pub mod tool_detector;
25-
pub mod runtime_detector;
23+
pub mod tool_management;
24+
pub mod runtime;
2625
pub mod monorepo;
2726
pub mod docker_analyzer;
2827
pub mod display;
2928

3029
// Re-export dependency analysis types
3130
pub use dependency_parser::{
32-
DependencyInfo, DependencyAnalysis, DetailedDependencyMap,
33-
Vulnerability, VulnerabilitySeverity
31+
DependencyInfo, DependencyAnalysis, DetailedDependencyMap
3432
};
3533

3634
// Re-export security analysis types
@@ -45,10 +43,15 @@ pub use security::{
4543
};
4644
pub use security::config::SecurityConfigPreset;
4745

46+
// Re-export tool management types
47+
pub use tool_management::{ToolInstaller, ToolDetector, ToolStatus, InstallationSource};
48+
4849
// Re-export runtime detection types
49-
pub use runtime_detector::{
50-
RuntimeDetector, JavaScriptRuntime, PackageManager, RuntimeDetectionResult, DetectionConfidence
51-
};
50+
pub use runtime::{RuntimeDetector, JavaScriptRuntime, PackageManager, RuntimeDetectionResult, DetectionConfidence};
51+
52+
// Re-export vulnerability checking types
53+
pub use vulnerability::{VulnerabilityChecker, VulnerabilityInfo, VulnerabilityReport, VulnerableDependency};
54+
pub use vulnerability::types::VulnerabilitySeverity as VulnSeverity;
5255

5356
// Re-export monorepo analysis types
5457
pub use monorepo::{

src/analyzer/runtime/detection.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use super::javascript::{RuntimeDetectionResult};
2+
use std::path::Path;
3+
4+
/// Generic runtime detection engine that can be extended for other languages
5+
pub struct RuntimeDetectionEngine;
6+
7+
impl RuntimeDetectionEngine {
8+
/// Detect the primary runtime and package manager for a project
9+
pub fn detect_primary_runtime(project_path: &Path) -> RuntimeDetectionResult {
10+
use super::javascript::RuntimeDetector;
11+
12+
let js_detector = RuntimeDetector::new(project_path.to_path_buf());
13+
js_detector.detect_js_runtime_and_package_manager()
14+
}
15+
16+
/// Get all available package managers in a project
17+
pub fn get_all_package_managers(project_path: &Path) -> Vec<String> {
18+
use super::javascript::RuntimeDetector;
19+
20+
let js_detector = RuntimeDetector::new(project_path.to_path_buf());
21+
js_detector.detect_all_package_managers()
22+
.into_iter()
23+
.map(|pm| pm.as_str().to_string())
24+
.collect()
25+
}
26+
27+
/// Check if a project uses a specific runtime
28+
pub fn uses_runtime(project_path: &Path, runtime: &str) -> bool {
29+
let detection = Self::detect_primary_runtime(project_path);
30+
detection.runtime.as_str() == runtime
31+
}
32+
}
Lines changed: 4 additions & 239 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::path::{PathBuf};
1+
use std::path::PathBuf;
22
use std::fs;
33
use serde::{Deserialize, Serialize};
44
use log::{debug, info};
@@ -112,15 +112,14 @@ impl RuntimeDetector {
112112
package_manager: manager,
113113
detected_lockfiles,
114114
has_package_json,
115-
has_engines_field: false, // Will be updated below
115+
has_engines_field: false,
116116
confidence: DetectionConfidence::High,
117117
};
118118
}
119119

120120
// Priority 2: Check package.json engines field (high confidence)
121-
let mut engines_result = self.detect_by_engines_field();
122-
if let Some((runtime, manager)) = engines_result.clone() {
123-
engines_result = Some((runtime.clone(), manager.clone()));
121+
let engines_result = self.detect_by_engines_field();
122+
if let Some((runtime, manager)) = engines_result {
124123
info!("Detected {} runtime with {} package manager via engines field", runtime.as_str(), manager.as_str());
125124
return RuntimeDetectionResult {
126125
runtime,
@@ -147,7 +146,6 @@ impl RuntimeDetector {
147146

148147
// Priority 4: Default behavior based on project type
149148
if has_package_json {
150-
// If package.json exists but no specific indicators, default to Node.js with npm
151149
debug!("Package.json exists but no specific runtime detected, defaulting to Node.js with npm");
152150
RuntimeDetectionResult {
153151
runtime: JavaScriptRuntime::Node,
@@ -158,7 +156,6 @@ impl RuntimeDetector {
158156
confidence: DetectionConfidence::Low,
159157
}
160158
} else {
161-
// No package.json, not a JavaScript project
162159
debug!("No package.json found, not a JavaScript project");
163160
RuntimeDetectionResult {
164161
runtime: JavaScriptRuntime::Unknown,
@@ -380,236 +377,4 @@ impl RuntimeDetector {
380377

381378
summary
382379
}
383-
}
384-
385-
#[cfg(test)]
386-
mod tests {
387-
use super::*;
388-
use std::fs;
389-
use tempfile::TempDir;
390-
391-
fn create_test_project() -> (TempDir, PathBuf) {
392-
let temp_dir = TempDir::new().unwrap();
393-
let project_path = temp_dir.path().to_path_buf();
394-
(temp_dir, project_path)
395-
}
396-
397-
#[test]
398-
fn test_bun_project_detection() {
399-
let (_temp_dir, project_path) = create_test_project();
400-
401-
// Create bun.lockb file
402-
fs::write(project_path.join("bun.lockb"), b"").unwrap();
403-
404-
let detector = RuntimeDetector::new(project_path);
405-
let result = detector.detect_js_runtime_and_package_manager();
406-
407-
assert_eq!(result.runtime, JavaScriptRuntime::Bun);
408-
assert_eq!(result.package_manager, PackageManager::Bun);
409-
assert_eq!(result.confidence, DetectionConfidence::High);
410-
assert!(result.detected_lockfiles.contains(&"bun.lockb".to_string()));
411-
}
412-
413-
#[test]
414-
fn test_bun_engines_detection() {
415-
let (_temp_dir, project_path) = create_test_project();
416-
417-
// Create package.json with bun engine
418-
let package_json = serde_json::json!({
419-
"name": "test-project",
420-
"engines": {
421-
"bun": "^1.0.0"
422-
}
423-
});
424-
fs::write(
425-
project_path.join("package.json"),
426-
serde_json::to_string_pretty(&package_json).unwrap()
427-
).unwrap();
428-
429-
let detector = RuntimeDetector::new(project_path);
430-
let result = detector.detect_js_runtime_and_package_manager();
431-
432-
assert_eq!(result.runtime, JavaScriptRuntime::Bun);
433-
assert_eq!(result.package_manager, PackageManager::Bun);
434-
assert_eq!(result.confidence, DetectionConfidence::High);
435-
assert!(result.has_engines_field);
436-
}
437-
438-
#[test]
439-
fn test_package_manager_field_detection() {
440-
let (_temp_dir, project_path) = create_test_project();
441-
442-
// Create package.json with packageManager field
443-
let package_json = serde_json::json!({
444-
"name": "test-project",
445-
"packageManager": "bun@1.0.0"
446-
});
447-
fs::write(
448-
project_path.join("package.json"),
449-
serde_json::to_string_pretty(&package_json).unwrap()
450-
).unwrap();
451-
452-
let detector = RuntimeDetector::new(project_path);
453-
let result = detector.detect_js_runtime_and_package_manager();
454-
455-
assert_eq!(result.runtime, JavaScriptRuntime::Bun);
456-
assert_eq!(result.package_manager, PackageManager::Bun);
457-
assert_eq!(result.confidence, DetectionConfidence::High);
458-
}
459-
460-
#[test]
461-
fn test_yarn_project_detection() {
462-
let (_temp_dir, project_path) = create_test_project();
463-
464-
// Create yarn.lock file
465-
fs::write(project_path.join("yarn.lock"), b"").unwrap();
466-
467-
let detector = RuntimeDetector::new(project_path);
468-
let result = detector.detect_js_runtime_and_package_manager();
469-
470-
assert_eq!(result.runtime, JavaScriptRuntime::Node);
471-
assert_eq!(result.package_manager, PackageManager::Yarn);
472-
assert_eq!(result.confidence, DetectionConfidence::High);
473-
}
474-
475-
#[test]
476-
fn test_npm_project_detection() {
477-
let (_temp_dir, project_path) = create_test_project();
478-
479-
// Create package-lock.json file
480-
fs::write(project_path.join("package-lock.json"), b"{}").unwrap();
481-
482-
let detector = RuntimeDetector::new(project_path);
483-
let result = detector.detect_js_runtime_and_package_manager();
484-
485-
assert_eq!(result.runtime, JavaScriptRuntime::Node);
486-
assert_eq!(result.package_manager, PackageManager::Npm);
487-
assert_eq!(result.confidence, DetectionConfidence::High);
488-
}
489-
490-
#[test]
491-
fn test_pnpm_project_detection() {
492-
let (_temp_dir, project_path) = create_test_project();
493-
494-
// Create pnpm-lock.yaml file
495-
fs::write(project_path.join("pnpm-lock.yaml"), b"").unwrap();
496-
497-
let detector = RuntimeDetector::new(project_path);
498-
let result = detector.detect_js_runtime_and_package_manager();
499-
500-
assert_eq!(result.runtime, JavaScriptRuntime::Node);
501-
assert_eq!(result.package_manager, PackageManager::Pnpm);
502-
assert_eq!(result.confidence, DetectionConfidence::High);
503-
}
504-
505-
#[test]
506-
fn test_bunfig_detection() {
507-
let (_temp_dir, project_path) = create_test_project();
508-
509-
// Create bunfig.toml file
510-
fs::write(project_path.join("bunfig.toml"), b"[install]\nregistry = \"https://registry.npmjs.org/\"").unwrap();
511-
512-
let detector = RuntimeDetector::new(project_path);
513-
let result = detector.detect_js_runtime_and_package_manager();
514-
515-
assert_eq!(result.runtime, JavaScriptRuntime::Bun);
516-
assert_eq!(result.package_manager, PackageManager::Bun);
517-
assert_eq!(result.confidence, DetectionConfidence::Medium);
518-
}
519-
520-
#[test]
521-
fn test_bun_script_detection() {
522-
let (_temp_dir, project_path) = create_test_project();
523-
524-
// Create package.json with bun script
525-
let package_json = serde_json::json!({
526-
"name": "test-project",
527-
"scripts": {
528-
"start": "bun run index.ts",
529-
"dev": "bun --watch index.ts"
530-
}
531-
});
532-
fs::write(
533-
project_path.join("package.json"),
534-
serde_json::to_string_pretty(&package_json).unwrap()
535-
).unwrap();
536-
537-
let detector = RuntimeDetector::new(project_path);
538-
let result = detector.detect_js_runtime_and_package_manager();
539-
540-
assert_eq!(result.runtime, JavaScriptRuntime::Bun);
541-
assert_eq!(result.package_manager, PackageManager::Bun);
542-
assert_eq!(result.confidence, DetectionConfidence::Medium);
543-
}
544-
545-
#[test]
546-
fn test_default_detection() {
547-
let (_temp_dir, project_path) = create_test_project();
548-
549-
// Create only package.json with no special fields
550-
let package_json = serde_json::json!({
551-
"name": "test-project"
552-
});
553-
fs::write(
554-
project_path.join("package.json"),
555-
serde_json::to_string_pretty(&package_json).unwrap()
556-
).unwrap();
557-
558-
let detector = RuntimeDetector::new(project_path);
559-
let result = detector.detect_js_runtime_and_package_manager();
560-
561-
assert_eq!(result.runtime, JavaScriptRuntime::Node);
562-
assert_eq!(result.package_manager, PackageManager::Npm);
563-
assert_eq!(result.confidence, DetectionConfidence::Low);
564-
}
565-
566-
#[test]
567-
fn test_multiple_lockfiles() {
568-
let (_temp_dir, project_path) = create_test_project();
569-
570-
// Create multiple lock files - bun should take priority
571-
fs::write(project_path.join("bun.lockb"), b"").unwrap();
572-
fs::write(project_path.join("package-lock.json"), b"{}").unwrap();
573-
fs::write(project_path.join("yarn.lock"), b"").unwrap();
574-
575-
let detector = RuntimeDetector::new(project_path);
576-
let result = detector.detect_js_runtime_and_package_manager();
577-
578-
assert_eq!(result.runtime, JavaScriptRuntime::Bun);
579-
assert_eq!(result.package_manager, PackageManager::Bun);
580-
assert_eq!(result.confidence, DetectionConfidence::High);
581-
582-
let all_managers = detector.detect_all_package_managers();
583-
assert!(all_managers.contains(&PackageManager::Bun));
584-
assert!(all_managers.contains(&PackageManager::Npm));
585-
assert!(all_managers.contains(&PackageManager::Yarn));
586-
}
587-
588-
#[test]
589-
fn test_audit_commands() {
590-
let (_temp_dir, project_path) = create_test_project();
591-
592-
// Create bun project
593-
fs::write(project_path.join("bun.lockb"), b"").unwrap();
594-
595-
let detector = RuntimeDetector::new(project_path);
596-
let commands = detector.get_audit_commands();
597-
598-
assert!(commands.contains(&"bun audit".to_string()));
599-
}
600-
601-
#[test]
602-
fn test_detection_summary() {
603-
let (_temp_dir, project_path) = create_test_project();
604-
605-
// Create bun project
606-
fs::write(project_path.join("bun.lockb"), b"").unwrap();
607-
608-
let detector = RuntimeDetector::new(project_path);
609-
let summary = detector.get_detection_summary();
610-
611-
assert!(summary.contains("bun"));
612-
assert!(summary.contains("high confidence"));
613-
assert!(summary.contains("bun.lockb"));
614-
}
615380
}

0 commit comments

Comments
 (0)