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;