Profile System
This skill explains how the profile-based configuration system works in the dotfiles project.
Overview
Profiles control which files are checked out and which configuration sections are processed. This allows a single repository to support multiple environments (Linux headless, Linux desktop, Windows) while only checking out relevant files.
How Profiles Work
- •Sparse Checkout: Git sparse checkout excludes files based on categories defined in
conf/manifest.ini. This reduces disk usage and clutter by only checking out files relevant to the selected profile. - •Section Filtering: Configuration files use section headers that match profiles to determine which items to process
- •Automatic Installation: All components defined in active profile sections are automatically installed
- •Persistence: Selected profile is saved in
.git/configfor automatic reuse on subsequent runs
Available Profiles
- •
base: Minimal core shell configuration (excludes OS-specific and desktop files) - •
arch: Arch Linux headless (includes Arch packages, excludes desktop) - •
arch-desktop: Arch Linux desktop (includes desktop tools, window manager, fonts) - •
desktop: Generic Linux desktop (includes desktop tools like VS Code without OS-specific packages) - •
windows: Windows environment (PowerShell, registry settings)
Auto-Detection Overrides
IMPORTANT: System detection always takes precedence over profile configuration to prevent incompatible operations:
- •Non-Arch Linux systems: Always exclude
archcategory regardless of selected profile - •Linux systems: Always exclude
windowscategory regardless of selected profile
These overrides ensure compatibility even if an incompatible profile is manually selected.
Profile Selection Priority
When running dotfiles.sh, the profile is determined in this order:
- •Explicit CLI argument:
--profile arch-desktop(highest priority) - •Persisted profile: Reads from
.git/config(dotfiles.profilekey) - •Interactive prompt: If neither exists, prompts user to select from available profiles
Example usage:
# First time - interactive selection ./dotfiles.sh -I # Prompts: "Select profile (1-4): " # Selection is saved to .git/config # Subsequent runs - uses saved profile ./dotfiles.sh -I # No prompt, uses persisted profile # Override saved profile ./dotfiles.sh -I --profile base # Uses 'base' and updates saved profile
Profile Persistence Implementation
Profile persistence uses git config:
- •Save:
git config --local dotfiles.profile <profile_name> - •Read:
git config --local --get dotfiles.profile - •Location:
.git/config(not committed, local to repository clone)
See src/linux/utils.sh for implementation:
- •
get_persisted_profile(): Reads saved profile - •
persist_profile(): Saves profile - •
prompt_profile_selection(): Interactive selection UI - •
list_available_profiles(): Reads fromconf/profiles.ini
Adding New Profiles
- •Add profile definition to
conf/profiles.ini:ini[my-profile] include= exclude=windows,desktop
- •Use with
--profile my-profileor select interactively
Adding Configuration Items
When adding packages, units, or other configuration:
- •Add to appropriate INI file under the correct section using comma-separated categories
- •Single category:
[arch]for Arch-only items - •Multiple categories:
[arch,desktop]for items requiring BOTH Arch AND desktop
- •Single category:
- •Item will be automatically processed when ALL required categories are active
- •No flags needed - profile determines what gets installed
Section Naming Convention
Important Distinction:
- •Profile names (in
profiles.inionly): Use hyphens like[arch-desktop] - •Section names (all other .ini files): Use comma-separated categories like
[arch,desktop]- •Comma-separated sections mean ALL categories must be active (logical AND)
- •Example:
[arch,desktop]is processed only when botharchanddesktopare not excluded
Profile Filtering in Code
Linux (Shell)
Use should_include_profile_tag() to check if a section should be processed:
if should_include_profile_tag "$section"; then # Process this section fi
Windows (PowerShell)
Use Test-ShouldIncludeSection to check if a section should be processed:
if (Test-ShouldIncludeSection -SectionName $section -ExcludedCategories $excludedCategories) {
# Process this section
}
Rules
- •Profile selection priority: CLI argument > persisted profile > interactive prompt
- •System detection always overrides profile configuration for compatibility
- •Profile names use hyphens (e.g.,
arch-desktop) - •Section names in config files use comma-separated categories (e.g.,
arch,desktop) - •Comma-separated sections require ALL categories to be active (logical AND)
- •Selected profile is persisted to
.git/configfor reuse - •Always use helper functions for profile filtering (
should_include_profile_tag,Test-ShouldIncludeSection) - •Configuration items are automatically installed based on active profile sections