tldr_cli/commands/
detect_patterns.rs1use std::path::PathBuf;
16
17use anyhow::Result;
18use clap::Args;
19
20use tldr_core::patterns::format::format_pattern_report_text;
21use tldr_core::{detect_patterns_with_config, Language, PatternCategory, PatternConfig};
22
23use crate::output::{OutputFormat, OutputWriter};
24
25#[derive(Debug, Args)]
27pub struct PatternsArgs {
28 #[arg(default_value = ".")]
30 pub path: PathBuf,
31
32 #[arg(long, short = 'l')]
34 pub lang: Option<Language>,
35
36 #[arg(long, short = 'c', value_parser = parse_category)]
38 pub category: Option<PatternCategory>,
39
40 #[arg(long, default_value = "0.5")]
42 pub min_confidence: f64,
43
44 #[arg(long, default_value = "1000")]
46 pub max_files: usize,
47
48 #[arg(long)]
50 pub no_constraints: bool,
51}
52
53fn parse_category(s: &str) -> Result<PatternCategory, String> {
54 s.parse()
55}
56
57impl PatternsArgs {
58 pub fn run(&self, format: OutputFormat, quiet: bool) -> Result<()> {
60 let writer = OutputWriter::new(format, quiet);
61
62 writer.progress(&format!("Analyzing patterns in {}...", self.path.display()));
63
64 let config = PatternConfig {
66 min_confidence: self.min_confidence,
67 max_files: self.max_files,
68 evidence_limit: 3,
69 categories: self.category.map(|c| vec![c]).unwrap_or_default(),
70 generate_constraints: !self.no_constraints,
71 };
72
73 let report = detect_patterns_with_config(&self.path, self.lang, config)?;
75
76 if writer.is_text() {
78 let text = format_pattern_report_text(&report);
79 writer.write_text(&text)?;
80 } else {
81 writer.write(&report)?;
82 }
83
84 Ok(())
85 }
86}