use crate::{
cli, formatting::FormattingConfig, progress::ProgressConfig, progress::ProgressManager,
};
use std::path::PathBuf;
pub struct AnalyzeConfig {
pub path: PathBuf,
pub format: cli::OutputFormat,
pub output: Option<PathBuf>,
pub threshold_complexity: u32,
pub threshold_duplication: usize,
pub languages: Option<Vec<String>>,
pub coverage_file: Option<PathBuf>,
pub enable_context: bool,
pub context_providers: Option<Vec<String>>,
pub disable_context: Option<Vec<String>>,
pub top: Option<usize>,
pub tail: Option<usize>,
pub summary: bool,
pub semantic_off: bool,
pub verbosity: u8,
pub verbose_macro_warnings: bool,
pub show_macro_stats: bool,
pub min_priority: Option<String>,
pub min_score: Option<f64>,
pub filter_categories: Option<Vec<String>>,
pub no_context_aware: bool,
pub threshold_preset: Option<cli::ThresholdPreset>,
pub _formatting_config: FormattingConfig,
pub parallel: bool,
pub jobs: usize,
pub multi_pass: bool,
pub show_attribution: bool,
pub aggregate_only: bool,
pub no_aggregation: bool,
pub aggregation_method: Option<String>,
pub min_problematic: Option<usize>,
pub no_god_object: bool,
pub max_files: Option<usize>,
pub debug_call_graph: bool,
pub trace_functions: Option<Vec<String>>,
pub call_graph_stats_only: bool,
pub debug_format: cli::DebugFormatArg,
pub validate_call_graph: bool,
pub ast_functional_analysis: bool,
pub functional_analysis_profile: Option<cli::FunctionalAnalysisProfile>,
pub no_tui: bool,
pub show_filter_stats: bool,
pub reference_time: chrono::DateTime<chrono::Utc>,
}
impl AnalyzeConfig {
pub fn needs_diagnostics(&self) -> bool {
self.debug_call_graph || self.validate_call_graph || self.call_graph_stats_only
}
}
pub fn setup_environment(config: &AnalyzeConfig) {
configure_output(config);
set_threshold_preset(config.threshold_preset);
setup_env_vars(config);
}
fn configure_output(config: &AnalyzeConfig) {
if config._formatting_config.color.should_use_color() {
colored::control::set_override(true);
} else {
colored::control::set_override(false);
}
}
fn set_threshold_preset(preset: Option<cli::ThresholdPreset>) {
if let Some(preset) = preset {
let value = match preset {
cli::ThresholdPreset::Strict => "strict",
cli::ThresholdPreset::Balanced => "balanced",
cli::ThresholdPreset::Lenient => "lenient",
};
std::env::set_var("DEBTMAP_THRESHOLD_PRESET", value);
}
}
fn setup_env_vars(config: &AnalyzeConfig) {
setup_max_files(config.max_files);
setup_min_priority(config.min_priority.as_deref());
setup_min_score(config.min_score);
setup_jobs(config.jobs);
setup_functional_analysis(config);
}
fn setup_max_files(max_files: Option<usize>) {
if let Some(max_files) = max_files {
std::env::set_var("DEBTMAP_MAX_FILES", max_files.to_string());
}
}
fn setup_min_score(min_score: Option<f64>) {
if let Some(min_score) = min_score {
std::env::set_var("DEBTMAP_MIN_SCORE_THRESHOLD", min_score.to_string());
}
}
fn setup_min_priority(min_priority: Option<&str>) {
let Some(priority) = min_priority else {
return;
};
let threshold = match priority.to_ascii_lowercase().as_str() {
"low" => 0.0,
"medium" => 30.0,
"high" => 50.0,
"critical" => 70.0,
_ => return,
};
std::env::set_var("DEBTMAP_MIN_SCORE_THRESHOLD", threshold.to_string());
}
fn setup_jobs(jobs: usize) {
if jobs > 0 {
std::env::set_var("DEBTMAP_JOBS", jobs.to_string());
}
}
fn setup_functional_analysis(config: &AnalyzeConfig) {
if !config.ast_functional_analysis {
return;
}
std::env::set_var("DEBTMAP_FUNCTIONAL_ANALYSIS", "true");
if let Some(profile) = config.functional_analysis_profile {
let profile_str = match profile {
cli::FunctionalAnalysisProfile::Strict => "strict",
cli::FunctionalAnalysisProfile::Balanced => "balanced",
cli::FunctionalAnalysisProfile::Lenient => "lenient",
};
std::env::set_var("DEBTMAP_FUNCTIONAL_ANALYSIS_PROFILE", profile_str);
}
}
pub fn setup_progress_manager(verbosity: u8) {
let quiet = std::env::var("DEBTMAP_QUIET").is_ok();
let progress_config = ProgressConfig::from_env(quiet, verbosity);
ProgressManager::init_global(progress_config);
if let Some(manager) = ProgressManager::global() {
manager.tui_start_stage(0);
}
}