tldr_cli/commands/
impact.rs1use std::path::PathBuf;
8
9use anyhow::Result;
10use clap::Args;
11
12use tldr_core::types::ImpactReport;
13use tldr_core::{build_project_call_graph, impact_analysis_with_ast_fallback, Language};
14
15use crate::commands::daemon_router::{params_with_func_depth, try_daemon_route};
16use crate::output::{format_impact_text, OutputFormat, OutputWriter};
17
18#[derive(Debug, Args)]
20pub struct ImpactArgs {
21 pub function: String,
23
24 #[arg(default_value = ".")]
26 pub path: PathBuf,
27
28 #[arg(long, short = 'l')]
30 pub lang: Option<Language>,
31
32 #[arg(long, short = 'd', default_value = "5")]
34 pub depth: usize,
35
36 #[arg(long)]
38 pub file: Option<PathBuf>,
39
40 #[arg(long)]
42 pub type_aware: bool,
43}
44
45impl ImpactArgs {
46 pub fn run(&self, format: OutputFormat, quiet: bool) -> Result<()> {
48 let writer = OutputWriter::new(format, quiet);
49
50 let language = self
52 .lang
53 .unwrap_or_else(|| Language::from_directory(&self.path).unwrap_or(Language::Python));
54
55 let type_aware_msg = if self.type_aware { " (type-aware)" } else { "" };
56
57 if let Some(report) = try_daemon_route::<ImpactReport>(
59 &self.path,
60 "impact",
61 params_with_func_depth(&self.function, Some(self.depth)),
62 ) {
63 if writer.is_text() {
65 let text = format_impact_text(&report, self.type_aware);
66 writer.write_text(&text)?;
67 return Ok(());
68 } else {
69 writer.write(&report)?;
70 return Ok(());
71 }
72 }
73
74 writer.progress(&format!(
76 "Building call graph for {} ({:?}){}...",
77 self.path.display(),
78 language,
79 type_aware_msg
80 ));
81
82 let graph = build_project_call_graph(&self.path, language, None, true)?;
84
85 writer.progress(&format!(
86 "Analyzing impact of {}{}...",
87 self.function, type_aware_msg
88 ));
89
90 let mut report = impact_analysis_with_ast_fallback(
94 &graph,
95 &self.function,
96 self.depth,
97 self.file.as_deref(),
98 &self.path,
99 language,
100 )?;
101
102 if self.type_aware {
105 report.type_resolution = Some(tldr_core::types::TypeResolutionStats {
106 enabled: true,
107 resolved_high_confidence: 0,
108 resolved_medium_confidence: 0,
109 fallback_used: 0,
110 total_call_sites: 0,
111 });
112 }
113
114 if writer.is_text() {
116 let text = format_impact_text(&report, self.type_aware);
117 writer.write_text(&text)?;
118 } else {
119 writer.write(&report)?;
120 }
121
122 Ok(())
123 }
124}