bytes_radar/cli/
mod.rs

1#[cfg(feature = "cli")]
2mod args;
3#[cfg(feature = "cli")]
4mod output;
5#[cfg(feature = "cli")]
6mod progress;
7#[cfg(feature = "cli")]
8mod url_parser;
9
10#[cfg(feature = "cli")]
11use crate::core::*;
12#[cfg(feature = "cli")]
13use clap::Parser;
14#[cfg(feature = "cli")]
15use std::time::Instant;
16
17#[cfg(feature = "cli")]
18pub use args::{Cli, OutputFormat};
19
20#[cfg(feature = "cli")]
21pub async fn run() -> Result<()> {
22    let cli = args::Cli::parse();
23
24    if cli.debug {
25        env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug")).init();
26    } else {
27        env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init();
28    }
29
30    match &cli.url {
31        Some(url) => analyze_remote_archive(url, &cli).await,
32        None => {
33            url_parser::show_usage_examples();
34            std::process::exit(1);
35        }
36    }
37}
38
39#[cfg(feature = "cli")]
40async fn analyze_remote_archive(url: &str, cli: &Cli) -> Result<()> {
41    let format = cli.format.as_ref().unwrap_or(&OutputFormat::Table);
42    let should_show_progress =
43        !cli.no_progress && matches!(format, OutputFormat::Table) && !cli.quiet;
44
45    let processed_url = url_parser::expand_url(url);
46
47    if should_show_progress && !cli.quiet {
48        println!("Analyzing: {}", processed_url);
49    }
50
51    let start_time = Instant::now();
52    let progress_bar = progress::create_progress_bar(should_show_progress);
53
54    let mut analyzer = RemoteAnalyzer::new();
55
56    if let Some(token) = &cli.token {
57        analyzer.set_github_token(token);
58    }
59
60    analyzer.set_timeout(cli.timeout);
61    analyzer.set_allow_insecure(cli.allow_insecure);
62    analyzer.set_progress_bar(progress_bar.clone());
63
64    if cli.aggressive_filter {
65        analyzer.set_aggressive_filtering(true);
66    } else {
67        let mut filter = filter::IntelligentFilter::default();
68        filter.max_file_size = cli.max_file_size * 1024;
69        filter.ignore_test_dirs = !cli.include_tests;
70        filter.ignore_docs_dirs = !cli.include_docs;
71        analyzer.set_filter(filter);
72    }
73
74    let project_analysis = analyzer.analyze_url(&processed_url).await?;
75
76    let elapsed = start_time.elapsed();
77
78    if let Some(pb) = &progress_bar {
79        pb.finish_and_clear();
80    }
81
82    progress::show_completion_message(elapsed, cli.quiet);
83
84    match format {
85        OutputFormat::Table => {
86            output::print_table_format(&project_analysis, cli.detailed, cli.quiet);
87        }
88        OutputFormat::Json => output::print_json_format(&project_analysis)?,
89        OutputFormat::Csv => output::print_csv_format(&project_analysis)?,
90        OutputFormat::Xml => output::print_xml_format(&project_analysis)?,
91    }
92
93    Ok(())
94}