1use std::path::Path;
2
3mod checks;
4mod diagnostics;
5mod discovery;
6mod workflow;
7
8pub use diagnostics::{Diagnostic, DiagnosticLevel};
9
10pub fn run_analysis(repo_root: &Path) -> anyhow::Result<Vec<Diagnostic>> {
12 let workflow_files = discovery::discover_workflows(repo_root)?;
14
15 let mut parsed = Vec::new();
17 for wf_path in &workflow_files {
18 match workflow::ParsedWorkflow::from_file(wf_path) {
19 Ok(wf) => parsed.push(wf),
20 Err(err) => {
21 parsed.push(workflow::ParsedWorkflow::from_parse_error(
23 wf_path.clone(),
24 err,
25 ));
26 }
27 }
28 }
29
30 let mut diags: Vec<Diagnostic> = Vec::new();
32
33 for wf in &parsed {
34 diags.extend(checks::missing_on::check(wf));
35 diags.extend(checks::missing_jobs::check(wf));
36 diags.extend(checks::invalid_needs::check(wf));
37 diags.extend(checks::invalid_uses::check(wf));
38 diags.extend(checks::rust_toolchain::check(wf));
39 diags.extend(checks::missing_checkout::check(wf));
40 diags.extend(checks::working_directory::check(wf, repo_root));
41 diags.extend(checks::file_references::check(wf, repo_root));
42 }
43
44 Ok(diags)
45}