Skip to content

Configuration

Utsob Roy edited this page Nov 28, 2025 · 9 revisions

Configuration

DotR uses a config.toml file to manage your dotfiles configuration. This file is automatically created when you run dotr init and contains all the information needed to track, deploy, and update your dotfiles.

Configuration File Structure

The config.toml file has three main sections:

banner = true

[prompts]
GIT_EMAIL = "Enter your git email address"

[variables]
EDITOR = "vim"
SHELL = "/bin/zsh"

[packages.f_bashrc]
src = "dotfiles/f_bashrc"
dest = "~/.bashrc"

[packages.d_nvim]
src = "dotfiles/d_nvim"
dest = "~/.config/nvim"
dependencies = ["f_vimrc"]
ignore = ["*.log", "node_modules/", "cache/*"]
symlink = false

Configuration Options

Banner

banner = true

Controls whether DotR displays a banner when running commands. Set to true or false.

Prompts

[prompts]
GIT_EMAIL = "Enter your git email address"
GIT_NAME = "Enter your full name"
API_KEY = "Enter your API key"

Prompts allow you to interactively collect values during deployment, update, or diff operations. They are especially useful for:

  • Sensitive data - API keys, tokens, passwords
  • Machine-specific values - Email addresses, paths, usernames
  • Environment-specific credentials - Different values for work vs home

Key Features:

  • Prompts are displayed when the variable is not found in .uservariables.toml
  • User input is automatically saved to .uservariables.toml (gitignored)
  • Values are reused on subsequent runs - no re-prompting
  • Available at three levels: config-level, package-level, and profile-level
  • Only prompts relevant to the current deployment are shown

See the Prompts section below for detailed usage.

Variables

Variables allow you to define custom values that can be used in your templated dotfiles. DotR supports five types of variables with different precedence levels:

  1. Environment variables - Automatically available (lowest precedence)
  2. Config variables - Defined in config.toml (low precedence)
  3. Package variables - Defined per package in config.toml (middle-low precedence)
  4. Profile variables - Defined per profile in config.toml (middle-high precedence)
  5. User variables - Defined in .uservariables.toml (highest precedence)

Config Variables (config.toml)

Variables in config.toml are tracked in version control and shared across machines:

[variables]
EDITOR = "vim"
SHELL = "/bin/zsh"
TERMINAL = "alacritty"

User Variables (.uservariables.toml)

User variables are machine-specific and automatically gitignored. Use them for sensitive data or local overrides:

.uservariables.toml:

# Machine-specific or sensitive variables
SECRET_KEY = "my-secret-key"
API_TOKEN = "token-12345"
DATABASE_PASSWORD = "password123"

# Override config variables for this machine
EDITOR = "nvim"  # Overrides config.toml value

Key Features:

  • Automatically created in .gitignore during dotr init
  • Overrides variables from config.toml and environment
  • Perfect for secrets, API keys, and machine-specific settings
  • Not saved to config.toml when you modify configuration

Complex Variables

Both config and user variables support arrays and nested tables:

[variables]
# Simple values
EDITOR = "nvim"
TERMINAL = "alacritty"

# Arrays
favorite_langs = ["Rust", "Python", "JavaScript"]
git_aliases = ["co", "st", "br"]

# Nested tables
[variables.git]
name = "John Doe"
email = "john@example.com"
signingkey = "ABC123"

[variables.paths]
home = "~"
config = "~/.config"
local = "~/.local"

Package Variables

Package variables are specific to individual packages and override config variables but not user variables:

[packages.nvim]
src = "dotfiles/nvim"
dest = "~/.config/nvim/"

[packages.nvim.variables]
PLUGIN_MANAGER = "lazy.nvim"
THEME = "tokyonight"

[packages.nvim.variables.lsp]
enabled = true
servers = ["rust-analyzer", "pyright", "tsserver"]

Key Features:

  • Scoped to a specific package only
  • Override config variables for that package
  • Support nested tables and arrays like config variables
  • Perfect for package-specific configuration
  • Available in templates and actions for that package

Use Cases:

  • Different themes for different applications
  • Package-specific paths or settings
  • Feature flags per package
  • Tool-specific configuration that varies by package

Variable Precedence

When the same variable is defined in multiple places:

User Variables (.uservariables.toml)  [Highest]
    ↓
Profile Variables (config.toml)
    ↓
Package Variables (config.toml)
    ↓
Config Variables (config.toml)
    ↓
Environment Variables                [Lowest]

Packages

Packages represent individual dotfiles or directories. Each package has a unique name and defines where files are stored in your repository (src) and where they should be deployed (dest).

Package Structure

[packages.package_name]
src = "dotfiles/package_name"    # Path in repository
dest = "~/path/to/destination"    # Deployment destination
skip = false                      # Optional: skip unless in profile or explicit
dependencies = ["other_package"]  # Optional dependencies
pre_actions = ["command1"]        # Optional pre-deployment actions
post_actions = ["command2"]       # Optional post-deployment actions

[packages.package_name.variables] # Optional package-specific variables
VAR_NAME = "value"

[packages.package_name.targets]   # Optional profile-specific destinations
profile_name = "~/alt/path"

Package Naming Convention

DotR automatically generates package names based on the file or directory you import:

  • Files are prefixed with f_

    • Example: .bashrcf_bashrc
    • Example: .vimrcf_vimrc
  • Directories are prefixed with d_

    • Example: nvim/d_nvim
    • Example: tmux/d_tmux

Special characters (., -) are replaced with underscores (_).

Custom Package Names:

You can override the automatic naming by using the --name or -n flag when importing:

# Auto-generated name: d_my_app
dotr import ~/.config/my-app

# Custom name: d_customname
dotr import ~/.config/my-app --name customname

# Another example
dotr import ~/.zshrc --name zsh_config
# Creates: f_zsh_config instead of f_zshrc

Custom names still get the appropriate prefix (f_ or d_) based on whether the path is a file or directory.

Package Properties

  • src (required): Relative path in your dotfiles repository where the configuration is stored
  • dest (required): Absolute or tilde-expanded path where the configuration should be deployed
  • skip (optional): If true, package is only deployed when explicitly specified or via profile dependencies (default: false)
  • dependencies (optional): Array of package names that this package depends on
  • pre_actions (optional): Array of shell commands to run before deploying the package
  • post_actions (optional): Array of shell commands to run after deploying the package
  • variables (optional): Table of package-specific variables
  • prompts (optional): Table of package-specific interactive prompts
  • ignore (optional): Array of glob patterns for files/directories to ignore during deployment
  • targets (optional): Table mapping profile names to alternative deployment destinations
  • symlink (optional): If true, deploys files to an intermediate location and creates a symlink at the destination (default: false)

Symlinking

The symlink field allows you to deploy files to an intermediate location (deployed/ directory in your repository) and create symlinks at the destination. This is useful for applications that modify their configuration files at runtime, allowing you to easily track changes.

[packages.d_vscode]
src = "dotfiles/d_vscode"
dest = "~/.config/Code/User"
symlink = true

How Symlink Mode Works:

  1. Files are deployed to deployed/<package_name> in your repository
  2. A symlink is created from the destination to deployed/<package_name>
  3. Templates are rendered in the deployed/ location
  4. Updates capture changes made by applications to the symlinked files

Import with Symlink:

# Import a file with symlink mode
dotr import ~/.config/Code/User --symlink

# The package will have symlink = true in config.toml

Benefits:

  • Track runtime changes: Applications that modify configs are reflected in your repository
  • Easy updates: Changes made by apps can be captured with dotr update
  • Clean separation: Keeps deployed/rendered files separate from source templates
  • No template re-rendering: Symlinks point to already-rendered templates

Example Workflow:

# Import VS Code settings with symlink
dotr import ~/.config/Code/User --name vscode --symlink

# Deploy creates deployed/d_vscode and symlinks ~/.config/Code/User -> deployed/d_vscode
dotr deploy -p d_vscode

# VS Code modifies settings
code  # Make changes in VS Code

# Update captures the changes back to your repository
dotr update -p d_vscode

Use Cases:

# VS Code - captures extension changes, keybindings
[packages.d_vscode]
src = "dotfiles/d_vscode"
dest = "~/.config/Code/User"
symlink = true

# Applications that auto-update configs
[packages.d_app]
src = "dotfiles/d_app"
dest = "~/.config/app"
symlink = true
ignore = ["cache/", "*.log"]  # Still works with symlinks

Notes:

  • The deployed/ directory should be added to .gitignore (rendered templates, not sources)
  • Symlinks work best with applications that modify their own configs
  • Templates are still supported - they're rendered once during deployment
  • Use --dry-run to preview symlink creation without making changes
  • Symlinks are only created on Unix-like systems (macOS, Linux)

Ignore Patterns

The ignore field allows you to exclude files and directories from deployment using glob patterns. This is useful for excluding temporary files, logs, caches, or platform-specific files.

[packages.d_nvim]
src = "dotfiles/d_nvim"
dest = "~/.config/nvim"

# Ignore log files, node_modules, and cache directory
ignore = [
    "*.log",           # All .log files
    "*.tmp",           # All .tmp files
    "node_modules/",   # node_modules directory
    "cache/*",         # Everything in cache directory
    ".DS_Store",       # macOS metadata
    "*.swp",           # Vim swap files
]

Glob Pattern Examples:

  • *.log - Matches all files ending with .log
  • *.tmp - Matches all files ending with .tmp
  • node_modules/ - Matches the node_modules directory
  • cache/* - Matches all files and directories inside cache
  • test_* - Matches files starting with test_
  • **/*.pyc - Matches all .pyc files in any subdirectory
  • .DS_Store - Matches specific filename

How Ignore Works:

  1. During deployment: Ignored files are skipped when copying from repository to destination
  2. During backup: Ignored files are skipped when backing up existing configurations
  3. During diff: Ignored files are not included in the diff output
  4. Relative paths: Patterns are matched against paths relative to the package root

Common Use Cases:

# IDE/Editor files
[packages.d_project]
ignore = [".idea/", ".vscode/", "*.swp", "*.swo", "*~"]

# Build artifacts and dependencies
[packages.d_webapp]
ignore = ["node_modules/", "dist/", "build/", "*.pyc", "__pycache__/"]

# Logs and temporary files
[packages.d_app]
ignore = ["*.log", "*.tmp", "cache/", "temp/"]

# Platform-specific files
[packages.d_config]
ignore = [".DS_Store", "Thumbs.db", "desktop.ini"]

# Sensitive data
[packages.d_secrets]
ignore = ["*.key", "*.pem", ".env.local"]

Dependencies

Dependencies ensure that related packages are deployed together. When you deploy a package with dependencies, DotR automatically includes all dependent packages.

[packages.f_bashrc]
src = "dotfiles/f_bashrc"
dest = "~/.bashrc"
dependencies = ["f_bash_aliases", "f_bash_functions"]

Profiles

Profiles enable environment-specific configurations, allowing you to have different settings for work, home, servers, or any other environment.

[profiles.work]
dependencies = ["f_bashrc", "d_nvim", "f_gitconfig"]

[profiles.work.variables]
GIT_EMAIL = "work@company.com"
THEME = "professional"

[profiles.home]
dependencies = ["f_bashrc", "d_nvim", "d_gaming"]

[profiles.home.variables]
GIT_EMAIL = "personal@email.com"
THEME = "colorful"

Profile Properties:

  • dependencies: Array of package names to deploy when using this profile
  • variables: Profile-specific variables that override package and config variables
  • prompts: Profile-specific interactive prompts for environment-specific values

See the Profiles page for detailed documentation.

Prompts

Prompts allow you to interactively collect sensitive or machine-specific values during deployment. DotR supports prompts at three levels: config, package, and profile.

How Prompts Work

  1. First Run: When you run deploy, update, or diff, DotR checks for missing variables
  2. Interactive Input: For any variable not in .uservariables.toml, you'll see a prompt:
    Enter your AWS Access Key ID
    >>> 
    
  3. Automatic Save: Your input is saved to .uservariables.toml (automatically gitignored)
  4. Reuse Values: On subsequent runs, saved values are reused - no re-prompting needed
  5. Smart Hierarchy: Only prompts relevant to the current deployment are shown

Config-Level Prompts

Global prompts for values used across multiple packages:

[prompts]
GIT_EMAIL = "Enter your git email address"
GIT_NAME = "Enter your full name"
EDITOR = "Enter your preferred editor (vim/nvim/emacs)"

These prompts apply to all packages and profiles.

Package-Level Prompts

Package-specific prompts for sensitive configuration:

[packages.aws_cli]
src = "dotfiles/aws"
dest = "~/.aws/"

[packages.aws_cli.prompts]
AWS_ACCESS_KEY_ID = "Enter your AWS Access Key ID"
AWS_SECRET_ACCESS_KEY = "Enter your AWS Secret Access Key"
AWS_REGION = "Enter your default AWS region (e.g., us-east-1)"

[packages.slack]
src = "dotfiles/slack"
dest = "~/.config/slack/"

[packages.slack.prompts]
SLACK_API_TOKEN = "Enter your Slack API token"
SLACK_WORKSPACE = "Enter your Slack workspace URL"

Package prompts only appear when deploying that specific package.

Profile-Level Prompts

Environment-specific prompts for different profiles:

[profiles.work]
dependencies = ["aws_cli", "slack", "vpn"]

[profiles.work.prompts]
WORK_EMAIL = "Enter your work email"
VPN_PASSWORD = "Enter your VPN password"
JIRA_TOKEN = "Enter your Jira API token"

[profiles.home]
dependencies = ["personal_git"]

[profiles.home.prompts]
PERSONAL_EMAIL = "Enter your personal email"
GITHUB_TOKEN = "Enter your GitHub personal access token"

Profile prompts only appear when deploying with that profile.

Prompt Hierarchy

When the same prompt is defined at multiple levels:

Profile Prompts (active profile)  [Highest]
     ↓
Package Prompts (deployed packages)
     ↓
Config Prompts                    [Lowest]

If a profile defines a prompt, it overrides config-level prompts. Package prompts are merged with config and profile prompts.

Use Cases

API Keys & Tokens:

[prompts]
GITHUB_TOKEN = "Enter your GitHub personal access token"
OPENAI_API_KEY = "Enter your OpenAI API key"

Email Addresses:

[profiles.work.prompts]
EMAIL = "Enter your work email"

[profiles.home.prompts]
EMAIL = "Enter your personal email"

Machine-Specific Paths:

[prompts]
WORKSPACE_DIR = "Enter your workspace directory path"
PROJECT_ROOT = "Enter your projects root directory"

Credentials:

[packages.database.prompts]
DB_USER = "Enter database username"
DB_PASSWORD = "Enter database password"
DB_HOST = "Enter database host"

Example Workflow

config.toml:

[prompts]
GIT_NAME = "Enter your full name"

[packages.gitconfig]
src = "dotfiles/gitconfig"
dest = "~/.gitconfig"

[packages.gitconfig.prompts]
GIT_EMAIL = "Enter your git email"

[profiles.work.prompts]
WORK_VPN = "Enter work VPN password"

First Deploy:

$ dotr deploy --profile work

Enter your full name
>>> John Doe

Enter your git email
>>> john.doe@example.com

Enter work VPN password
>>> ********

[INFO] Saved prompts to .uservariables.toml
[INFO] Deploying package 'gitconfig'...

Subsequent Deploys:

$ dotr deploy --profile work

[INFO] Using saved values from .uservariables.toml
[INFO] Deploying package 'gitconfig'...

Best Practices

  1. Use prompts for secrets - Keep API keys and passwords out of version control
  2. Config-level for common values - Email, name, editor preferences
  3. Package-level for package-specific - Database credentials, API keys for specific services
  4. Profile-level for environments - Work vs home credentials, different tokens per environment
  5. Clear prompt messages - Include examples or expected formats in the prompt text
  6. Document prompts in README - Let users know what values they'll need to provide
  7. Never commit .uservariables.toml - It's gitignored by default, keep it that way
  8. Use descriptive variable names - Makes templates and configs easier to understand

Example Configuration

Here's a complete example showing common dotfile configurations:

banner = true

[variables]
EDITOR = "nvim"
SHELL = "/bin/zsh"
TERMINAL = "alacritty"

# Shell configurations
[packages.f_bashrc]
src = "dotfiles/f_bashrc"
dest = "~/.bashrc"

[packages.f_zshrc]
src = "dotfiles/f_zshrc"
dest = "~/.zshrc"

[packages.f_bash_aliases]
src = "dotfiles/f_bash_aliases"
dest = "~/.bash_aliases"

# Editor configurations
[packages.d_nvim]
src = "dotfiles/d_nvim"
dest = "~/.config/nvim"
dependencies = ["f_vimrc"]

# Ignore logs, caches, and plugin lock files
ignore = [
    "*.log",
    ".cache/",
    "plugin/packer_compiled.lua",
    "lazy-lock.json"
]

[packages.f_vimrc]
src = "dotfiles/f_vimrc"
dest = "~/.vimrc"

# Git configuration
[packages.f_gitconfig]
src = "dotfiles/f_gitconfig"
dest = "~/.gitconfig"

# Terminal configurations
[packages.d_tmux]
src = "dotfiles/d_tmux"
dest = "~/.config/tmux"
post_actions = ["tmux source-file ~/.config/tmux/tmux.conf"]

[packages.d_alacritty]
src = "dotfiles/d_alacritty"
dest = "~/.config/alacritty"

# Neovim with package variables
[packages.d_nvim]
src = "dotfiles/d_nvim"
dest = "~/.config/nvim"
dependencies = ["f_vimrc"]
post_actions = [
    "echo 'Installing {{ PLUGIN_MANAGER }}...'",
    "nvim --headless +PluginInstall +qall"
]

[packages.d_nvim.variables]
PLUGIN_MANAGER = "lazy.nvim"
THEME = "tokyonight"

Working with Configuration

Viewing Variables

To see all available variables (including environment variables and complex structures):

dotr print-vars

This displays all variables with proper formatting for nested structures:

User Variables:
  EDITOR = vim
  HOME = /Users/username
  git =
    name = John Doe
    email = john@example.com
  favorite_langs = [
    - Rust
    - Python
    - JavaScript
  ]

Manual Configuration Editing

You can manually edit config.toml to:

  • Add or modify variables
  • Update package paths
  • Add dependencies between packages
  • Change deployment destinations

After making manual changes, ensure your TOML syntax is valid. DotR will validate the configuration on the next command.

Importing Packages

The import command adds existing configuration files or directories to your dotfiles repository:

# Basic import
dotr import ~/.bashrc

# Import a directory
dotr import ~/.config/nvim

# Import with a custom package name
dotr import ~/.config/my-complex-app-name --name myapp

# Import for a specific profile
dotr import ~/.ssh/config --profile work

Import Command Options:

dotr import <IMPORT_PATH> [OPTIONS]

Arguments:
  <IMPORT_PATH>  Path to the file or directory to import

Options:
  -s, --symlink                    Import with symlink mode enabled
  -n, --name <NAME>                Custom package name (without prefix)
  -p, --profile <PROFILE>          Associate with a specific profile
  -w, --working-dir <WORKING_DIR>  Specify working directory
  -h, --help                       Print help

Deploy Command Options:

dotr deploy [OPTIONS]

Options:
  -p, --packages [<PACKAGES>...]   Specify which packages to deploy
  -P, --profile <PROFILE>          Use a specific profile
      --ignore-errors              Continue operation even if errors occur
      --clean                      Remove files in destination not present in source
  -w, --working-dir <WORKING_DIR>  Specify working directory
  -h, --help                       Print help

Update Command Options:

dotr update [OPTIONS]

Options:
  -p, --packages [<PACKAGES>...]   Specify which packages to update
  -P, --profile <PROFILE>          Use a specific profile
      --ignore-errors              Continue operation even if errors occur
      --clean                      Remove files in destination not present in source
  -w, --working-dir <WORKING_DIR>  Specify working directory
  -h, --help                       Print help

Diff Command Options:

dotr diff [OPTIONS]

Options:
  -p, --packages [<PACKAGES>...]   Specify which packages to diff
  -P, --profile <PROFILE>          Use a specific profile
      --ignore-errors              Continue operation even if errors occur
  -w, --working-dir <WORKING_DIR>  Specify working directory
  -h, --help                       Print help

Flag Details:

  • --clean: When enabled, removes any files in the destination that don't exist in the source. This ensures the deployed configuration exactly matches your repository. Available for deploy and update commands.

    # Remove extra files in ~/.config/nvim that aren't in your repository
    dotr deploy -p d_nvim --clean
    
    # Clean deploy all packages
    dotr deploy --clean
    
    # Clean update (backup with cleanup)
    dotr update --clean

    Use cases:

    • Clean up leftover files from previous configurations
    • Ensure deployed configs exactly match repository state
    • Remove old plugin files or deprecated configurations
    • Remove temporary or generated files that shouldn't persist

    How it works:

    • For deploy: Removes files in deployment destination not present in repository
    • For update: Removes files in repository not present in deployment destination
    • Respects ignore patterns - ignored files won't be deleted
    • Skips backup files (.dotrbak extension)
    • Removes empty directories after cleanup

    Warning: Be careful with --clean as it will delete files. Always run dotr diff first to preview changes, or back up important data.

  • --ignore-errors: Continues deploying/updating/diffing remaining packages even if one package fails. Useful when you want to process as many packages as possible despite errors. Available for deploy, update, and diff commands.

    # Deploy all packages, continuing even if some fail
    dotr deploy --ignore-errors
    
    # Update with error tolerance
    dotr update --ignore-errors --profile work
    
    # Diff all packages, showing errors but continuing
    dotr diff --ignore-errors

    Use cases:

    • Deploying to a new machine where some packages may not be compatible
    • Batch operations where you want to see all errors at once
    • CI/CD pipelines where partial success is acceptable
    • Testing configurations across multiple packages

    At the end of the operation, DotR displays statistics showing how many packages succeeded, failed, or had no changes.

Package Management Commands

List Packages:

View all managed packages in your configuration.

# List all packages
dotr packages list

# List with verbose output (shows src, dest, dependencies)
dotr packages list --verbose

# List packages for a specific profile
dotr packages list --profile work

Package Subcommands:

The packages command provides a convenient way to manage packages with a consistent interface:

# All package operations can be done through the packages command
dotr packages import ~/.config/app
dotr packages deploy -p d_nvim
dotr packages update -p d_nvim
dotr packages diff -p d_nvim
dotr packages remove d_nvim

These are equivalent to the top-level commands (dotr import, dotr deploy, etc.) but provide better organization and discoverability.

Remove Packages:

Remove packages from your configuration and optionally clean up orphaned packages.

# Remove a single package
dotr remove f_bashrc

# Remove multiple packages
dotr remove f_bashrc d_nvim f_gitconfig

# Remove with force (skip confirmation)
dotr remove f_bashrc --force

# Remove and clean up orphaned packages (packages no longer in any profile)
dotr remove f_bashrc --remove-orphans

# Preview removal without making changes
dotr remove f_bashrc --dry-run

# Remove for a specific profile
dotr remove f_bashrc --profile work

Remove Options:

  • --force: Skip confirmation prompts
  • --remove-orphans: Also remove packages that are no longer referenced by any profile
  • --dry-run: Preview what would be removed without making changes
  • --profile: Remove from a specific profile's dependencies

How Remove Works:

  1. Removes package entry from config.toml
  2. Removes from profile dependencies (if --profile is specified)
  3. Optionally removes orphaned packages (if --remove-orphans is specified)
  4. Does NOT delete files from repository or deployment locations (manual cleanup required)

Example Workflow:

# Preview what will be removed
dotr remove d_old_config --dry-run

# Remove the package
dotr remove d_old_config

# Check for orphaned packages
dotr packages list

# Remove multiple packages and clean up orphans
dotr remove d_config1 d_config2 --remove-orphans

Profile Management Commands

List Profiles:

View all configured profiles.

# List all profiles
dotr profiles list

# List with verbose output (shows dependencies and variables)
dotr profiles list --verbose

Add Profiles:

Create new profiles for different environments.

# Add a new profile
dotr profiles add staging

# Add and set as current profile (uses DOTR_PROFILE environment variable)
dotr profiles add production --set-as-current

# After adding, edit config.toml to configure dependencies and variables

Remove Profiles:

Remove profiles from your configuration.

# Remove a profile
dotr profiles remove staging

# Remove and clean up orphaned packages
dotr profiles remove staging --remove-orphans

# Preview removal without making changes
dotr profiles remove staging --dry-run

Profile Management Options:

  • --set-as-current (add): Sets the new profile as the current profile for the session
  • --remove-orphans (remove): Also removes packages no longer referenced by any profile
  • --dry-run (remove): Preview what would be removed without making changes

How Profile Management Works:

  1. Add: Creates a new profile entry in config.toml with empty dependencies
  2. Remove: Removes profile entry and optionally cleans up orphaned packages
  3. List: Shows all profiles with optional details about dependencies and variables

Example Workflow:

# Create a new staging environment
dotr profiles add staging

# Edit config.toml to add dependencies and variables
# [profiles.staging]
# dependencies = ["f_bashrc", "d_nvim"]
# [profiles.staging.variables]
# ENV = "staging"

# Deploy with the new profile
dotr deploy --profile staging

# Later, remove the profile
dotr profiles remove staging --remove-orphans

How Import Works:

  1. Creates package entry in config.toml with auto-generated or custom name
  2. Backs up existing file if already in repository (with .dotrbak extension)
  3. Copies file to repository under dotfiles/ directory
  4. Adds to profile if --profile is specified

Naming Examples:

# Auto-generated names
dotr import ~/.bashrc          # → f_bashrc
dotr import ~/.config/nvim     # → d_nvim
dotr import ~/.my-app.conf     # → f_my_app_conf

# Custom names
dotr import ~/.bashrc --name shell_config        # → f_shell_config
dotr import ~/.config/nvim --name editor         # → d_editor
dotr import ~/.my-app.conf --name application    # → f_application

When to Use Custom Names:

  • Simplify package names: --name editor instead of auto-generated d_my_very_long_editor_name
  • Organize related configs: Multiple configs can use meaningful names like f_work_ssh, f_personal_ssh
  • Avoid naming conflicts: If you have multiple similar config files
  • Better readability: d_shell is clearer than d_zsh when you support multiple shells

Path Resolution

DotR supports multiple path formats:

  • Tilde expansion: ~/.config/nvim expands to your home directory
  • Absolute paths: /etc/config
  • Relative paths: src/config (resolved from working directory)

Repository Structure

When you initialize a DotR repository, the following structure is created:

.
├── config.toml          # Main configuration file
├── .gitignore          # Ignores .uservariables.toml
├── .uservariables.toml # User-specific variables (not tracked)
└── dotfiles/           # Your dotfiles are stored here
    ├── f_bashrc
    ├── f_zshrc
    ├── d_nvim/
    │   ├── init.lua
    │   └── lua/
    └── d_tmux/
        ├── tmux.conf
        └── theme.conf

Best Practices

  1. Use config variables for settings shared across machines (themes, default editors)
  2. Use package variables for package-specific settings (plugin managers, themes per app)
  3. Use profile variables for environment-specific settings (work vs home emails, paths)
  4. Use prompts for interactive collection of secrets and credentials
  5. Use user variables for machine-specific or sensitive data (API keys, local paths)
  6. Use custom names when importing to create meaningful, readable package names
  7. Use ignore patterns to exclude temporary files, logs, caches, and build artifacts
  8. Set up dependencies for related configurations (shell configs, editor plugins)
  9. Use actions for post-deployment setup (installing plugins, reloading services)
  10. Use profiles to organize configurations for different environments
  11. Never commit .uservariables.toml to version control
  12. Document user variables in your README so you know what to set up on new machines

Backup Files

When deploying dotfiles, DotR automatically creates backups with the .dotrbak extension:

  • Files: ~/.bashrc~/.bashrc.dotrbak
  • Directories (granular): Individual files within directories get .dotrbak extensions (e.g., init.lua.dotrbak)

Granular Changes (v0.13.0+):

  • Only files with actual content changes are deployed and backed up
  • Unchanged files are skipped, making deployments faster and avoiding unnecessary backup clutter
  • Use the diff command to preview exactly what will change before deploying

This ensures you can always restore your previous configuration if needed.