deezconfigs 0.9.0

Manage deez config files.
Documentation

deezconfigs

license: GPL v3+ GitHub Tag crates.io

Manage deez config files.

deezconfigs will mirror your config files to your $HOME directory (sync) and synchronize them back (rsync). Additionally, you can choose to symlink the files instead (link).

Same idea as GNU Stow or chezmoi, but way simpler, requiring less neuron activation to operate.

Usage

Usage: deez [<options>] <command> [<args>]

Commands:
  sync [<root>|<git>]    Update Home from configs
  rsync [<root>]         Update configs from Home
  link [<root>]          Symlink configs to Home

  status [<root>|<git>]  List files and their status
  diff [<root>|<git>]    Show what has changed
  clean [<root>|<git>]   Remove all configs from Home

Options:
  -h, --help             Show this message and exit
  -V, --version          Show the version and exit
  -v, --verbose          Show files being copied

[!NOTE]

The "config root" can be any directory containing config files. You should, but are not required to, create a .deez file in the root. This lets deezconfigs know it is safe to use, and lets you run deez inside sub-directories.

$ deez sync
Mirror the files in the current root to `$HOME`.
Also create any missing directories.

$ deez sync ~/myconfigs
Use `~/myconfigs` as the config root.

$ deez sync git:git@github.com:qrichert/configs.git
Sync directly from a Git remote (`https://` works too).

$ deez rsync
Sync files from `$HOME` back into the config root.

$ deez link
Create symlinks in `$HOME` instead of copying the files.
Also create any missing directories.

$ deez --help
For more.

Roadmap

  • Command sync.
  • Command rsync.
  • Command link.
  • Command status.
  • Command diff.
  • Command clean.
  • Warn or error if trying to rsync linked config. If you do that it will empty the config files in the root. So add a check to rsync that ensures symlinks don't point at configs in root.
  • Handle case where a directory exists where we expect a file (see TODO comment in all commands).
  • Think about allowing ignore files everywhere (i.e., never sync ignore files).
  • Proper verbose --help section.
  • Refactor tests, there is too much duplication (everything ignore and walk can be tested once for all commands).
  • Refactor argument parsing? Maybe?
  • Add hooks examples (maybe even in --help).
  • Custom Home directory, or document exporting HOME=whatever.
  • Increase test coverage (features are mostly covered, what's missing are tests for the error cases).
  • Perf refactorings for bottlenecks (or for fun).

FAQ

Yet Another Config Manager

I very rarely edit my configuration files. So when I do, I never quite remember how the config manager worked. I wanted a tool so easy that taking 3s to glance at the --help would be enough to remember how to update the configs repo (deez rsync), and mirror the changes to my other environments (deez sync).

That's also why deezconfigs does very little. Instead of making me remberer deez commands, it delegates to tools I use way more often. I much rather nvim or git commit my config files, because those commands are burnt into my muscle memory.

Do I need to use Git?

Not at all. deezconfigs is designed to integrate nicely with Git, but Git is absolutely not a requirement.

Ignore some files

By default, deezconfigs ignores the .git directory at the root, the .ignore and/or .gitignore file at the root (but not elsewhere, although it respects them everywhere), all .deez files, wherever they are (enabling multi-root repos), and the hooks (at the root).

If you want to ignore more files than this, add them to your root .gitignore. Git will let you version the files regardless, just git add -f them.

This, in my mind, strikes a nice balance between configurability and simplicity. You can ignore whatever you want, without squeezing too many heuristics into deezconfigs. It's a Git thing, nothing new to learn.

Copying some files, while linking others

Use mutliple roots. You can have multiple roots (subdirectories) in one repo. Use sync in one, and link in the other.

If you need anything more advanced than that, deezconfigs is likely not the right tool for you.

No templating?

No. It was an idea at first, but hooks are powerful enough to let you do your own templating. It's the same idea as "let Git do its thing". Instead of supporting sub-par templating, deezconfigs defers to hooks. Nothing's stopping you from using a Python script as a hook with some Jinja2 template, or any other language/template engine combination you like.

Unstructured info dump that needs editing

deez requires a .deez file in the config root (or it will ask for confirmation), to prevent yourself from ruining the $HOME directory if ran on the wrong root.

  • Respects .ignore and .gitignore files.
  • list colors out-of-date files in red (respecting NO_COLOR).
  • Smart root finding will be used when 1) no root was explicitly supplied, and 2) the current working directory (default roor) is not a config root (no .deez file). In this case, deezconfigs will look into parent dirs for a .deez file. If one is found, use it as root instead of warning "this is not a deez root".

Hooks

  • You can have hooks: pre-<command>, post-<command>.
  • The extension can be any type of script (it's the file name that counts).
  • The script must be executable and must contain a shebang (#!) if not interpretable by sh directly (e.g., python scripts).
  • This script will be run through sh: sh -c <root>/<thescript> inside the config root directory.
  • Hooks are executed in lexicographic order based on their file name (i.e., post-sync.001.sh will be run before post-sync.002.sh).

deezconfigs provides some basic information to hooks through environment variables:

  • DEEZ_ROOT Absolute path to the config Root. This is equal to pwd on Unix systems, since hooks are run in the root.
  • DEEZ_HOME Absolute path to the Home directory. This is equal to $HOME on Unix systems.
  • DEEZ_VERBOSE Will be true if run in verbose mode, otherwise it will be unset (hint: use [ -n $DEEZ_VERBOSE ] to test for existance).
  • DEEZ_OS Contains the name of the current operating system (e.g, linux, macos, windows, etc.) The name is a re-export of Rust's std::consts::OS.