tldr_cli/commands/
whatbreaks.rs1use std::path::PathBuf;
18
19use anyhow::Result;
20use clap::{Args, ValueEnum};
21
22use tldr_core::analysis::whatbreaks::{whatbreaks_analysis, TargetType, WhatbreaksOptions};
23use tldr_core::Language;
24
25use crate::output::{format_whatbreaks_text, OutputFormat, OutputWriter};
26
27#[derive(Debug, Clone, Copy, ValueEnum)]
29pub enum TargetTypeArg {
30 Function,
32 File,
34 Module,
36}
37
38impl From<TargetTypeArg> for TargetType {
39 fn from(arg: TargetTypeArg) -> Self {
40 match arg {
41 TargetTypeArg::Function => TargetType::Function,
42 TargetTypeArg::File => TargetType::File,
43 TargetTypeArg::Module => TargetType::Module,
44 }
45 }
46}
47
48#[derive(Debug, Args)]
53pub struct WhatbreaksArgs {
54 pub target: String,
56
57 #[arg(default_value = ".")]
59 pub path: PathBuf,
60
61 #[arg(long = "type", short = 't', value_enum)]
63 pub target_type: Option<TargetTypeArg>,
64
65 #[arg(long, short = 'd', default_value = "3")]
67 pub depth: usize,
68
69 #[arg(long)]
71 pub quick: bool,
72
73 #[arg(long, short = 'l')]
75 pub lang: Option<Language>,
76}
77
78impl WhatbreaksArgs {
79 pub fn run(&self, format: OutputFormat, quiet: bool) -> Result<()> {
81 let writer = OutputWriter::new(format, quiet);
82
83 if !self.path.exists() {
85 anyhow::bail!("Path not found: {}", self.path.display());
86 }
87
88 writer.progress(&format!(
89 "Analyzing what breaks if '{}' changes...",
90 self.target
91 ));
92
93 let options = WhatbreaksOptions {
95 depth: self.depth,
96 quick: self.quick,
97 language: self.lang,
98 force_type: self.target_type.map(|t| t.into()),
99 };
100
101 let report = whatbreaks_analysis(&self.target, &self.path, &options)?;
103
104 writer.progress(&format!(
105 "Target type: {} ({})",
106 report.target_type, report.detection_reason
107 ));
108
109 if writer.is_text() {
111 let text = format_whatbreaks_text(&report);
112 writer.write_text(&text)?;
113 } else {
114 writer.write(&report)?;
115 }
116
117 Ok(())
118 }
119}