cargo-governor 2.0.3

Machine-First, LLM-Ready, CI/CD-Native release automation tool for Rust crates
Documentation
//! Show owners service

use crate::error::CommandExitCode;
use crate::meta::CargoConfig;
use governor_owners::resolve_owners;

/// Service for displaying owner configuration
pub struct ShowService {
    config: CargoConfig,
    explain: bool,
}

impl ShowService {
    pub const fn new(config: CargoConfig, explain: bool) -> Self {
        Self { config, explain }
    }

    pub fn execute(&self, all: bool) -> CommandExitCode {
        let packages: Vec<_> = if all {
            self.config.packages.iter().collect()
        } else {
            self.config.current_package().into_iter().collect()
        };

        for pkg in packages {
            self.show_package_owners(pkg);
        }

        CommandExitCode::Success
    }

    fn show_package_owners(&self, pkg: &crate::meta::PackageConfig) {
        println!("Owners for '{}':", pkg.name);

        let workspace_config = self.config.workspace.as_ref();
        let package_config = pkg.owners.as_ref();

        if workspace_config.is_none() && package_config.is_none() {
            println!("  (no owners configured in Cargo.toml)");
            println!();
            return;
        }

        let resolved = Self::resolve_owners(pkg, workspace_config);

        if resolved.owners.is_empty() {
            println!("  (no owners resolved)");
        } else {
            self.display_owners(&resolved);
        }

        println!("  Total: {}", resolved.owners.len());
        println!();
    }

    fn resolve_owners(
        pkg: &crate::meta::PackageConfig,
        workspace_config: Option<&governor_owners::WorkspaceOwnersConfig>,
    ) -> governor_owners::ResolvedOwners {
        let workspace = workspace_config.cloned().unwrap_or_default();
        let package = pkg.owners.clone().unwrap_or_default();
        resolve_owners(&workspace, &package)
    }

    fn display_owners(&self, resolved: &governor_owners::ResolvedOwners) {
        for owner in &resolved.owners {
            if self.explain {
                if let Some(source) = resolved.sources.get(owner) {
                    println!("  {owner} (from {source})");
                } else {
                    println!("  {owner}");
                }
            } else {
                println!("  {owner}");
            }
        }
    }
}