Skip to content
benjosuaPublic

About

Unix-first ergonomic dotfile manager in Rust

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dot

dot is a Unix-first dotfile manager written in Rust.

It is designed around a few defaults:

  • top-level directories are packages
  • symlink is the default target kind
  • .tmpl files render automatically
  • state and render cache live in XDG directories, not in your repo
  • planning is explicit and safe before mutation

Commands

dot init
dot plan [packages...]
dot apply [packages...]
dot status [packages...]
dot undeploy [packages...]
dot doctor [packages...]

Global flags:

--repo <path>
--host <name>
--verbose
--json
--yes
--overwrite-unmanaged
--overwrite-drift
--allow-privileged
--no-render-diff

Layout

With a Stow-style repo:

dotfiles/
  zsh/
    .zshrc
  git/
    .config/git/config.tmpl
  assets/
    wallpaper.png

dot plan maps those files to:

  • zsh/.zshrc -> ~/.zshrc
  • git/.config/git/config.tmpl -> ~/.config/git/config
  • assets/wallpaper.png -> ~/.local/share/... only when you override it in dot.toml

Config

dot.toml is optional. If present, it lets you override targets, kinds, modes, and selectors.

[settings]
default_kind = "symlink"
render_suffix = ".tmpl"
collision_policy = "error"

[settings.conflicts]
unmanaged = "block"
managed = "block"
privileged = "skip_package"
merge_tool = "opendiff"

[variables]
email = "user@example.test"

[packages.git.files."git/.config/git/config.tmpl"]
target = "~/.config/git/config"
kind = "render"

[packages.assets.files."assets/wallpaper.png"]
target = "~/.local/share/wallpaper.png"
kind = "copy"
mode = "0644"

[packages.machine.files."machine/.config/app/config.toml"]
target = "~/.config/app/config.toml"
kind = "render"
when.os = ["linux", "macos"]
when.host = ["laptop", "desktop"]

[packages.git.files."git/.config/git/config.tmpl".conflicts]
managed = "merge"

[packages.machine.conflicts]
privileged = "apply"

Conflict policy precedence is file -> package -> settings. Available actions are:

  • unmanaged = "block" | "overwrite" | "merge"
  • managed = "block" | "overwrite" | "merge"
  • privileged = "skip_package" | "apply"

Safety

  • plan and apply share the same planner
  • replacements are first-class operations
  • unmanaged targets and managed drift are governed by explicit conflict policy
  • --overwrite-unmanaged and --overwrite-drift are one-shot overrides
  • --yes applies both overwrite overrides for compatibility with confirmation-style workflows
  • merge-required conflicts print diff and merge-tool guidance without launching tools automatically
  • packages that require privilege are skipped by default unless you pass --allow-privileged
  • unreadable targets are surfaced as privileged inspection steps
  • apply refuses to run when the planner reports validation errors

Development

cargo fmt
cargo test

About

Unix-first ergonomic dotfile manager in Rust

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages