cartulary 0.3.0-alpha.1

The knowledge layer of your project — decisions, issues, docs, all in one place.
Documentation
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
        );
    }
}