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