use clap::ArgMatches;
use crate::domain::usecases::fmt::{run_fmt, DrSource, FmtMode, FmtOutcome, FmtReport};
use crate::infra::driven::fs::canonical::{decision_record_canonical, issue_canonical};
use crate::infra::driven::fs::raw_text::{FsRawTextReader, FsRawTextWriter};
use super::super::Context;
pub(in super::super) fn execute_fmt(matches: &ArgMatches, ctx: &Context<'_>) {
let mode = if matches.get_flag("check") {
FmtMode::Check
} else if matches.get_flag("dry-run") {
FmtMode::DryRun
} else {
FmtMode::Apply
};
let issue_repo = ctx.issue_repository();
let issue_defects = ctx.issue_defect_scanner();
let dr_repos: Vec<_> = ctx
.config()
.decision_kinds
.iter()
.map(|k| ctx.decision_record_repository(k))
.collect();
let dr_defects: Vec<_> = ctx
.config()
.decision_kinds
.iter()
.map(|k| ctx.decision_record_defect_scanner(k))
.collect();
let dr_sources: Vec<DrSource<'_>> = dr_repos
.iter()
.zip(dr_defects.iter())
.map(|(r, d)| DrSource {
repo: r,
defect_scanner: d,
canonical: &decision_record_canonical,
})
.collect();
let outcome = run_fmt(
&issue_repo,
&issue_defects,
&issue_canonical,
&dr_sources,
&FsRawTextReader,
&FsRawTextWriter,
mode,
);
render_outcome(&outcome);
let should_fail =
outcome.has_errors() || (matches!(mode, FmtMode::Check) && outcome.report.has_changes());
if should_fail {
std::process::exit(1);
}
}
fn render_outcome(outcome: &FmtOutcome) {
render_report(&outcome.report);
for err in &outcome.errors {
eprintln!("error: {err}");
}
}
fn render_report(report: &FmtReport) {
for change in &report.changes {
println!("--- {}", change.path.display());
if !change.diff.is_empty() {
print!("{}", change.diff);
}
}
if report.has_changes() {
println!(
"{} file(s) need formatting, {} already canonical",
report.changes.len(),
report.unchanged
);
}
}