deezconfigs 0.4.0

Manage deez config files.
Documentation
# deezconfigs

[![license: GPL v3+](https://img.shields.io/badge/license-GPLv3+-blue)](https://www.gnu.org/licenses/gpl-3.0)
![GitHub Tag](https://img.shields.io/github/v/tag/qrichert/deezconfigs?sort=semver&filter=*.*.*&label=release)
[![crates.io](https://img.shields.io/crates/d/deezconfigs?logo=rust&logoColor=white&color=orange)](https://crates.io/crates/deezconfigs)

_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

> [!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` from within sub-directories.

```console
$ 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

- [x] CLI arguments parsing.
- [x] Basic `sync`.
- [x] Protect `$HOME` with a `.deez` file.
- [x] Add `--verbose` mode (use `-V` for version).
- [x] Use Git remote as `sync` root.
- [x] Smart root finder (looks in parents)
- [x] Hooks (pre, post actions)
- [x] Basic `rsync`.
- [ ] Basic `link`.
- [ ] Likely `list` (with up-to-date status for each file).
- [ ] Likely `clean`
- [ ] Refactor argument parsing.
- [ ] Proper verbose `--help` section.
- [ ] ~~Maybe `diff` (difference between source and target).~~
- [ ] ~~Think about templating.~~ (hooks are enough)
- [ ] Increase test coverage (features are mostly covered, what's
      missing are tests for the error cases).

## 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.

## Tips

### 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.

## 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-sync`, `post-sync`, `pre-rsync`,
  `post-rsync`, `pre-link`, `post-link`.
- 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., `bash` or `python` scripts).
- This script will be run through `sh`: `sh -c <root>/<thescript>`
  inside the config root directory.

_deezconfigs_ provides some basic information to hooks through
environment variables:

- `DEEZ_VERBOSE` Will be `true` if run in verbose mode, otherwise it
  will be unset (hint: use `[ -n $DEEZ_VERBOSE ]` to test for
  existance).