agpm_cli/templating/dependencies/
mod.rs

1//! Dependency handling for template context building.
2//!
3//! This module provides a two-phase architecture for resolving and building
4//! dependency data structures used in template rendering:
5//!
6//! # Architecture
7//!
8//! ## Extractors (`extractors.rs`)
9//!
10//! The extractor submodule handles **parsing and extraction** of dependency metadata
11//! from resource files:
12//!
13//! - **`DependencyExtractor` trait**: Core abstraction for accessing lockfile data,
14//!   caches, and project configuration
15//! - **`extract_dependency_custom_names()`**: Parses frontmatter to extract custom
16//!   alias names for dependencies (e.g., `name: my_helper` in YAML frontmatter)
17//! - **`extract_dependency_specs()`**: Extracts complete `DependencySpec` objects
18//!   including tool, flatten, and install fields
19//! - **Caching**: Uses `custom_names_cache` and `dependency_specs_cache` to avoid
20//!   repeated file I/O and parsing operations
21//!
22//! ## Builders (`builders.rs`)
23//!
24//! The builder submodule handles **data structure construction and rendering**:
25//!
26//! - **`build_dependencies_data()`**: Orchestrates dependency resolution, content
27//!   rendering, and context building for templates
28//! - **`add_custom_alias()`**: Mutates dependency maps to add custom name aliases
29//! - **Rendering**: Handles recursive template rendering with cycle detection
30//! - **Cache Management**: Manages render cache for already-processed dependencies
31//!
32//! # Separation of Concerns
33//!
34//! The split between extraction and building serves several purposes:
35//!
36//! 1. **Performance**: Extraction results are cached, avoiding repeated file I/O
37//! 2. **Clarity**: Parsing logic (extractors) is separate from data structure
38//!    construction (builders)
39//! 3. **Testability**: Each phase can be tested independently
40//! 4. **File Size**: Keeps each module under 650 lines vs 1200+ line monolith
41//!
42//! # Usage
43//!
44//! This module is primarily used by `crate::templating::context::TemplateContextBuilder`,
45//! which implements the `DependencyExtractor` trait and delegates to these submodules:
46//!
47//! ```text
48//! TemplateContextBuilder
49//!   ├─> extract_dependency_custom_names()  [extractors.rs]
50//!   ├─> extract_dependency_specs()         [extractors.rs]
51//!   └─> build_dependencies_data()          [builders.rs]
52//!         └─> renders dependencies recursively
53//! ```
54//!
55//! # Caching Strategy
56//!
57//! Two levels of caching improve performance:
58//!
59//! - **Custom Names Cache**: Maps `ResourceId` → `BTreeMap<dep_ref, custom_name>`
60//!   - Avoids re-parsing frontmatter for custom name extraction
61//!   - Invalidated when resource content changes (via checksum)
62//!
63//! - **Dependency Specs Cache**: Maps `ResourceId` → `BTreeMap<dep_ref, DependencySpec>`
64//!   - Avoids re-parsing frontmatter for full spec extraction
65//!   - Includes tool, flatten, install, and template_vars fields
66//!
67//! - **Render Cache**: Maps `RenderCacheKey` → `String`
68//!   - Avoids re-rendering already-processed dependency content
69//!   - Includes tool, commit hash, and variant hash in cache key
70//!
71//! # Usage
72//!
73//! This module is primarily used by `crate::templating::context::TemplateContextBuilder`,
74//! which implements the `DependencyExtractor` trait and delegates to these submodules:
75//!
76//! ```text
77//! TemplateContextBuilder
78//!   ├─> extract_dependency_custom_names()  [extractors.rs]
79//!   ├─> extract_dependency_specs()         [extractors.rs]
80//!   └─> build_dependencies_data()          [builders.rs]
81//!         └─> renders dependencies recursively
82//! ```
83
84pub mod builders;
85pub mod extractors;
86
87// Re-export the main trait and helper functions for external use
88pub(crate) use builders::build_dependencies_data;
89pub(crate) use extractors::DependencyExtractor;