depclean/lib.rs
1// src/lib.rs
2
3// Re-export modules for easier external access.
4pub mod parser;
5pub mod graph;
6pub mod analysis;
7pub mod impact;
8pub mod report;
9pub mod cli;
10// Optional: Include if you're supporting npm as well.
11
12use clap::Parser;
13use std::fs;
14
15use crate::cli::Cli;
16use crate::parser::parse_cargo_lock;
17use crate::graph::DependencyGraph;
18use crate::analysis::{find_duplicates, find_optimal_version};
19use crate::impact::estimate_impact;
20use crate::report::{print_report, VersionSuggestion};
21
22/// Runs the main functionality of the depclean tool.
23///
24/// This function:
25/// - Parses command-line arguments using Clap.
26/// - Reads the specified lockfile (e.g., Cargo.lock).
27/// - Parses the lockfile into a structured format.
28/// - Builds a dependency graph from the parsed data.
29/// - Analyzes the graph for duplicate dependencies.
30/// - Generates version suggestions and estimates potential savings.
31/// - Prints a formatted report to standard output.
32pub fn run() {
33 // Create a Tokio runtime to execute asynchronous code.
34 let rt = tokio::runtime::Runtime::new().expect("Failed to create Tokio runtime");
35
36 rt.block_on(async {
37 // Parse command-line arguments.
38 let args = Cli::parse();
39
40 // Load the lockfile contents.
41 let lockfile_contents = fs::read_to_string(&args.lockfile)
42 .expect("Failed to read lockfile");
43
44 // Parse the Cargo.lock file.
45 let lockfile = parse_cargo_lock(&lockfile_contents)
46 .expect("Failed to parse lockfile");
47
48 // Build the dependency graph from the parsed packages.
49 let graph = DependencyGraph::from_lockfile(lockfile.package);
50
51 // Analyze duplicates in the dependency graph.
52 let duplicates = find_duplicates(&graph);
53
54 // Generate version suggestions for each duplicate dependency.
55 let mut suggestions = Vec::new();
56 for dup in &duplicates {
57 // Use the duplicate's package name as the crate name.
58 let recommended = find_optimal_version(&dup.name, &dup.versions).await
59 .unwrap_or_else(|| "No optimal version found".to_string());
60 suggestions.push(VersionSuggestion {
61 recommended_version: recommended,
62 estimated_saving: 10 * (dup.versions.len() - 1), // simplistic calculation
63 });
64 }
65
66 // Optionally, perform a more detailed impact estimation.
67 let _impact = estimate_impact(&duplicates);
68
69 // Print the final report.
70 print_report(duplicates, suggestions);
71 });
72}