cartulary 0.3.0-alpha.1

The knowledge layer of your project — decisions, issues, docs, all in one place.
Documentation
use clap::{Arg, ArgMatches, Command};

use crate::domain::usecases::check::{check_issue_corpus, IssueSource};
use crate::infra::driving::cli::commands::check::{render_human_entries, CheckEntry};
use crate::infra::driving::cli::errors::{die1, CliError};
use crate::infra::driving::cli::{render_structured, Context};

pub(super) fn subcommand() -> Command {
    Command::new("check")
        .about("Validate all issue files and report errors")
        .arg(
            Arg::new("verbose")
                .long("verbose")
                .short('v')
                .help("Also list valid files")
                .action(clap::ArgAction::SetTrue),
        )
}

pub(super) fn execute(sub: &ArgMatches, ctx: &Context<'_>) {
    let output_fmt = ctx.output_fmt;
    let verbose = sub.get_flag("verbose");
    let repo = ctx.issue_repository();
    let defects = ctx.issue_defect_scanner();
    let config = ctx.config();
    let known_refs = ctx.load_known_refs().unwrap_or_else(|e| {
        die1(
            CliError::new(format!("loading workspace refs: {e}")),
            output_fmt,
        );
    });
    let descriptors = config.tag_descriptors_for("issues");
    let entries = check_issue_corpus(
        &IssueSource {
            repo: &repo,
            defect_scanner: &defects,
            content_reader: &repo,
            statuses: ctx.issues_statuses,
            tag_descriptors: &descriptors,
        },
        &known_refs,
    )
    .unwrap_or_else(|e| die1(CliError::new(e.to_string()), output_fmt));

    if output_fmt.is_structured() {
        let serialised: Vec<CheckEntry> = entries.iter().map(CheckEntry::from).collect();
        let has_errors = serialised.iter().any(|e| !e.ok);
        render_structured(&serialised, output_fmt);
        if has_errors {
            std::process::exit(1);
        }
        return;
    }

    render_human_entries(&entries, verbose);
    if entries.iter().any(|e| e.violations.has_errors()) {
        std::process::exit(1);
    }
}