dry4rust/cli/
analysis_output.rs1use std::path::Path;
7use std::string::ToString;
8
9use crate::analysis::AnalysisResult;
10use crate::analysis::analyze;
11use crate::analyzer::LanguageAnalyzer;
12use crate::cli::cli_error::CliError;
13use crate::cli::cli_error::CliResult;
14use crate::cli::cli_overrides::CliOverrides;
15use crate::cli::output_format::OutputFormat;
16use crate::config::Config;
17use crate::output::reporter::Reporter;
18use crate::scanner::ScanConfig;
19use crate::scanner::scan_files;
20
21pub struct AnalysisOutput {
24 pub config: Config,
25 pub result: AnalysisResult,
26 pub reporter: Box<dyn Reporter>,
27}
28
29impl AnalysisOutput {
30 pub fn produce(
42 analyzer: &dyn LanguageAnalyzer,
43 root: &Path,
44 format: OutputFormat,
45 overrides: &CliOverrides,
46 ) -> CliResult<Self> {
47 Self::from_config(analyzer, root, format, Self::configure(root, overrides)?)
48 }
49
50 pub fn produce_ignoring_baseline(
60 analyzer: &dyn LanguageAnalyzer,
61 root: &Path,
62 format: OutputFormat,
63 overrides: &CliOverrides,
64 ) -> CliResult<Self> {
65 let mut config = Self::configure(root, overrides)?;
66 let named = config.baseline.take();
67 let output = Self::from_config(analyzer, root, format, config)?;
68 Ok(Self {
69 config: Config {
70 baseline: named,
71 ..output.config
72 },
73 ..output
74 })
75 }
76
77 fn configure(root: &Path, overrides: &CliOverrides) -> CliResult<Config> {
78 Config::load(root)
79 .and_then(|config| overrides.apply_to(config))
80 .map_err(|e| CliError::InvalidConfig(e.to_string()))
81 }
82
83 fn from_config(
84 analyzer: &dyn LanguageAnalyzer,
85 root: &Path,
86 format: OutputFormat,
87 config: Config,
88 ) -> CliResult<Self> {
89 let scan_config = ScanConfig::new(config.root.clone())
90 .with_excludes(config.exclude.clone())
91 .with_extensions(
92 analyzer
93 .file_extensions()
94 .iter()
95 .map(ToString::to_string)
96 .collect(),
97 );
98 let files = scan_files(&scan_config);
99
100 if files.is_empty() {
101 return Err(CliError::NoSourceFiles(config.root));
102 }
103
104 let result = analyze(analyzer, &files, &config)?;
105 let reporter = format.reporter(Some(root));
106
107 Ok(Self {
108 config,
109 result,
110 reporter,
111 })
112 }
113}