-
-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture Overview
Understanding DotRun's design principles and system architecture
DotRun separates personal configurations from executable automation tools:
Personal Configs (dotfiles) Executable Tools (DotRun)
├── .bashrc ├── deployment scripts
├── .vimrc ├── development tools
├── .gitconfig ├── testing utilities
└── personal settings └── team automations
Why this matters:
- Personal configs remain private and customized
- Automation tools can be shared across teams
- No conflicts between personal preferences and team workflows
DotRun works alongside existing dotfile managers without interference:
Your Existing Setup + DotRun
├── yadm/chezmoi/stow # Manages personal configs
└── DotRun # Manages automation scripts
Collections use standard Git workflows for team collaboration:
Team Workflow
Developer A ──┐
Developer B ──┼─→ Git Repository ──→ Collection Import
Developer C ──┘
Tool Files (~/.local/share/dotrun/):
~/.local/share/dotrun/
├── dr # Main binary
├── collections.conf # Installed collections registry
└── shell/ # Shell-specific files
├── bash/
├── zsh/
└── fish/User Content (~/.config/dotrun/):
~/.config/dotrun/
├── collections/ # Persistent git clones of collections
│ ├── <collection-name >/
│ │ ├── .git/ # Full git repository
│ │ ├── dotrun.collection.yml # Collection metadata
│ │ ├── scripts/ # Collection scripts
│ │ ├── aliases/ # Collection aliases
│ │ ├── helpers/ # Collection helpers
│ │ └── configs/ # Collection configs
│
├── scripts/ # Imported (copied) scripts
├── aliases/ # Imported (copied) aliases
├── helpers/ # Imported (copied) helpers
├── configs/ # Imported (copied) configs
│
└── .dr-hashes/ # SHA256 tracking for imported files
└── <resource-basename >.sha256 # Original hash for modification detectionCollections Tracking Format (~/.local/share/dotrun/collections.conf):
# Format: name|repository|version|last_sync_timestamp
# Example:
dotrun | https://github.com/jvPalma/dotrun.git | 3.1.0 | 1729612800When you run dr script-name, DotRun searches in this order:
1. Personal Scripts
~/.config/dotrun/bin/script-name.sh
~/.config/dotrun/bin/*/script-name.sh
2. Collections (in import order)
~/.config/dotrun/collections/collection1/bin/script-name.sh
~/.config/dotrun/collections/collection2/bin/script-name.sh
3. Namespaced Scripts
collection-name/script-name
category/script-name
graph TD
A[dr script-name] --> B{Script exists?}
B -->|No| C[Show error + suggestions]
B -->|Yes| D[Check permissions]
D -->|Denied| E[Show permission error]
D -->|OK| F[Validate dependencies]
F -->|Missing| G[Show dependency error]
F -->|OK| H[Execute script]
H --> I[Return exit code]
The main executable handles:
- Command parsing and routing
- Script discovery and resolution
- Error handling and user feedback
- Shell completion generation
Key responsibilities:
# Command routing
dr set script-name → script_create()
dr script-name → script_execute()
dr collections list → collections_list()Handles personal script lifecycle:
Set → Test → Document → Share
↓ ↓ ↓ ↓
set run help export
Features:
- Template generation for new scripts
- In-place editing with
$EDITOR - Documentation co-location
- Script validation and linting
Manages team collaboration through Git-based collections:
Remote Repository → Local Import → Script Availability
↓ ↓ ↓
Git repo ~/.config/ dr collection/
with scripts dotrun/ script-name
collections/
Capabilities:
- Git repository cloning and updates
- Version management with tags/branches
- Dependency resolution between collections
- Conflict resolution for script names
Copy-Based vs Symlink Architecture
DotRun v3.1.0 uses a copy-based model:
Behavior:
- Import copies files from the collection clone into
~/.config/dotrun/{scripts,aliases,helpers,configs}/ - SHA256 hashes are recorded under
~/.config/dotrun/.dr-hashes/to detect local edits
Why Copy-Based:
- Users can safely edit imported files without touching the collection clone
- Updates become deterministic: hash match ⇒ safe to replace; hash mismatch ⇒ present choices
- Clear separation between collection repository and user workspace
Why Not Symlinks:
- Symlinks couple working state to the collection clone and complicate cross-platform behavior
- Local edits can unintentionally change the underlying repo or be blocked by permissions
- Harder to track which files have been customized
Hash Tracking Overview:
# On import:
cp "$source" "$dest"
echo "$(sha256sum "$dest" | awk '{print $1}')" >"$DR_CONFIG/.dr-hashes/$(basename "$dest").sha256"
# On update:
stored="$(cat "$DR_CONFIG/.dr-hashes/$(basename "$dest").sha256")"
current="$(sha256sum "$dest" | awk '{print $1}')"
[[ "$stored" == "$current" ]] && echo "unmodified" || echo "modified"Hash Store:
-
.dr-hashes/files are named after the destination file's basename - Hashes represent the last-imported content state used for change detection
Update Conflict Resolution:
- Unmodified (hash matches): update-in-place or skip, with optional diff preview
- Modified (hash differs): choose keep, overwrite, diff, or backup+overwrite
- New (in collection, not imported): import, view, or skip
Integrates documentation at multiple levels:
Script Level Collection Level
├── ### DOC sections ├── README.md
├── .md documentation ├── Category docs
└── Help generation └── Usage examples
Features:
- Inline help with
### DOCblocks - Rich markdown documentation
- Automatic help generation
- Beautiful rendering with
glow(if available)
Provides seamless shell experience:
Shell Features
├── Tab completion (bash/zsh/fish)
├── PATH integration (~/.local/bin)
├── Exit code propagation
└── Environment variable passing
User: dr set category/script-name
↓
1. Validate name and category
↓
2. Create directory structure
↓
3. Generate script template
↓
4. Create documentation template
↓
5. Open in $EDITOR
↓
6. Set executable permissions
User: dr -col add <repository-url>
↓
1. Resolve collection source
- Read from ~/.local/share/dotrun/collections.conf or user-specified repository
↓
2. Sync collection clone
- Clone or fetch into ~/.config/dotrun/collections/<name>/
- Checkout requested version or default branch/tag
↓
3. Discover resources
- Identify files under scripts/, aliases/, helpers/, configs/ within the collection clone
↓
4. Import with hash registration
- Copy each selected resource into ~/.config/dotrun/<namespace>/
- Compute SHA256 of the destination file
- Write hash to ~/.config/dotrun/.dr-hashes/<basename>.sha256
↓
5. Record install/upgrade
- Update ~/.local/share/dotrun/collections.conf with:
name|repository|version|last_sync_timestamp
↓
6. Post-import verification
- Validate resource visibility, permissions, and namespace collisions
Update Behavior:
- Unmodified (hash match): suggest update/diff/skip
- Modified (hash mismatch): suggest keep/overwrite/diff/backup
- New (in collection only): suggest import/view/skip
User: dr script-name args...
↓
1. Parse command line arguments
↓
2. Resolve script location
↓
3. Check script permissions
↓
4. Validate dependencies (if defined)
↓
5. Execute with arguments
↓
6. Propagate exit code
DotRun integrates with existing dotfile managers:
yadm Integration:
# Initialize yadm tracking
dr yadm-init
# Result: ~/.config/dotrun becomes part of your dotfiles
yadm add ~/.config/dotrun
yadm commit -m "Add DotRun scripts"chezmoi Integration:
# Add to chezmoi source
chezmoi add ~/.config/dotrun
# Template for team-specific scripts
{{ if eq .team "frontend" }}
dr import git@company.com/frontend-tools.git frontend
{{ end }}DotRun scripts integrate seamlessly with CI/CD pipelines:
# GitHub Actions example
- name: Setup DotRun
run: |
curl -fsSL https://raw.githubusercontent.com/jvPalma/dotrun/master/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Import project tools
run: dr import ${{ github.repository }}.git project
- name: Run deployment
run: dr project/deploy stagingScripts can run in containerized environments:
# Mount DotRun configuration
docker run -v ~/.config/dotrun:/dotrun:ro \
-v $(pwd):/workspace \
-w /workspace \
ubuntu:latest \
/dotrun/bin/build-script.sh- Scripts run with user permissions (no privilege escalation)
- No setuid/setgid binaries
- Scripts can request elevated permissions explicitly
Trust Levels
├── Personal Scripts (full trust)
├── Team Collections (team trust)
├── Public Collections (verify before use)
└── Unknown Collections (explicit approval)
- Script names validated against patterns
- Repository URLs validated before cloning
- File paths validated to prevent directory traversal
Cold start: ~50ms (script discovery + resolution)
Warm start: ~10ms (cached resolution)
Tab completion: ~100ms (full script enumeration)
- Script capacity: 1000+ scripts with minimal impact
- Collection capacity: 50+ collections efficiently managed
- Memory usage: ~5MB for typical usage
- Disk usage: Scales with number of scripts and collections
- Lazy loading: Collections loaded only when accessed
- Caching: Script locations cached for faster resolution
- Parallel operations: Collection updates run in parallel
- Minimal dependencies: Core functionality requires only bash
Shared utilities in ~/.config/dotrun/helpers/:
source "$DR_CONFIG/helpers/pkg.sh" # Package validation
source "$DR_CONFIG/helpers/log.sh" # Logging utilities
source "$DR_CONFIG/helpers/colors.sh" # Terminal colorsWhile not formally plugins, scripts can extend DotRun:
# Collection management scripts
dr set collections/update-all
dr set collections/validate-structure
# Development workflow scripts
dr set dev/create-feature-branch
dr set dev/run-pre-commit-checksScripts can implement DotRun-like subcommands:
# dr project deploy staging --verbose
# Implemented as: ~/.config/dotrun/bin/project.sh
case "$1" in
deploy)
shift
deploy_command "$@"
;;
test)
shift
test_command "$@"
;;
*) show_help ;;
esac- Configuration management: Global and per-collection config files
- Dependency graph: Automatic dependency resolution between scripts
- Remote execution: Execute scripts on remote machines
- Script marketplace: Central repository of public collections
- Core directory structure will remain stable
- Script execution interface will maintain compatibility
- New features will be additive, not breaking
DotRun's architecture reflects several key insights:
- Simplicity: Uses standard Unix tools and patterns
- Transparency: Everything is files and directories
- Composability: Works with existing tools and workflows
- Collaboration: Git-native sharing without complexity
- Performance: Fast enough for interactive use
This design enables DotRun to serve both individual developers seeking better script organization and large teams needing sophisticated automation workflows.
This architecture overview provides the foundation for understanding how DotRun works internally and how to extend it for your specific needs.