pub fn compute_relative_install_path(
tool_root: &Path,
dep_path: &Path,
flatten: bool,
) -> PathBufExpand description
Computes the relative install path by removing redundant directory prefixes.
This function intelligently strips redundant path components when a dependency’s path
starts with the same directory name as the tool’s installation root. This prevents
duplicate directory names like .claude/agents/agents/example.md.
§Algorithm
- Extract the last component of the tool root (e.g.,
agentsfrom.claude/agents/) - Check if the dependency path starts with that same component (case-sensitive)
- If yes, strip that leading component from the dependency path
- If no, return the dependency path unchanged
§Arguments
tool_root- The base installation directory (e.g.,.claude/agents/)dep_path- The relative path from the dependency (e.g.,agents/example.md)
§Returns
The relative path to use for installation, with redundant prefixes removed.
§Examples
use agpm_cli::utils::platform::compute_relative_install_path;
use std::path::Path;
// Standard case: strip redundant prefix
let tool_root = Path::new(".claude/agents");
let dep_path = Path::new("agents/carrots/agent.md");
let result = compute_relative_install_path(tool_root, dep_path, false);
assert_eq!(result, Path::new("carrots/agent.md"));
// Flatten: use only filename
let tool_root = Path::new(".claude/agents");
let dep_path = Path::new("agents/carrots/agent.md");
let result = compute_relative_install_path(tool_root, dep_path, true);
assert_eq!(result, Path::new("agent.md"));
// No match: preserve full path
let tool_root = Path::new(".claude/agents");
let dep_path = Path::new("helpers/agent.md");
let result = compute_relative_install_path(tool_root, dep_path, false);
assert_eq!(result, Path::new("helpers/agent.md"));
// Custom target with different name
let tool_root = Path::new(".custom/my-stuff");
let dep_path = Path::new("agents/helper.md");
let result = compute_relative_install_path(tool_root, dep_path, false);
assert_eq!(result, Path::new("agents/helper.md")); // No stripping§Use Cases
- Installing resources from well-organized repositories
- Preventing
.claude/snippets/snippets/example.mdduplication - Working with custom installation targets
- Preserving intentional directory structures
- Flattening directory structures for agents and commands
§Design Rationale
This approach is more generic than hardcoded resource type stripping:
- Works with custom targets (e.g.,
.custom/my-agents/) - No dependency on resource type names
- Handles edge cases like single-file dependencies
- Respects intentional hierarchies (e.g.,
helpers/agent.mdpreserved) - Supports explicit flattening for resource types that don’t need nested directories