Skip to main content

fallow_engine/health/
pipeline.rs

1//! Health pipeline carrier types shared by the engine health executor.
2
3use fallow_config::{ResolvedConfig, WorkspaceInfo};
4use fallow_output::DiffIndex;
5use fallow_types::workspace::WorkspaceDiagnostic;
6use rustc_hash::{FxHashMap, FxHashSet};
7use std::path::PathBuf;
8
9use crate::{
10    duplicates::DuplicationReport,
11    results::{AnalysisResults, DeadCodeAnalysisArtifacts},
12};
13
14use super::StylingAnalysisArtifacts;
15
16/// Discovery / parse inputs the CLI resolves before calling the engine.
17pub struct HealthPipelineInputs {
18    pub config: ResolvedConfig,
19    pub files: Vec<fallow_types::discover::DiscoveredFile>,
20    pub modules: Vec<fallow_types::extract::ModuleInfo>,
21    /// Pre-parse pipeline timings (config / discover / parse milliseconds).
22    pub config_ms: f64,
23    pub discover_ms: f64,
24    pub parse_ms: f64,
25    pub parse_cpu_ms: f64,
26    /// True when discover + parse were reused from the upstream check pass.
27    pub shared_parse: bool,
28    pub pre_computed_analysis: Option<DeadCodeAnalysisArtifacts>,
29    pub dead_code_results: Option<AnalysisResults>,
30    pub styling_artifacts: Option<StylingAnalysisArtifacts>,
31    pub pre_computed_duplication: Option<DuplicationReport>,
32    pub workspaces: Vec<WorkspaceInfo>,
33    pub workspace_diagnostics: Vec<WorkspaceDiagnostic>,
34}
35
36pub(super) struct HealthPipelineRunInputs<M> {
37    pub(super) config: ResolvedConfig,
38    pub(super) files: Vec<fallow_types::discover::DiscoveredFile>,
39    pub(super) modules: M,
40    pub(super) config_ms: f64,
41    pub(super) discover_ms: f64,
42    pub(super) parse_ms: f64,
43    pub(super) parse_cpu_ms: f64,
44    pub(super) shared_parse: bool,
45    pub(super) pre_computed_analysis: Option<DeadCodeAnalysisArtifacts>,
46    pub(super) dead_code_results: Option<AnalysisResults>,
47    pub(super) styling_artifacts: Option<StylingAnalysisArtifacts>,
48    pub(super) pre_computed_duplication: Option<DuplicationReport>,
49    pub(super) workspaces: Vec<WorkspaceInfo>,
50    pub(super) workspace_diagnostics: Vec<WorkspaceDiagnostic>,
51}
52
53impl From<HealthPipelineInputs>
54    for HealthPipelineRunInputs<Vec<fallow_types::extract::ModuleInfo>>
55{
56    fn from(input: HealthPipelineInputs) -> Self {
57        Self {
58            config: input.config,
59            files: input.files,
60            modules: input.modules,
61            config_ms: input.config_ms,
62            discover_ms: input.discover_ms,
63            parse_ms: input.parse_ms,
64            parse_cpu_ms: input.parse_cpu_ms,
65            shared_parse: input.shared_parse,
66            pre_computed_analysis: input.pre_computed_analysis,
67            dead_code_results: input.dead_code_results,
68            styling_artifacts: input.styling_artifacts,
69            pre_computed_duplication: input.pre_computed_duplication,
70            workspaces: input.workspaces,
71            workspace_diagnostics: input.workspace_diagnostics,
72        }
73    }
74}
75
76/// Scope inputs the CLI resolves before calling the engine.
77///
78/// The engine no longer fetches changed files, workspace roots, the shared diff
79/// index, or the CODEOWNERS-backed grouping resolver itself: those touch CLI
80/// state (the shared-diff `OnceLock`, CODEOWNERS parsing, workspace discovery
81/// error rendering), so the CLI resolves them and threads them in here.
82pub struct HealthScopeInputs<'a, R> {
83    pub changed_files: Option<FxHashSet<PathBuf>>,
84    pub diff_index: Option<&'a DiffIndex>,
85    pub ws_roots: Option<Vec<PathBuf>>,
86    pub group_resolver: Option<R>,
87}
88
89pub(super) struct HealthPipelineTimings {
90    pub(super) config: f64,
91    pub(super) discover: f64,
92    pub(super) parse: f64,
93    /// Summed parse CPU time across rayon workers; `0.0` when parse was reused.
94    pub(super) parse_cpu: f64,
95    /// True when discover + parse were reused from the upstream check pass.
96    pub(super) shared_parse: bool,
97}
98
99impl HealthPipelineTimings {
100    pub(super) fn into_base_input(self, complexity_ms: f64) -> HealthTimingBaseInput {
101        HealthTimingBaseInput {
102            config_ms: self.config,
103            discover_ms: self.discover,
104            parse_ms: self.parse,
105            parse_cpu_ms: self.parse_cpu,
106            complexity_ms,
107            shared_parse: self.shared_parse,
108        }
109    }
110}
111
112pub(super) struct HealthScope<'a, R> {
113    pub(super) max_cyclomatic: u16,
114    pub(super) max_cognitive: u16,
115    pub(super) max_crap: f64,
116    pub(super) enforce_crap: bool,
117    pub(super) ignore_set: globset::GlobSet,
118    pub(super) changed_files: Option<FxHashSet<PathBuf>>,
119    pub(super) diff_index: Option<&'a DiffIndex>,
120    pub(super) ws_roots: Option<Vec<PathBuf>>,
121    pub(super) group_resolver: Option<R>,
122    pub(super) file_paths: FxHashMap<crate::discover::FileId, &'a PathBuf>,
123}
124
125pub(super) struct HealthTimingBaseInput {
126    pub(super) config_ms: f64,
127    pub(super) discover_ms: f64,
128    pub(super) parse_ms: f64,
129    pub(super) parse_cpu_ms: f64,
130    pub(super) complexity_ms: f64,
131    pub(super) shared_parse: bool,
132}