A zero-dependency, self-contained dotfile bootstrapper written in Bash. Deploy packages and symlink dotfiles with a single command.
sow is a single shell script with no external dependencies beyond Bash itself. Add it to your dotfiles repository as a Git submodule and you can bootstrap any machine with just git clone and git submodule update -- no package manager, no installer, no runtime needed.
sow [COMMAND] [OPTION]...
| Command | Description |
|---|---|
deploy |
Deploy packages and/or dotfiles |
help |
Display usage information |
| Option | Description |
|---|---|
-p |
Target packages only |
-d |
Target dotfiles only |
-n |
Dry run; print actions without executing them |
-f |
Force; replace conflicting files and links instead of failing |
By default (no -p or -d), both packages and dotfiles are deployed.
Defines the package manager command and the list of packages to install. This file is sourced as Bash.
install=(paru -S --needed --noconfirm)
pkgs=(
git
neovim
zed
)install-- array containing the install command and its flags.pkgs-- array of package names to install.
Defines indexed arrays of alternating source and destination paths. This file is sourced as Bash.
links=(
./test "$HOME/.config/test"
)
copies=(
./rules.md "$HOME/.config/example/rules.md"
)Each source must be followed by its destination. Sources may appear more than once, but duplicate destinations across both arrays are rejected before deployment.
linkscreates symbolic links, creating directories as needed. Matching links are skipped; conflicting files or links stop deployment with an error. Unrelated files and links are left untouched. With-f, conflicting files and links are removed and replaced, which is useful after moving the dotfiles repository; a directory in the way of a file is never removed and still fails.copiescopies regular files withcp -f; symbolic links at the destination are replaced.
Dry runs check for conflicts without making changes. If deployment fails, earlier changes are not rolled back.