Merge branch 'jesseleite/readme-organization'
[dotbot.git] / README.md
blob7adb30c037b96d9363c67bf2310929a662c90902
1 # Dotbot [![Build Status](https://travis-ci.org/anishathalye/dotbot.svg?branch=master)](https://travis-ci.org/anishathalye/dotbot)
3 Dotbot makes installing your dotfiles as easy as `git clone $url && cd dotfiles
4 && ./install`, even on a freshly installed system!
6 - [Rationale](#rationale)
7 - [Getting Started](#getting-started)
8 - [Configuration](#configuration)
9 - [Directives](#directives)
10   - [Link](#link)
11   - [Create](#create)
12   - [Shell](#shell)
13   - [Clean](#clean)
14   - [Defaults](#defaults)
15   - [Plugins](#plugins)
16 - [Wiki][wiki]
18 ---
20 ## Rationale
22 Dotbot is a tool that bootstraps your dotfiles (it's a [Dot]files
23 [bo]o[t]strapper, get it?). It does *less* than you think, because version
24 control systems do more than you think.
26 Dotbot is designed to be lightweight and self-contained, with no external
27 dependencies and no installation required. Dotbot can also be a drop-in
28 replacement for any other tool you were using to manage your dotfiles, and
29 Dotbot is VCS-agnostic -- it doesn't make any attempt to manage your dotfiles.
31 If you want an in-depth tutorial about organizing your dotfiles, see this [blog
32 post][managing-dotfiles-post].
34 ## Getting Started
36 ### Starting Fresh?
38 Great! You can automate the creation of your dotfiles by using the
39 user-contributed [init-dotfiles][init-dotfiles] script. If you'd rather use a
40 template repository, check out [dotfiles_template][dotfiles-template]. Or, if
41 you're just looking for [some inspiration][inspiration], we've got you covered.
43 ### Integrate with Existing Dotfiles
45 The following will help you get set up using Dotbot in just a few steps.
47 If you're using **Git**, you can add Dotbot as a submodule:
49 ```bash
50 cd ~/.dotfiles # replace with the path to your dotfiles
51 git init # initialize repository if needed
52 git submodule add https://github.com/anishathalye/dotbot
53 git config -f .gitmodules submodule.dotbot.ignore dirty # ignore dirty commits in the submodule
54 cp dotbot/tools/git-submodule/install .
55 touch install.conf.yaml
56 ```
58 If you're using **Mercurial**, you can add Dotbot as a subrepo:
60 ```bash
61 cd ~/.dotfiles # replace with the path to your dotfiles
62 hg init # initialize repository if needed
63 echo "dotbot = [git]https://github.com/anishathalye/dotbot" > .hgsub
64 hg add .hgsub
65 git clone https://github.com/anishathalye/dotbot
66 cp dotbot/tools/hg-subrepo/install .
67 touch install.conf.yaml
68 ```
70 To get started, you just need to fill in the `install.conf.yaml` and Dotbot
71 will take care of the rest. To help you get started we have [an
72 example](#full-example) config file as well as [configuration
73 documentation](#configuration) for the accepted parameters.
75 Note: The `install` script is merely a shim that checks out the appropriate
76 version of Dotbot and calls the full Dotbot installer. By default, the script
77 assumes that the configuration is located in `install.conf.yaml` the Dotbot
78 submodule is located in `dotbot`. You can change either of these parameters by
79 editing the variables in the `install` script appropriately.
81 Setting up Dotbot as a submodule or subrepo locks it on the current version.
82 You can upgrade Dotbot at any point. If using a submodule, run `git submodule
83 update --remote dotbot`, substituting `dotbot` with the path to the Dotbot
84 submodule; be sure to commit your changes before running `./install`, otherwise
85 the old version of Dotbot will be checked out by the install script. If using a
86 subrepo, run `git fetch && git checkout origin/master` in the Dotbot directory.
88 If you prefer, you can install Dotbot from [PyPI] and call it as a command-line
89 program:
91 ```bash
92 pip install dotbot
93 touch install.conf.yaml
94 ```
96 In this case, rather than running `./install`, you can invoke Dotbot with
97 `dotbot -c <path to configuration file>`.
99 ### Full Example
101 Here's an example of a complete configuration.
103 The conventional name for the configuration file is `install.conf.yaml`.
105 ```yaml
106 - defaults:
107     link:
108       relink: true
110 - clean: ['~']
112 - link:
113     ~/.dotfiles: ''
114     ~/.tmux.conf: tmux.conf
115     ~/.vim: vim
116     ~/.vimrc: vimrc
118 - create:
119     - ~/downloads
120     - ~/.vim/undo-history
122 - shell:
123   - [git submodule update --init --recursive, Installing submodules]
126 The configuration file is typically written in YAML, but it can also be written
127 in JSON (which is a subset of YAML). [Here][json-equivalent] is the JSON
128 [equivalent][json2yaml] of the YAML configuration given above. JSON
129 configuration files are conventionally named `install.conf.json`.
131 ## Configuration
133 Dotbot uses YAML or JSON-formatted configuration files to let you specify how
134 to set up your dotfiles. Currently, Dotbot knows how to [link](#link) files and
135 folders, [create](#create) folders, execute [shell](#shell) commands, and
136 [clean](#clean) directories of broken symbolic links. Dotbot also supports user
137 [plugins](#plugins) for custom commands.
139 **Ideally, bootstrap configurations should be idempotent. That is, the
140 installer should be able to be run multiple times without causing any
141 problems.** This makes a lot of things easier to do (in particular, syncing
142 updates between machines becomes really easy).
144 Dotbot configuration files are arrays of tasks, where each task
145 is a dictionary that contains a command name mapping to data for that command.
146 Tasks are run in the order in which they are specified. Commands within a task
147 do not have a defined ordering.
149 When writing nested constructs, keep in mind that YAML is whitespace-sensitive.
150 Following the formatting used in the examples is a good idea. If a YAML
151 configuration file is not behaving as you expect, try inspecting the
152 [equivalent JSON][json2yaml] and check that it is correct.
154 Also, note that `~` in YAML is the same as `null` in JSON. If you want a single
155 character string containing a tilde, make sure to enclose it in quotes: `'~'`
157 ## Directives
159 ### Link
161 Link commands specify how files and directories should be symbolically linked.
162 If desired, items can be specified to be forcibly linked, overwriting existing
163 files if necessary. Environment variables in paths are automatically expanded.
165 #### Format
167 Link commands are specified as a dictionary mapping targets to source
168 locations. Source locations are specified relative to the base directory (that
169 is specified when running the installer). If linking directories, *do not* include a trailing slash.
171 Link commands support an (optional) extended configuration. In this type of
172 configuration, instead of specifying source locations directly, targets are
173 mapped to extended configuration dictionaries.
175 Available extended configuration parameters:
177 | Link Option | Explanation |
178 | -- | -- |
179 | `path` | The source for the symlink, the same as in the shortcut syntax (default:null, automatic (see below)) |
180 | `create` | When true, create parent directories to the link as needed. (default:false) |
181 | `relink` | Removes the old target if it's a symlink (default:false) |
182 | `force` | Force removes the old target, file or folder, and forces a new link (default:false) |
183 | `relative` | Use a relative path to the source when creating the symlink (default:false, absolute links) |
184 | `glob` | Treat a `*` character as a wildcard, and perform link operations on all of those matches (default:false) |
185 | `if` | Execute this in your `$SHELL` and only link if it is successful. |
187 #### Example
189 ```yaml
190 - link:
191     ~/.config/terminator:
192       create: true
193       path: config/terminator
194     ~/.vim: vim
195     ~/.vimrc:
196       relink: true
197       path: vimrc
198     ~/.zshrc:
199       force: true
200       path: zshrc
203 If the source location is omitted or set to `null`, Dotbot will use the
204 basename of the destination, with a leading `.` stripped if present. This makes
205 the following config files equivalent:
207 ```yaml
208 - link:
209     ~/bin/ack: ack
210     ~/.vim: vim
211     ~/.vimrc:
212       relink: true
213       path: vimrc
214     ~/.zshrc:
215       force: true
216       path: zshrc
217     ~/.config/:
218       glob: true
219       path: config/*
220       relink: true
223 ```yaml
224 - link:
225     ~/bin/ack:
226     ~/.vim:
227     ~/.vimrc:
228       relink: true
229     ~/.zshrc:
230       force: true
231     ~/.config/:
232       glob: true
233       path: config/*
234       relink: true
237 ### Create
239 Create commands specify empty directories to be created.  This can be useful
240 for scaffolding out folders or parent folder structure required for various
241 apps, plugins, shell commands, etc.
243 #### Format
245 Create commands are specified as an array of directories to be created.
247 #### Example
249 ```yaml
250 - create:
251     - ~/projects
252     - ~/downloads
253     - ~/.vim/undo-history
256 ### Shell
258 Shell commands specify shell commands to be run. Shell commands are run in the
259 base directory (that is specified when running the installer).
261 #### Format
263 Shell commands can be specified in several different ways. The simplest way is
264 just to specify a command as a string containing the command to be run.
266 Another way is to specify a two element array where the first element is the
267 shell command and the second is an optional human-readable description.
269 Shell commands support an extended syntax as well, which provides more
270 fine-grained control. A command can be specified as a dictionary that contains
271 the command to be run, a description, whether to suppress outputting the
272 command in the display via `quiet`,  and whether `stdin`, `stdout`,
273 and `stderr` are enabled. In this syntax, all keys are optional except for the
274 command itself.
276 #### Example
278 ```yaml
279 - shell:
280   - chsh -s $(which zsh)
281   - [chsh -s $(which zsh), Making zsh the default shell]
282   -
283     command: read var && echo Your variable is $var
284     stdin: true
285     stdout: true
286     description: Reading and printing variable
287     quiet: true
288   -
289     command: read fail
290     stderr: true
293 ### Clean
295 Clean commands specify directories that should be checked for dead symbolic
296 links. These dead links are removed automatically. Only dead links that point
297 to the dotfiles directory are removed unless the `force` option is set to
298 `true`.
300 #### Format
302 Clean commands are specified as an array of directories to be cleaned.
304 Clean commands support an extended configuration syntax. In this type of
305 configuration, commands are specified as directory paths mapping to options. If
306 the `force` option is set to `true`, dead links are removed even if they don't
307 point to a file inside the dotfiles directory.
309 #### Example
311 ```yaml
312 - clean: ['~']
314 - clean:
315     ~/.config:
316       force: true
319 ### Defaults
321 Default options for plugins can be specified so that options don't have to be
322 repeated many times. This can be very useful to use with the link command, for
323 example.
325 Defaults apply to all commands that follow setting the defaults. Defaults can
326 be set multiple times; each change replaces the defaults with a new set of
327 options.
329 #### Format
331 Defaults are specified as a dictionary mapping action names to settings, which
332 are dictionaries from option names to values.
334 #### Example
336 ```yaml
337 - defaults:
338     link:
339       create: true
340       relink: true
343 ### Plugins
345 Dotbot also supports custom directives implemented by plugins. Plugins are
346 implemented as subclasses of `dotbot.Plugin`, so they must implement
347 `can_handle()` and `handle()`. The `can_handle()` method should return `True`
348 if the plugin can handle an action with the given name. The `handle()` method
349 should do something and return whether or not it completed successfully.
351 All built-in Dotbot directives are written as plugins that are loaded by
352 default, so those can be used as a reference when writing custom plugins.
354 Plugins are loaded using the `--plugin` and `--plugin-dir` options, using
355 either absolute paths or paths relative to the base directory. It is
356 recommended that these options are added directly to the `install` script.
358 ## Wiki
360 Check out the [Dotbot wiki][wiki] for more information, tips and tricks,
361 user-contributed plugins, and more.
363 ## Contributing
365 Do you have a feature request, bug report, or patch? Great! See
366 [CONTRIBUTING.md][contributing] for information on what you can do about that.
368 ## Packaging
370 1. Update version information.
372 2. Build the package using ``python setup.py sdist bdist_wheel``.
374 3. Sign and upload the package using ``twine upload -s dist/*``.
376 ## License
378 Copyright (c) 2014-2019 Anish Athalye. Released under the MIT License. See
379 [LICENSE.md][license] for details.
381 [PyPI]: https://pypi.org/project/dotbot/
382 [init-dotfiles]: https://github.com/Vaelatern/init-dotfiles
383 [dotfiles-template]: https://github.com/anishathalye/dotfiles_template
384 [inspiration]: https://github.com/anishathalye/dotbot/wiki/Users
385 [managing-dotfiles-post]: http://www.anishathalye.com/2014/08/03/managing-your-dotfiles/
386 [json-equivalent]: https://gist.github.com/anishathalye/84bd6ba1dbe936e05141e07ec45f5fd4
387 [json2yaml]: https://www.json2yaml.com/
388 [wiki]: https://github.com/anishathalye/dotbot/wiki
389 [contributing]: CONTRIBUTING.md
390 [license]: LICENSE.md