Skip to content

craveytrain/dotfiles

Repository files navigation

Dotfiles Repository

A comprehensive dotfiles management system using the ansible-role-dotmodules role for automated system configuration and dotfile deployment.

Governance: See Constitution v1.0.0 for project principles AI-Assisted Development: Integrated with GitHub Spec-Kit for spec-driven development Quick Start: New to this repo? See QUICKSTART.md for fast setup

Overview

This repository contains modular dotfile configurations that can be deployed using Ansible automation. Each module is self-contained and can be mixed and matched to create a personalized development environment.

Repository Structure

dotfiles/
├── .specify/          # Spec-Kit specifications (auto-managed)
├── docs/              # Documentation and policy
│   └── policy/        # Governance and policy documents
│       ├── CONSTITUTION.md    # Core principles (v1.0.0)
│       ├── GOVERNANCE.md      # Governance model
│       ├── CODING_STANDARDS.md # Coding standards
│       └── CHANGELOG.md       # Change history
├── modules/           # Dotfile modules (each with config.yml and files/)
│   ├── 1password/     # 1Password CLI for password management
│   ├── dev-tools/     # Development utilities (mise, jq, shellcheck, etc.)
│   ├── editor/        # Editor configurations (vim)
│   ├── fish/          # Fish shell configuration and functions
│   ├── fonts/         # System fonts for development
│   ├── git/           # Git configuration and tools
│   ├── node/          # Node.js development (node, pnpm via mise)
│   ├── shell/         # Common shell utilities (eza, ripgrep, etc.)
│   └── zsh/           # Zsh shell configuration and prompt theme
├── playbooks/         # Ansible playbooks for deployment
│   ├── deploy.yml     # Main deployment playbook
│   └── inventory      # Ansible inventory file
├── QUICKSTART.md      # Quick start guide for new users
├── requirements.yml   # Ansible Galaxy requirements
└── README.md          # This file

Module Structure

Each module follows this structure:

module-name/
├── README.md          # Module documentation (purpose, features, usage)
├── config.yml         # Module configuration (Homebrew packages, stow dirs, etc.)
└── files/             # Dotfiles to be deployed
    ├── .config/       # Configuration files
    ├── .bin/          # Binary/script files
    └── .*rc           # Shell configuration files

Usage

Prerequisites

  • macOS (required for Homebrew integration)
  • Ansible 2.9+
  • GNU Stow (for dotfile deployment)
  • Homebrew (for package management)

Installation

  1. Clone this repository:

    git clone https://github.com/yourusername/dotfiles.git
    cd dotfiles
  2. Install the ansible-role-dotmodules role:

    ansible-galaxy install -r requirements.yml
  3. Run the playbook:

    ansible-playbook -i playbooks/inventory playbooks/deploy.yml --ask-become-pass

Available Modules

Module Description Key Tools
shell Common shell utilities eza, ripgrep, tldr, trash, wget, stow
fish Fish shell configuration fish, fisher, tide
zsh Zsh shell configuration zsh, powerlevel10k
git Git configuration git, gh, diff-so-fancy, difftastic
editor Editor configurations vim
dev-tools Development tools mise, jq, shellcheck, actionlint, bat
node Node.js development node, pnpm (via mise)
1password Password management CLI 1password-cli (op)
fonts System fonts Fira Code, Hack Nerd Font, Inconsolata, Input

Configuration

Each module's config.yml file defines:

  • Homebrew packages to install
  • Homebrew taps to add
  • Homebrew casks to install
  • Stow directories for dotfile deployment

Example config.yml:

---
# Shell common utilities module
homebrew_packages:
  - eza
  - ripgrep
  - tldr
  - trash
  - wget
  - stow

stow_dirs:
  - zsh

mergeable_files:
  - '.zshrc'  # Merged with other modules' contributions

Shell Registration

Modules can automatically register shells in /etc/shells, which is required to use them as your default shell via chsh.

How It Works

Add register_shell to your module's config.yml to enable automatic registration:

# modules/fish/config.yml
homebrew_packages:
  - fish

register_shell: fish  # Automatically registers /opt/homebrew/bin/fish (or /usr/local/bin/fish on Intel)

Shell paths are automatically detected based on your system architecture:

  • Apple Silicon (M1/M2/M3): /opt/homebrew/bin/fish
  • Intel Mac: /usr/local/bin/fish

Skipping Registration

To disable shell registration permanently, simply remove or comment out the register_shell line from your module's config.yml.

To skip registration for a single deployment (useful for CI/CD, testing, or restricted environments), use the --skip-tags flag:

ansible-playbook -i playbooks/inventory playbooks/deploy.yml --skip-tags register_shell

Note: When using --skip-tags register_shell, you don't need --ask-become-pass since no sudo privileges are required.

When to Skip Registration

Use --skip-tags register_shell when:

  • CI/CD pipelines: No sudo access available
  • Testing deployments: Don't want to modify system files
  • Restricted environments: Corporate systems with policies preventing /etc/shells modification
  • Quick deployments: Shell registration not needed for the current session

Updating Dotfiles

After making changes to your dotfiles:

  1. Commit your changes:

    git add .
    git commit -m "Update dotfiles"
  2. Re-run the playbook to apply changes:

    ansible-playbook -i playbooks/inventory playbooks/deploy.yml --ask-become-pass

Module Management

Enable/Disable Modules

Edit playbooks/deploy.yml and modify the install list:

install:
  - fish
  - zsh
  - git
  # - editor  # Comment out to disable
  - dev-tools

Add a New Module

  1. Create module directory: modules/my-module/
  2. Add config.yml with Homebrew packages and stow_dirs
  3. Add files/ directory with your dotfiles
  4. Add module name to install list in playbooks/deploy.yml

Local Configuration Overrides

All modules support machine-specific configuration overrides via local config files. These files are not tracked in version control and allow you to customize settings per-machine without modifying the base dotfiles.

How It Works

Base configuration files (.gitconfig, .zshrc, .vimrc, etc.) automatically load local config files if they exist:

  • Git: ~/.gitconfig.local (loaded via [include] directive)
  • Zsh: ~/.zshrc.local (loaded via conditional source)
  • Fish: ~/.config/fish/config.local.fish (loaded via conditional source)
  • Vim: ~/.vimrc.local (loaded via conditional source)

Creating Local Config Files

You create these files manually in your home directory when you need machine-specific settings. Each module's README documents:

  • Where to create the local config file
  • What format/syntax to use
  • Concrete examples for common use cases

Example - Git local config:

# Create ~/.gitconfig.local
vim ~/.gitconfig.local

# Add machine-specific settings
[user]
    name = Your Name (Work Laptop)
    email = work@company.com

Example - Shell local config (for environment variables):

# Create ~/.zshrc.local (or ~/.config/fish/config.local.fish for fish)
vim ~/.zshrc.local

# Add environment variable overrides for tools
export NPM_CONFIG_REGISTRY=https://registry.company.com
export BAT_THEME="Monokai Extended Light"

Tools Without Local Config Support

Some tools (npm, mise, bat) don't support local config files but respect environment variables. See the dev-tools module README for available environment variables and how to set them in your shell's local config file.

Benefits

  • Machine-specific settings: Different identities, paths, or preferences per machine
  • Private credentials: Store API keys and tokens without committing to git
  • No conflicts: Local configs override base configs without modifying tracked files
  • Zero errors: Base configs load normally if local files don't exist

For detailed instructions, see each module's README file.

Customization

Adding New Modules

  1. Create a new directory in modules/
  2. Add a config.yml file with your configuration
  3. Create a files/ directory with your dotfiles
  4. Add the module to your playbook's install list in playbooks/deploy.yml

Modifying Existing Modules

  1. Edit the module's config.yml to change dependencies
  2. Modify files in the files/ directory
  3. Re-run your playbook to apply changes

How It Works

  1. Module Processing: Each module is processed independently
  2. Configuration Aggregation: All module configurations are merged
  3. Dependency Resolution: Homebrew packages, taps, and casks are collected
  4. Dotfile Deployment: GNU Stow deploys all dotfiles
  5. Package Installation: Homebrew installs all dependencies

Benefits

  • Modular: Mix and match modules for different setups
  • Automated: One command sets up your entire environment
  • Reproducible: Same setup across multiple machines
  • Version Controlled: All configurations in Git
  • Conflict Resolution: Intelligent handling of configuration conflicts

Troubleshooting

Common Issues

  1. Missing dependencies: Ensure all required Ansible roles are installed
  2. Stow conflicts: Check for existing dotfiles that might conflict
  3. Homebrew issues: Ensure Homebrew is properly installed

Debug Mode

Run with verbose output to see what's happening:

ansible-playbook -i playbooks/inventory playbooks/deploy.yml --ask-become-pass -v

Development with Spec-Kit

This repository uses GitHub Spec-Kit for spec-driven development with Cursor AI.

Note: Spec-Kit commands require the GitHub Spec-Kit extension to be installed in Cursor. The commands are provided by the extension, not by files in this repository.

Installing Spec-Kit

Spec-Kit is installed via UV (Python tool manager), not as a Cursor extension:

# Install UV if not already installed
brew install uv

# Install Spec-Kit CLI
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git

# Verify installation
specify check

Once installed, the /speckit.* slash commands will be available in Cursor's AI chat (press Cmd+K).

For detailed usage instructions, see CURSOR.md.

Quick Start

Once the Spec-Kit extension is installed, press Cmd+K in Cursor and use slash commands:

  1. Create specification: /speckit.specify Add Firefox module with developer edition
  2. Create plan: /speckit.plan Install via Homebrew, configure for development
  3. Generate tasks: /speckit.tasks
  4. Implement: /speckit.implement

Available Commands

These commands are provided by the GitHub Spec-Kit extension:

  • /speckit.constitution - View/update project principles
  • /speckit.specify - Create feature specifications
  • /speckit.clarify - Interactive requirement clarification
  • /speckit.plan - Generate implementation plans
  • /speckit.tasks - Break down into actionable tasks
  • /speckit.implement - Execute implementation
  • /speckit.analyze - Verify cross-artifact consistency
  • /speckit.checklist - Quality validation gates

See CURSOR.md for comprehensive development guidelines and patterns.

Policy Documents

This repository is governed by a set of policy documents:

All contributions must comply with the principles defined in the Constitution.

Migration from Old Structure

If you were using the old bootstrap.sh script, the new structure is fully compatible. The Ansible playbook replaces the bootstrap script and provides the same functionality with additional benefits:

  • Automated dependency management
  • Idempotent operations
  • Better error handling
  • Cross-platform support (with configuration)

Credits

Thanks to getfatday for the ansible-role-dotmodules structure and inspiration.

License

MIT License - see LICENSE file for details.

About

My very own dotfiles

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors