Files
lenovo-gentoo/Dotfiles-Management.md

812 lines
17 KiB
Markdown

# Dotfile Management with chezmoi
Complete guide to managing your dotfiles with chezmoi on this Gentoo workstation and across multiple machines.
## Table of Contents
- [Overview](#overview)
- [Quick Reference](#quick-reference)
- [Daily Workflow](#daily-workflow)
- [Adding New Tools](#adding-new-tools)
- [Editing Existing Configs](#editing-existing-configs)
- [Templates for Cross-Platform Configs](#templates-for-cross-platform-configs)
- [Syncing Across Machines](#syncing-across-machines)
- [Advanced Usage](#advanced-usage)
- [Troubleshooting](#troubleshooting)
---
## Overview
### What is chezmoi?
chezmoi is a cross-platform dotfile manager that allows you to:
- Keep your dotfiles in a git repository
- Sync configs across multiple machines (Gentoo, macOS, Ubuntu, etc.)
- Use templates for machine-specific configurations
- Manage secrets securely
- Automate setup on new machines
### Current Setup
**Dotfiles Repository**: `~/repository/git.hinrichs.dev/alexander/dotfiles`
- This is your main git repository
- Contains all your dotfiles and chezmoi configuration
- Pushed to your Gitea server
**Chezmoi Source Directory**: `~/.local/share/chezmoi`
- Git clone of your dotfiles repository
- Working directory for chezmoi
- Where you make changes before applying them
**Chezmoi Config**: `~/.config/chezmoi/chezmoi.yaml`
- Generated from `.chezmoi.yaml.tmpl`
- Contains your machine-specific values (name, email, work/personal, etc.)
### How It Works
```
┌─────────────────────────────────────────────────┐
│ 1. Edit dotfiles in chezmoi source │
│ chezmoi edit ~/.zshrc │
│ (edits ~/.local/share/chezmoi/dot_zshrc) │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ 2. Preview changes │
│ chezmoi diff │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ 3. Apply to home directory │
│ chezmoi apply │
│ (copies to ~/.zshrc) │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ 4. Commit and push │
│ chezmoi cd │
│ git add . && git commit && git push │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ 5. Pull on other machines │
│ chezmoi update │
└─────────────────────────────────────────────────┘
```
---
## Quick Reference
| Task | Command |
|------|---------|
| Edit dotfile | `chezmoi edit ~/.zshrc` |
| Preview changes | `chezmoi diff` |
| Apply changes | `chezmoi apply` |
| Add new file | `chezmoi add ~/.newfile` |
| Go to source dir | `chezmoi cd` |
| Update from git | `chezmoi update` |
| List managed files | `chezmoi managed` |
| Show status | `chezmoi status` |
| View rendered template | `chezmoi cat ~/.zshrc` |
---
## Daily Workflow
### Scenario 1: Edit Existing Config
**Goal**: Update your shell configuration
```bash
# 1. Edit the file
chezmoi edit ~/.zshrc
# 2. Preview what will change
chezmoi diff
# 3. Apply the changes
chezmoi apply
# 4. Test the changes
source ~/.zshrc
# 5. If everything works, commit
chezmoi cd
git add dot_zshrc.tmpl # or dot_zshrc if not a template
git commit -m "feat: add new shell alias"
git push
```
### Scenario 2: Update Neovim Config
**Goal**: Modify Neovim configuration
```bash
# 1. Edit the config
chezmoi edit ~/.config/nvim/lua/alxndrhi/options.lua
# 2. Preview
chezmoi diff
# 3. Apply
chezmoi apply
# 4. Test in neovim
nvim
# 5. Commit
chezmoi cd
git add dot_config/nvim/lua/alxndrhi/options.lua
git commit -m "feat: update neovim tab settings"
git push
```
### Scenario 3: Pull Latest Changes
**Goal**: Sync dotfiles from another machine
```bash
# Pull and apply in one command
chezmoi update
# Or step by step:
chezmoi cd
git pull
exit
chezmoi apply
# Restart affected services
source ~/.zshrc # If shell config changed
# or restart terminal
```
---
## Adding New Tools
When you install a new CLI tool or application with configuration files, here's how to add it to your dotfiles.
### Example: Adding a New Tool (e.g., 'alacritty')
**Step 1: Install the tool**
```bash
# Install via package manager
sudo emerge -av x11-terms/alacritty
```
**Step 2: Create and test the configuration**
```bash
# Create config directory
mkdir -p ~/.config/alacritty
# Create config file
nvim ~/.config/alacritty/alacritty.toml
# Test the tool
alacritty --version
alacritty # Launch and verify config works
```
**Step 3: Add configuration to chezmoi**
```bash
# Add the config file
chezmoi add ~/.config/alacritty/alacritty.toml
# Or add entire directory
chezmoi add --recursive ~/.config/alacritty
```
**What this does:**
- Copies `~/.config/alacritty/` to `~/.local/share/chezmoi/dot_config/alacritty/`
- File is now managed by chezmoi
**Step 4: Verify it was added**
```bash
# Check if file is managed
chezmoi managed | grep alacritty
# View the source file
chezmoi cd
ls -la dot_config/alacritty/
```
**Step 5: Commit to git**
```bash
chezmoi cd
git add dot_config/alacritty/
git commit -m "feat: add alacritty terminal emulator configuration"
git push
```
**Step 6: Test on another machine**
```bash
# On another machine
chezmoi update
# Verify alacritty config is there
ls -la ~/.config/alacritty/
```
### Adding Shell Scripts
If you have custom scripts in `~/bin` or `~/.local/bin`:
```bash
# Add entire directory
chezmoi add --recursive ~/.local/bin
# Or individual scripts
chezmoi add ~/.local/bin/my-script.sh
# Make sure they're executable
chezmoi chattr +executable ~/.local/bin/my-script.sh
# Commit
chezmoi cd
git add .
git commit -m "feat: add custom shell scripts"
git push
```
---
## Editing Existing Configs
### Edit and Apply
```bash
# Edit any managed file
chezmoi edit ~/.gitconfig
# This opens: ~/.local/share/chezmoi/dot_gitconfig.tmpl
# (or dot_gitconfig if not a template)
# After editing, preview changes
chezmoi diff
# Apply
chezmoi apply
# Test
git config --list
```
### Edit Multiple Files
```bash
# Edit several files in your editor
chezmoi edit ~/.zshrc ~/.gitconfig ~/.config/starship.toml
# Preview all changes
chezmoi diff
# Apply all
chezmoi apply
# Commit all
chezmoi cd
git add .
git commit -m "feat: update shell and git configs"
git push
```
### Edit Directly in Source Directory
```bash
# Go to chezmoi source
chezmoi cd
# Edit files directly
nvim dot_zshrc.tmpl
nvim dot_config/nvim/init.lua
# Preview from anywhere
chezmoi diff
# Apply from anywhere
chezmoi apply
# Commit
git add .
git commit -m "feat: update configs"
git push
```
---
## Templates for Cross-Platform Configs
Some configs need to be different on different operating systems or machines. Use templates for this.
### Convert a File to Template
```bash
# Make a file a template
chezmoi chattr +template ~/.zshrc
# This renames: dot_zshrc → dot_zshrc.tmpl
```
### Template Syntax
Templates use Go's `text/template` syntax:
```bash
# OS detection
{{ if eq .chezmoi.os "darwin" -}}
# macOS-specific config
export PATH="/opt/homebrew/bin:$PATH"
{{- else if eq .chezmoi.os "linux" -}}
# Linux-specific config
export PATH="/usr/local/bin:$PATH"
{{- end }}
# Distribution detection
{{ if eq .osid "linux-gentoo" -}}
# Gentoo-specific config
alias emerge-update="sudo emerge --sync && sudo emerge -uDNav @world"
{{- else if eq .osid "linux-ubuntu" -}}
# Ubuntu-specific config
alias apt-update="sudo apt update && sudo apt upgrade"
{{- end }}
# Work vs Personal
{{ if .work -}}
# Work-specific config
export COMPANY_DOMAIN="company.com"
{{- else if .personal -}}
# Personal config
export PROJECTS_DIR="$HOME/repository"
{{- end }}
# Machine-specific
{{ if eq .machine "gentoo-workstation" -}}
# Workstation config
export DISPLAY=:0
{{- else if eq .machine "macos-laptop" -}}
# Laptop config
{{- end }}
```
### Available Template Variables
```bash
# View all available data
chezmoi data
# Common variables:
.chezmoi.os # darwin, linux, windows
.chezmoi.osRelease.id # gentoo, ubuntu, arch
.chezmoi.hostname # lenovo-thinkpad
.osid # linux-gentoo, darwin, etc.
.machine # gentoo-workstation, macos-laptop
.work # true/false
.personal # true/false
.email # your@email.com
.name # Your Name
.features.desktop # true/false
.features.development # true/false
.features.docker # true/false
```
### Example: Cross-Platform .zshrc
```bash
# Edit the template
chezmoi edit ~/.zshrc
# Add OS-specific paths
{{ if eq .chezmoi.os "darwin" -}}
# macOS Homebrew
export PATH="/opt/homebrew/bin:$PATH"
# macOS-specific aliases
alias update="brew update && brew upgrade"
{{- else if eq .osid "linux-gentoo" -}}
# Gentoo paths
export PATH="/usr/local/bin:$HOME/.local/bin:$PATH"
# Gentoo-specific aliases
alias update="sudo emerge --sync && sudo emerge -uDNav @world"
{{- end }}
# Common config (works on all platforms)
export EDITOR=nvim
export VISUAL=nvim
# Apply
chezmoi apply
# Test
echo $PATH
```
### View Rendered Template
```bash
# See how template renders on this machine
chezmoi cat ~/.zshrc
# Test specific template expression
chezmoi execute-template "{{ .chezmoi.os }}"
chezmoi execute-template "{{ .osid }}"
```
---
## Syncing Across Machines
### Setup on New Machine
**One-line install** (if you have the bootstrap script):
```bash
sh -c "$(curl -fsLS https://git.hinrichs.dev/alexander/dotfiles/raw/branch/main/install.sh)"
```
**Manual setup**:
```bash
# 1. Install chezmoi
# (see installation instructions for your OS)
# 2. Initialize with your dotfiles repo
chezmoi init https://git.hinrichs.dev/alexander/dotfiles.git
# 3. Preview what will be applied
chezmoi diff
# 4. Apply dotfiles
chezmoi apply
# 5. Restart shell
exec zsh
```
### Keep Machines in Sync
**On Machine A** (where you made changes):
```bash
# Edit configs
chezmoi edit ~/.zshrc
# Apply
chezmoi apply
# Commit and push
chezmoi cd
git add .
git commit -m "feat: update shell config"
git push
```
**On Machine B** (pull the changes):
```bash
# Pull and apply
chezmoi update
# Or step by step:
chezmoi cd
git pull
exit
chezmoi apply
# Restart shell if needed
exec zsh
```
---
## Advanced Usage
### Ignore Files Per Machine
Edit `.chezmoiignore` to exclude files on specific machines:
```bash
chezmoi cd
nvim .chezmoiignore
# Example content:
{{ if not .features.desktop -}}
# Ignore desktop configs on servers
.config/hypr/
.config/waybar/
{{- end }}
{{ if eq .chezmoi.os "darwin" -}}
# Ignore Linux-specific configs on macOS
.config/systemd/
{{- end }}
```
### Run Scripts on Apply
Create scripts that run when applying dotfiles:
```bash
chezmoi cd
nvim .chezmoiscripts/run_once_after_setup-tool.sh
#!/bin/sh
# Install tool if not present
if ! command -v tool >/dev/null 2>&1; then
echo "Installing tool..."
# Installation commands
fi
```
Script naming:
- `run_once_*` - Runs once (tracked by hash)
- `run_onchange_*` - Runs when script content changes
- `run_before_*` - Runs before applying
- `run_after_*` - Runs after applying
### Encrypt Sensitive Files
```bash
# Add encrypted file
chezmoi add --encrypt ~/.ssh/id_rsa
# chezmoi uses age or gpg for encryption
```
### Dry Run / Testing
```bash
# See what would change without applying
chezmoi apply --dry-run --verbose
# Test on a VM before applying to main machine
```
---
## Troubleshooting
### Warning: Config File Template Changed
**Error**: `chezmoi: warning: config file template has changed`
**Solution**:
```bash
chezmoi init
# Answer prompts for name, email, work/personal
```
### Diff Shows Too Much / Opens vim
The default diff tool is `nvim -d`. To use built-in diff:
```bash
# Use built-in diff (easier to read)
chezmoi diff --use-builtin-diff
# Or use it with pager
chezmoi diff --use-builtin-diff | less
```
### File Conflicts
**Error**: File already exists and differs
**Solution**:
```bash
# Merge manually
chezmoi merge ~/.zshrc
# Or force overwrite
chezmoi apply --force
# Or remove from management and re-add
chezmoi forget ~/.zshrc
# Fix the file manually
chezmoi add ~/.zshrc
```
### Template Errors
**Error**: Template syntax error
**Solution**:
```bash
# View raw template
chezmoi cd
cat dot_zshrc.tmpl
# Check template syntax
chezmoi cat ~/.zshrc
# Test specific expression
chezmoi execute-template "{{ .chezmoi.os }}"
```
### Reset Everything
```bash
# Remove all managed files (DESTRUCTIVE!)
chezmoi purge
# Start fresh
chezmoi init https://git.hinrichs.dev/alexander/dotfiles.git
chezmoi apply
```
### Re-run Installation Scripts
```bash
# Reset script state (scripts will run again)
chezmoi state reset --bucket=scriptState
# Re-apply
chezmoi apply
```
### Check Configuration
```bash
# View chezmoi data
chezmoi data | less
# View config file
cat ~/.config/chezmoi/chezmoi.yaml
# Edit config
chezmoi edit-config
```
---
## Common Patterns
### Pattern 1: Update Tool on All Machines
```bash
# On your main machine
chezmoi edit ~/.config/tool/config
chezmoi apply
chezmoi cd
git add . && git commit -m "feat: update tool config" && git push
# On other machines
chezmoi update
```
### Pattern 2: Add New Tool
```bash
# Install and configure
sudo emerge tool
nvim ~/.config/tool/config
# Add to chezmoi
chezmoi add --recursive ~/.config/tool
chezmoi cd
git add . && git commit -m "feat: add tool configuration" && git push
```
### Pattern 3: Machine-Specific Config
```bash
# Edit template
chezmoi edit ~/.zshrc
# Add machine-specific logic
{{ if eq .machine "gentoo-workstation" -}}
# Workstation-only config
{{- end }}
# Apply and commit
chezmoi apply
chezmoi cd && git add . && git commit -m "feat: add workstation config" && git push
```
### Pattern 4: Temporarily Disable Chezmoi
```bash
# Edit file directly (bypassing chezmoi)
nvim ~/.zshrc
# Test changes
source ~/.zshrc
# If good, update chezmoi
chezmoi add ~/.zshrc
chezmoi cd && git add . && git commit -m "feat: update zshrc" && git push
```
---
## Best Practices
1. **Always preview before applying**
```bash
chezmoi diff # Check what will change
chezmoi apply # Then apply
```
2. **Test changes before committing**
```bash
chezmoi apply
# Test the changes
# If broken, fix and re-apply
# Only commit when working
```
3. **Use templates for cross-platform configs**
- OS-specific paths
- Package manager commands
- Tool locations
4. **Keep commits atomic and descriptive**
```bash
# Good
git commit -m "feat: add starship prompt configuration"
# Bad
git commit -m "update stuff"
```
5. **Document complex templates**
```bash
# Add comments in templates
# {{ if eq .chezmoi.os "darwin" -}}
# macOS uses Homebrew in /opt/homebrew
export PATH="/opt/homebrew/bin:$PATH"
# {{- end }}
```
6. **Don't commit secrets**
- Use `.chezmoiignore` for sensitive files
- Or use encryption for files that must be synced
7. **Test on a VM before deploying widely**
- Especially for major changes
- Prevents breaking all machines at once
---
## Resources
- **Official chezmoi docs**: https://www.chezmoi.io/
- **Dotfiles repository**: `~/repository/git.hinrichs.dev/alexander/dotfiles`
- **This system's USER-GUIDE.md**: Quick reference for chezmoi commands
- **chezmoi GitHub**: https://github.com/twpayne/chezmoi
---
## Summary
**Daily workflow:**
1. `chezmoi edit ~/.config` - Edit configs
2. `chezmoi diff` - Preview changes
3. `chezmoi apply` - Apply changes
4. `chezmoi cd && git add . && git commit && git push` - Commit
5. `chezmoi update` on other machines - Sync
**Adding new tools:**
1. Install and configure the tool
2. `chezmoi add ~/.config/tool` - Add to chezmoi
3. Commit and push
**Cross-platform:**
1. `chezmoi chattr +template ~/.file` - Make template
2. Add `{{ if eq .chezmoi.os "..." }}` logic
3. Apply and test on each platform
Your dotfiles are now version controlled, synced across machines, and managed professionally!