pub struct DependencyResolver { /* private fields */ }Expand description
Main dependency resolver with service-based architecture.
This orchestrates multiple specialized services to handle different aspects of the dependency resolution process while maintaining compatibility with existing interfaces.
§Architecture
The resolver follows a modular service pattern where each complex aspect of resolution is delegated to a specialized service:
VersionResolutionServicehandles Git operations and batch SHA resolutionPatternExpansionServiceexpands glob patterns into concrete dependencies- Version conflict detection identifies and reports version conflicts
§Resolution Process
The resolution occurs in distinct phases:
- Collection Phase: Extract dependencies from the project manifest
- Version Resolution Phase: Batch resolve all version constraints to commit SHAs
- Pattern Expansion Phase: Expand glob patterns (e.g.,
agents/*.md) into individual resources - Transitive Resolution Phase (optional): Resolve dependencies declared within resources
- Conflict Detection Phase: Detect and report version conflicts across the dependency graph
§Examples
use agpm_cli::resolver::DependencyResolver;
use agpm_cli::manifest::Manifest;
use agpm_cli::cache::Cache;
// Load manifest and create cache
let manifest = Manifest::load_from_file("agpm.toml")?;
let cache = Cache::new()?;
// Create resolver and resolve dependencies
let mut resolver = DependencyResolver::new(manifest, cache).await?;
let lockfile = resolver.resolve().await?;
println!("Resolved {} dependencies", lockfile.total_resources());§Key Features
- Parallel Processing: Configurable concurrency for performance
- SHA-based Deduplication: Shared worktrees for identical commits
- Transitive Dependencies: Optional resolution of dependencies of dependencies
- Version Constraints: Support for semver-style constraints (
^1.0,~2.1) - Pattern Support: Glob patterns for bulk dependency inclusion
- Conflict Detection: Comprehensive detection of version conflicts
§Related Services
VersionResolutionService: Git operations and SHA resolutionPatternExpansionService: Glob pattern handling- Service container for transitive resolution (transitive_resolver::ResolutionServices)
- Version conflict detection and reporting (conflict_detector::ConflictDetector)
Implementations§
Source§impl DependencyResolver
impl DependencyResolver
Sourcepub async fn new_with_context(
manifest: Manifest,
cache: Cache,
operation_context: Option<Arc<OperationContext>>,
) -> Result<Self>
pub async fn new_with_context( manifest: Manifest, cache: Cache, operation_context: Option<Arc<OperationContext>>, ) -> Result<Self>
Sourcepub async fn new_with_global(manifest: Manifest, cache: Cache) -> Result<Self>
pub async fn new_with_global(manifest: Manifest, cache: Cache) -> Result<Self>
Create a new resolver with global configuration support.
This loads both manifest sources and global sources from ~/.agpm/config.toml.
§Arguments
manifest- Project manifest with dependenciescache- Cache for Git operations and worktrees
§Errors
Returns an error if global configuration cannot be loaded
Sourcepub async fn new_with_global_concurrency(
manifest: Manifest,
cache: Cache,
max_concurrency: Option<usize>,
operation_context: Option<Arc<OperationContext>>,
) -> Result<Self>
pub async fn new_with_global_concurrency( manifest: Manifest, cache: Cache, max_concurrency: Option<usize>, operation_context: Option<Arc<OperationContext>>, ) -> Result<Self>
Creates a new dependency resolver with global config and custom concurrency limit.
§Arguments
manifest- Project manifest with dependenciescache- Cache for Git operations and worktreesmax_concurrency- Optional concurrency limit for parallel operationsoperation_context- Optional context for warning deduplication
§Errors
Returns an error if global configuration cannot be loaded
Sourcepub async fn with_cache(manifest: Manifest, cache: Cache) -> Result<Self>
pub async fn with_cache(manifest: Manifest, cache: Cache) -> Result<Self>
Sourcepub async fn new_with_global_context(
manifest: Manifest,
cache: Cache,
operation_context: Option<Arc<OperationContext>>,
) -> Result<Self>
pub async fn new_with_global_context( manifest: Manifest, cache: Cache, operation_context: Option<Arc<OperationContext>>, ) -> Result<Self>
Create a new resolver with global configuration and operation context.
§Arguments
manifest- Project manifest with dependenciescache- Cache for Git operations and worktreesoperation_context- Optional context for warning deduplication
§Errors
Returns an error if global configuration cannot be loaded
Sourcepub fn core(&self) -> &ResolutionCore
pub fn core(&self) -> &ResolutionCore
Get a reference to the resolution core.
Sourcepub async fn resolve(&mut self) -> Result<LockFile>
pub async fn resolve(&mut self) -> Result<LockFile>
Resolve all dependencies and generate a complete lockfile.
Performs dependency resolution with automatic conflict detection and backtracking to find compatible versions when conflicts occur.
§Errors
Returns an error if any step of resolution fails
Sourcepub async fn resolve_with_options(
&mut self,
enable_transitive: bool,
progress: Option<Arc<MultiPhaseProgress>>,
) -> Result<LockFile>
pub async fn resolve_with_options( &mut self, enable_transitive: bool, progress: Option<Arc<MultiPhaseProgress>>, ) -> Result<LockFile>
Sourcepub async fn pre_sync_sources(
&mut self,
deps: &[(String, ResourceDependency)],
progress: Option<Arc<MultiPhaseProgress>>,
) -> Result<()>
pub async fn pre_sync_sources( &mut self, deps: &[(String, ResourceDependency)], progress: Option<Arc<MultiPhaseProgress>>, ) -> Result<()>
Sourcepub async fn update(
&mut self,
existing: &LockFile,
deps_to_update: Option<Vec<String>>,
progress: Option<Arc<MultiPhaseProgress>>,
) -> Result<LockFile>
pub async fn update( &mut self, existing: &LockFile, deps_to_update: Option<Vec<String>>, progress: Option<Arc<MultiPhaseProgress>>, ) -> Result<LockFile>
Update dependencies with existing lockfile and specific dependencies to update.
§Arguments
existing- Existing lockfile to updatedeps_to_update- Optional specific dependency names to update (None = all)progress- Optional multi-phase progress tracker for UI updates
§Current Implementation (MVP)
Currently performs full resolution regardless of deps_to_update value.
This is correct but not optimized - all dependencies are re-resolved even
when only specific ones are requested.
§Future Enhancement
Full incremental update would:
- Match
deps_to_updatenames to lockfile entries - Keep unchanged dependencies at their locked versions
- Re-resolve only specified dependencies to latest matching versions
- Re-extract transitive dependencies for updated resources
- Merge updated entries with unchanged entries from existing lockfile
- Detect and resolve any new conflicts
This requires significant changes to the resolution pipeline to support “pinned” versions alongside “latest” resolution.
§Errors
Returns an error if update process fails
Sourcepub fn operation_context(&self) -> Option<&Arc<OperationContext>>
pub fn operation_context(&self) -> Option<&Arc<OperationContext>>
Get current operation context if available.
Sourcepub fn set_operation_context(&mut self, context: Arc<OperationContext>)
pub fn set_operation_context(&mut self, context: Arc<OperationContext>)
Set the operation context for warning deduplication.
§Arguments
context- The operation context to use