llmcc 0.2.65

llmcc brings multi-depth architecture graphs for code understanding and generation.
Documentation
//! Shared CLI options for llmcc tools.
//!
//! This module defines common command-line options used across different llmcc binaries
//! (llmcc and llmcc-test) to ensure consistent behavior and reduce code duplication.

use clap::Args;
use llmcc_dot::ComponentDepth;

/// Common options for graph building and visualization.
#[derive(Args, Debug, Clone, Default)]
pub struct GraphOptions {
    /// Component grouping depth for graph visualization.
    /// - 0/flat: No grouping (flat graph, no clusters)
    /// - 1/crate: Crate level only
    /// - 2/module: Module level
    /// - 3/file: File level (default)
    #[arg(long = "component-depth", default_value = "3")]
    component_depth_num: usize,

    /// Number of top PageRank nodes to include (enables pagerank filtering).
    /// When set, only the top K most important nodes are shown.
    #[arg(long = "pagerank-top-k")]
    pub pagerank_top_k: Option<usize>,

    /// Generate architecture graph (data flow) instead of dependency graph.
    /// Architecture graph shows: param_type -> func -> return_type
    #[arg(long = "arch-graph")]
    pub architecture_graph: bool,

    /// Cluster modules by their parent crate (for module-level graphs).
    /// Creates visual subgraphs grouping related modules together.
    #[arg(long = "cluster-by-crate")]
    pub cluster_by_crate: bool,

    /// Use shortened labels (module name only, without crate prefix).
    /// Makes labels more compact for large graphs.
    #[arg(long = "short-labels")]
    pub short_labels: bool,
}

impl GraphOptions {
    /// Get the component depth as an enum
    pub fn component_depth(&self) -> ComponentDepth {
        ComponentDepth::from_number(self.component_depth_num)
    }
}

/// Common options for controlling processing behavior.
#[derive(Args, Debug, Clone, Default)]
pub struct ProcessingOptions {
    /// Process files in parallel (default: false for stable ordering).
    #[arg(long)]
    pub parallel: bool,

    /// Print IR during symbol resolution.
    #[arg(long = "print-ir", default_value = "false")]
    pub print_ir: bool,
}

/// Combined common options for test runners.
#[derive(Args, Debug, Clone, Default)]
pub struct CommonTestOptions {
    #[command(flatten)]
    pub graph: GraphOptions,

    #[command(flatten)]
    pub processing: ProcessingOptions,

    /// Keep the temporary project directory for inspection.
    #[arg(long = "keep-temps")]
    pub keep_temps: bool,

    /// Update expectation sections with current output (bless).
    #[arg(long)]
    pub update: bool,
}

impl GraphOptions {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn with_component_depth(mut self, depth: ComponentDepth) -> Self {
        self.component_depth_num = depth.as_number();
        self
    }

    pub fn with_pagerank_top_k(mut self, top_k: Option<usize>) -> Self {
        self.pagerank_top_k = top_k;
        self
    }
}

impl ProcessingOptions {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn with_parallel(mut self, parallel: bool) -> Self {
        self.parallel = parallel;
        self
    }

    pub fn with_print_ir(mut self, print_ir: bool) -> Self {
        self.print_ir = print_ir;
        self
    }
}