kabu 0.7.1

CLI tool to enhance git worktree and jj workspace with automated setup
use crate::color;
use crate::color::ColorScheme;
use crate::config::{self, Config};
use crate::error::{Error, Result};
use crate::hook;
use crate::trust;

use std::path::Path;

pub(crate) enum TrustHint {
    None,
    SkipHooks { command: &'static str },
}

pub(crate) fn load_config_with_trust_check(
    repo_root: &Path,
    main_worktree_path: &Path,
    enforce_hooks: bool,
    hint: TrustHint,
) -> Result<Config> {
    let global_config = config::load_global()?;
    let initial_repo_config = config::load(repo_root)?.unwrap_or_default();
    let initial_config =
        config::merge_with_global(initial_repo_config.clone(), global_config.as_ref());
    color::set_cli_theme(&initial_config.ui.colors);

    if enforce_hooks
        && initial_repo_config.hooks.has_hooks()
        && !trust::is_trusted(main_worktree_path, &initial_repo_config)?
    {
        hook::display_hooks_for_review(&initial_repo_config.hooks);

        eprintln!();
        eprintln!("{}", ColorScheme::error("Configuration is not trusted."));
        eprintln!("The config file contains hooks that can execute arbitrary commands.");
        eprintln!("For security, you must explicitly review and trust the configuration.");
        eprintln!();
        eprintln!("To trust this configuration, run:");
        eprintln!("  kabu trust");

        if let TrustHint::SkipHooks { command } = hint {
            eprintln!();
            eprintln!("Or skip hooks:");
            eprintln!("  {command}");
        }

        return Err(Error::HooksNotTrusted);
    }

    // TOCTOU protection: reload config immediately before use
    let repo_config = config::load(repo_root)?.unwrap_or_default();
    let config = config::merge_with_global(repo_config.clone(), global_config.as_ref());
    color::set_cli_theme(&config.ui.colors);
    if enforce_hooks
        && repo_config.hooks.has_hooks()
        && !trust::is_trusted(main_worktree_path, &repo_config)?
    {
        eprintln!(
            "{}",
            ColorScheme::error("Config file was modified after trust check.")
        );
        eprintln!("For security, configuration must be re-trusted after any changes.");
        eprintln!("Run: kabu trust");
        return Err(Error::HooksNotTrusted);
    }

    Ok(config)
}