foch_cli/cli/handler/check/
mod.rs1use crate::cli::arg::{AnalysisModeArg, CheckArgs, CheckChannelArg, CheckOutputFormat};
2use crate::cli::handler::{HandlerResult, resolve_input_source};
3use foch::check::run_checks_with_options;
4use foch::game::eu4::analysis::report::render_text;
5use foch::input::{CheckOptions, Config, InputRequest};
6use foch::model::{AnalysisMode, ChannelMode, CheckResult};
7
8mod fix;
9
10pub fn handle_check(check_args: &CheckArgs, config: Config) -> HandlerResult {
11 if fix::requested(check_args) {
12 return fix::handle_check_fix(check_args, config);
13 }
14 let request = InputRequest::new(
15 resolve_input_source(check_args.playset_path.as_deref(), &config)?,
16 config,
17 );
18 let run_options = CheckOptions {
19 analysis_mode: to_analysis_mode(check_args.analysis_mode),
20 channel_mode: to_channel_mode(check_args.channel),
21 include_game_base: !check_args.no_game_base,
22 };
23
24 let result = run_checks_with_options(request, run_options.clone());
25 if let Some(path) = check_args.parse_issue_report.as_ref() {
26 std::fs::write(
27 path,
28 serde_json::to_string_pretty(&result.parse_issue_report)?,
29 )?;
30 }
31
32 let output_result = select_output_result(&result, run_options.channel_mode);
33 let rendered = match check_args.format {
34 CheckOutputFormat::Text => render_text(
35 &output_result,
36 !check_args.no_color,
37 run_options.channel_mode,
38 ),
39 CheckOutputFormat::Json => serde_json::to_string_pretty(&output_result)?,
40 };
41
42 if let Some(path) = check_args.output.as_ref() {
43 std::fs::write(path, rendered)?;
44 println!("check result written to: {}", path.display());
45 } else {
46 println!("{rendered}");
47 }
48
49 if result.has_fatal_errors() {
50 return Ok(1);
51 }
52
53 if check_args.strict && result.has_strict_findings() {
54 return Ok(2);
55 }
56
57 Ok(0)
58}
59
60fn select_output_result(result: &CheckResult, channel_mode: ChannelMode) -> CheckResult {
61 let mut output = result.clone();
62 output.findings = result.filtered_findings(channel_mode);
63 if channel_mode == ChannelMode::Strict {
64 output.advisory_findings.clear();
65 }
66 output
67}
68
69fn to_analysis_mode(mode: AnalysisModeArg) -> AnalysisMode {
70 match mode {
71 AnalysisModeArg::Basic => AnalysisMode::Basic,
72 AnalysisModeArg::Semantic => AnalysisMode::Semantic,
73 }
74}
75
76fn to_channel_mode(channel: CheckChannelArg) -> ChannelMode {
77 match channel {
78 CheckChannelArg::Strict => ChannelMode::Strict,
79 CheckChannelArg::All => ChannelMode::All,
80 }
81}