ferrflow 7.0.2

Universal semantic versioning for monorepos and classic repos
Documentation
use anyhow::Result;
use std::path::Path;

use crate::config::Config;
use crate::git::{get_repo_root, open_repo};

mod checks;
mod report;

use report::Report;

#[derive(Clone, Copy, clap::ValueEnum)]
pub enum DoctorFormat {
    Human,
    Json,
}

pub fn run(config_path: Option<&Path>, format: DoctorFormat, online: bool) -> Result<()> {
    let cwd = std::env::current_dir()?;
    let repo = open_repo(&cwd).ok();
    let root = repo
        .as_ref()
        .and_then(|r| get_repo_root(r).ok())
        .unwrap_or_else(|| cwd.clone());

    let discovered = Config::discovered_config_paths(&root);
    let (config, config_error) = match Config::load(&root, config_path) {
        Ok(config) => (Some(config), None),
        Err(err) => (None, Some(format!("{err:#}"))),
    };

    let report = Report::build(vec![
        checks::repo_section(repo.as_ref(), config.as_ref(), &root),
        checks::config_section(config.as_ref(), config_error.as_deref(), &discovered, &root),
        checks::versioning_section(config.as_ref(), &root),
        checks::forge_section(repo.as_ref(), config.as_ref(), online),
        checks::ci_section(&root),
    ]);

    match format {
        DoctorFormat::Json => println!("{}", report.to_json()?),
        DoctorFormat::Human => report.print_human(),
    }

    if report.exit_code != 0 {
        std::process::exit(report.exit_code);
    }
    Ok(())
}

#[cfg(test)]
mod tests;