MCPcopy
hub / github.com/anishathalye/dotbot

github.com/anishathalye/dotbot @v1.24.1 sqlite

repository ↗ · DeepWiki ↗ · release v1.24.1 ↗
267 symbols 1,047 edges 40 files 160 documented · 60%
README

Dotbot Build Status Coverage PyPI PyPI - Python version

Dotbot makes installing your dotfiles as easy as git clone $url && cd dotfiles && ./install, even on a freshly installed system!


Rationale

Dotbot is a tool that bootstraps your dotfiles (it's a [Dot]files [bo]o[t]strapper, get it?). It does less than you think, because version control systems do more than you think.

Dotbot is designed to be lightweight and self-contained, with no external dependencies and no installation required. Dotbot can also be a drop-in replacement for any other tool you were using to manage your dotfiles, and Dotbot is VCS-agnostic — it doesn't make any attempt to manage your dotfiles.

Dotbot has many [plugins] that extend its functionality, such as:

See this blog post or more resources on the tutorials page for more detailed explanations of how to organize your dotfiles.

Getting started

Starting fresh?

Great! You can automate the creation of your dotfiles by using the user-contributed [init-dotfiles][init-dotfiles] script. If you'd rather use a template repository, check out [dotfiles_template][dotfiles-template]. Or, if you're just looking for [some inspiration][inspiration], we've got you covered.

Integrate with existing dotfiles

The following will help you get set up using Dotbot in just a few steps.

You can create an empty configuration file with:

touch install.conf.yaml

If you're using Git, you can add Dotbot as a submodule:

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 .

If you're using Mercurial, you can add Dotbot as a subrepo:

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 .

If you are using PowerShell instead of a POSIX shell, you can use the provided install.ps1 script instead of install. On Windows, Dotbot only supports Python 3.8+, and it requires that your account is [allowed to create symbolic links][windows-symlinks].

To get started, you just need to fill in the install.conf.yaml and Dotbot will take care of the rest. To help you get started we have an example config file as well as configuration documentation for the accepted parameters.

Note: The install script is merely a shim that checks out the appropriate version of Dotbot and calls the full Dotbot installer. By default, the script assumes that the configuration is located in install.conf.yaml the Dotbot submodule is located in dotbot. You can change either of these parameters by editing the variables in the install script appropriately.

Setting up Dotbot as a submodule or subrepo locks it on the current version. You can upgrade Dotbot at any point. If using a submodule, run git submodule update --remote dotbot, substituting dotbot with the path to the Dotbot submodule; be sure to commit your changes before running ./install, otherwise the old version of Dotbot will be checked out by the install script. If using a subrepo, run git fetch && git checkout origin/master in the Dotbot directory.

Installation as a command-line program

If you prefer, instead of bundling Dotbot as a submodule with your dotfiles, you can install Dotbot from [PyPI] as a standalone command-line program. Use the tool of your choice, such as pip or [uv][uv]:

uv tool install dotbot

Some systems include Dotbot in their native package manager, such as [Homebrew][homebrew-dotbot] and [Arch Linux][arch-dotbot], so for example, you can also install it with brew install dotbot.

With Dotbot installed as a command-line program on your system, you can invoke Dotbot with dotbot -c <path to configuration file>.

Full example

Here's an example of a complete configuration.

The conventional name for the configuration file is install.conf.yaml.

- defaults:
    link:
      relink: true

- clean: ['~']

- link:
    ~/.tmux.conf: tmux.conf
    ~/.vim: vim
    ~/.vimrc: vimrc

- create:
    - ~/downloads
    - ~/.vim/undo-history

- shell:
  - [git submodule update --init --recursive, Installing submodules]

The configuration file is typically written in YAML, but it can also be written in JSON (which is a [subset of YAML][json2yaml]). JSON configuration files are conventionally named install.conf.json.

Installing Your Dotfiles

To install your dotfiles on a new machine or after updates:

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

To update an existing installation:

cd ~/.dotfiles
git pull
./install

Configuration

Dotbot uses YAML or JSON-formatted configuration files to let you specify how to set up your dotfiles. Currently, Dotbot knows how to link files and folders, create folders, execute shell commands, and clean directories of broken symbolic links. Dotbot also supports user plugins for custom commands.

Ideally, bootstrap configurations should be idempotent. That is, the installer should be able to be run multiple times without causing any problems. This makes a lot of things easier to do (in particular, syncing updates between machines becomes really easy).

Dotbot configuration files are arrays of tasks, where each task is a dictionary that contains a command name mapping to data for that command. Tasks are run in the order in which they are specified. Commands within a task do not have a defined ordering.

When writing nested constructs, keep in mind that YAML is whitespace-sensitive. Following the formatting used in the examples is a good idea. If a YAML configuration file is not behaving as you expect, try inspecting the [equivalent JSON][json2yaml] and check that it is correct.

Directives

Most Dotbot commands support both a simplified and extended syntax, and they can also be configured via setting defaults.

Link

Link commands create symbolic links at specified locations that point to files in your dotfiles repository. This allows you to keep your configuration files in version control while having them appear where applications expect to find them. Symlinks are created by default, but hardlinks are also supported. If desired, items can be specified to be forcibly linked, overwriting existing files if necessary. Environment variables in paths are automatically expanded.

Format

Link commands are specified as a dictionary mapping link names to targets. The link name (key) is where the symbolic link will be created, and the target (value) is the file in your dotfiles directory that the link will point to. Targets are specified relative to the base directory (that is specified when running the installer). If linking directories, do not include a trailing slash.

Link commands support an optional extended configuration. In this type of configuration, instead of specifying targets directly, link names are mapped to extended configuration dictionaries.

Parameter Explanation
path The target for the link (file in dotfiles directory), the same as in the shortcut syntax (default: null, automatic (see below))
type The type of link to create. If specified, must be either symlink or hardlink. (default: symlink)
create When true, create parent directories to the link as needed. (default: false)
relink Removes the old link if it's a symlink (default: false)
force Force removes the old link, file or folder, and forces a new link (default: false)
backup Backup existing files/directories if they exist, creating a backup with suffix .dotbot-backup.{timestamp} (default: false)
relative When creating a symlink, use a relative path to the target. (default: false, absolute links)
canonicalize Resolve any symbolic links encountered in the target to symlink to the canonical path (default: true, real paths)
if Execute this in your $SHELL and only link if it is successful.
ignore-missing Do not fail if the target is missing and create the link anyway (default: false)
glob Treat path as a glob pattern, expanding patterns referenced below, linking all files matched. (default: false)
exclude Array of glob patterns to remove from glob matches. Uses same syntax as path. Ignored if glob is false. (default: empty, keep all matches)
prefix Prepend prefix prefix to basename of each file when linked, when glob is true. (default: '')

When glob: true, Dotbot uses glob.glob to resolve glob paths, expanding Unix shell-style wildcards, which are not the same as regular expressions; Only the following are expanded:

Pattern Meaning
* matches anything
** matches any file, recursively
? matches any single character
[seq] matches any character in seq
[!seq] matches any character not in seq

However, due to the design of glob.glob, using a glob pattern such as config/*, will not match items that begin with .. To specifically capture items that being with ., you will need to include the . in the pattern, like this: config/.*.

When using glob with the exclude: option, the paths in the exclude paths should be relative to the base directory, same as the glob pattern itself. For example, if a glob pattern vim/* matches directories vim/autoload, vim/ftdetect, vim/ftplugin, and vim/spell, and you want to ignore the spell directory, then you should use exclude: ["vim/spell"] (not just "spell").

Example

- 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: '.'

If the target location is omitted or set to null, Dotbot will use the basename of the link name, with a leading . stripped if present. This makes the following two config files equivalent.

Explicit targets:

- link:
    ~/bin/ack: ack
    ~/.vim: vim
    ~/.vimrc:
      relink: true
      path: vimrc
    ~/.zshrc:
      force: true
      path: zshrc
    ~/.config/:
      glob: true
      path: config/*
      relink: true
      exclude: [ config/Code ]
    ~/.config/Code/User/:
      create: true
      glob: true
      path: config/Code/User/*
      relink: true

Implicit targets:

- link:
    ~/bin/ack:
    ~/.vim:
    ~/.vimrc:
      relink: true
    ~/.zshrc:
      force: true
    ~/.config/:
      glob: true
      path: config/*
      relink: true
      exclude: [ config/Code ]
    ~/.config/Code/User/:
      create: true
      glob: true
      path: config/Code/User/*
      relink: true

Create

Create commands specify empty directories to be created. This can be useful for scaffolding out folders or parent folder structure required for various apps, plugins, shell commands, etc.

Format

Create commands are specified as an array of directories to be created. If you want to use the optional extended configuration, create commands are specified as dictionaries. For convenience, it's permissible to leave the options blank (null) in the dictionary syntax.

Parameter Explanation
mode The file mode to use for creating the leaf directory (default: 0777)

The mode parameter is treated in the same way as in Python's os.mkdir. Its behavior is platform-dependent. On Unix systems, the current umask value is first masked out.

Example

- create:
    - ~/downloads
    - ~/.vim/undo-history
- create:
    ~/.ssh:
      mode: 0700
    ~/projects:

Shell

Shell c

Core symbols most depended-on inside this repo

debug
called by 23
src/dotbot/messenger/messenger.py
action
called by 16
src/dotbot/messenger/messenger.py
warning
called by 15
src/dotbot/messenger/messenger.py
info
called by 13
src/dotbot/messenger/messenger.py
error
called by 13
src/dotbot/messenger/messenger.py
dry_run
called by 10
src/dotbot/context.py
base_directory
called by 8
src/dotbot/context.py
_exists
called by 6
src/dotbot/plugins/link.py

Shape

Function 155
Method 87
Class 22
Route 3

Languages

Python100%

Modules by API surface

tests/test_link.py68 symbols
tests/conftest.py19 symbols
src/dotbot/plugins/link.py18 symbols
tests/test_shell.py17 symbols
tests/test_cli.py16 symbols
src/dotbot/messenger/messenger.py13 symbols
tests/test_clean.py12 symbols
tests/test_plugins.py10 symbols
src/dotbot/context.py9 symbols
src/dotbot/messenger/level.py7 symbols
src/dotbot/plugins/create.py6 symbols
src/dotbot/plugins/clean.py6 symbols

For agents

$ claude mcp add dotbot \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact