dotbot

repository·master·Indexed 27 days ago

https://github.com/anishathalye/dotbot

A lightweight, VCS-agnostic dotfiles bootstrapper designed to automate the installation and configuration of dotfiles on a new system. It uses YAML or JSON configuration files to execute tasks such as creating symlinks (link), scaffolding directories (create), running shell commands (shell), and removing dead symlinks (clean). Dotbot is self-contained with no external dependencies and supports custom plugins.

Tokens
3.5K
Snippets
19
Records
27
Agent score
92%

What's inside dotbot

  1. Install and update dotfiles using the install script

    master

    To install your dotfiles on a new machine or update an existing installation, use the install shim (or install.ps1 on Windows) located in your dotfiles directory.

    New Installation:

    git clone <your-dotfiles-repo-url> ~/.dotfiles
    cd ~/.dotfiles
    ./install

    Update Existing Installation:

    cd ~/.dotfiles
    git pull
    ./install
    git clone <your-dotfiles-repo-url> ~/.dotfiles
    cd ~/.dotfiles
    ./install
  2. Integrate Dotbot as a Git submodule

    master

    If you manage your dotfiles with Git, you can bundle Dotbot as a submodule within your repository. This locks Dotbot to a specific version. After adding the submodule, copy the provided install shim to your root directory.

    Steps:

    1. Navigate to your dotfiles directory.
    2. Initialize the repository if necessary.
    3. Add the Dotbot submodule.
    4. Configure Git to ignore dirty commits in the submodule.
    5. Copy the installation shim.
    cd ~/.dotfiles # replace with the path to your dotfiles
    git init # initialize repository if needed
    git submodule add https://github.com/anishathalye/dotbot
    git config -f .gitmodules submodule.dotbot.ignore dirty # ignore dirty commits in the submodule
    cp dotbot/tools/git-submodule/install .
  3. Load custom plugins

    master

    Dotbot supports custom directives via plugins. Plugins must be subclasses of dotbot.Plugin and implement can_handle() and handle(). To support dry-runs, they should declare supports_dry_run = True and use Context.dry_run().

    Loading via Configuration: Specify an array of files or directories (containing plugins) under the plugins key. Paths are relative to the base directory.

    Loading via Command Line: Use the --plugin flag. This can be used multiple times. Paths are relative to the working directory where dotbot is invoked.

    # Via config
    - plugins:
        - dotbot-plugins/dotbot-brew/
        - dotbot-plugins/custom_plugin.py
    # Via CLI
    dotbot --plugin dotbot-plugins/dotbot-brew/ --plugin dotbot-plugins/custom_plugin.py ...
  4. Integrate Dotbot as a Mercurial subrepo

    master

    If you use Mercurial, you can add Dotbot as a subrepo by creating a .hgsub file and cloning the Dotbot repository into your dotfiles directory.

    cd ~/.dotfiles # replace with the path to your dotfiles
    hg init # initialize repository if needed
    echo "dotbot = [git]https://github.com/anishathalye/dotbot" > .hgsub
    hg add .hgsub
    git clone https://github.com/anishathalye/dotbot
    cp dotbot/tools/hg-subrepo/install .
  5. Run tests for Dotbot

    master

    Dotbot uses Hatch to manage testing. You can run the full test suite on your local machine using the hatch test command.

    Supported Hatch test options:

    • -c: Measure test coverage.
    • -a: Test against a matrix of Python versions.
    • Append a specific test path (e.g., tests/test_shell.py::test_name) to run a single test.
    hatch test
  6. Run tests in an isolated Docker container

    master

    Because Dotbot interacts with the filesystem and executes shell commands, you can run tests inside an isolated Docker container to prevent side effects on your host machine.

    1. Start a Python container and mount the current directory: docker run -it --rm -v "${PWD}:/dotbot" -w /dotbot python:3.13-bookworm /bin/bash
    2. Inside the container, install Hatch: pip install hatch.
    3. Run the tests using hatch test.
    docker run -it --rm -v "${PWD}:/dotbot" -w /dotbot python:3.13-bookworm /bin/bash
  7. Build and publish Dotbot artifacts

    master

    Use Hatch to manage the packaging lifecycle:

    • Build artifacts: Use hatch build to create source distributions (sdist) and built distributions (wheel).
    • Publish: Use hatch publish to upload build artifacts to PyPI.
    hatch build
    hatch publish
  8. Install Dotbot as a standalone CLI

    master

    You can install Dotbot as a standalone command-line program using pip or uv. Once installed, you can invoke it using the dotbot command and specify your configuration file with the -c flag.

    To install using uv:

    uv tool install dotbot

    To run Dotbot with a specific configuration:

    dotbot -c <path to configuration file>
    uv tool install dotbot
  9. Use the Create directive to scaffold directories

    master

    The create directive specifies empty directories to be created. This is useful for setting up folder structures required by applications.

    Formats:

    • An array of directory paths.
    • A dictionary for extended configuration.

    Parameters:

    • mode: The file mode for the leaf directory (default: 0777). Behavior is platform-dependent and follows Python's os.mkdir logic (on Unix, it is masked by the current umask).
    - create:
        - ~/downloads
        - ~/.vim/undo-history
    - create:
        ~/.ssh:
          mode: 0700
        ~/projects:
  10. Use the Link directive to create symlinks or hardlinks

    master

    The link directive creates symbolic or hard links at specified locations pointing to files in your dotfiles repository.

    Shortcut Syntax: A dictionary mapping link names (where the link will be created) to targets (files in your dotfiles directory). If the target is omitted, Dotbot uses the link name's basename (stripping a leading . if present).

    Extended Syntax: Maps link names to configuration dictionaries for fine-grained control.

    Key Configuration Parameters:

    • path: The target file in the dotfiles directory.
    • type: Either symlink (default) or hardlink.
    • create: If true, creates parent directories as needed.
    • relink: If true, removes the old symlink before creating a new one.
    • force: Forcefully removes an existing file/folder/link before creating the new link.
    • backup: Creates a backup with suffix .dotbot-backup.{timestamp} if the file exists.
    • relative: Uses a relative path for the symlink instead of an absolute path.
    • canonicalize: Resolves target symlinks to their real paths (default: true).
    • if: A shell command that must succeed for the link to be created.
    • ignore-missing: If true, does not fail if the target is missing.
    • glob: If true, treats path as a glob pattern to link all matched files.
    • exclude: An array of glob patterns to exclude from a glob match.
    • prefix: Prepends a string to the basename of each file when glob is true.
    - link:
        ~/.config/terminator:
          create: true
          path: config/terminator
        ~/.vim: vim
        ~/.vimrc:
          relink: true
          path: vimrc
        ~/.zshrc:
          force: true
          path: zshrc
        ~/.hammerspoon:
          if: '[ `uname` = Darwin ]'
          path: hammerspoon
        ~/.config/:
          glob: true
          path: dotconf/config/**
        ~/:
          glob: true
          path: dotconf/*
          prefix: '.'