1 stable release
Uses new Rust 2024
| 1.0.0 | Jul 8, 2025 |
|---|
#409 in Configuration
22KB
379 lines
Phoebus
Introduction
phoebus is a declarative configuration file manager (not only for dotfiles!) easily integrated with version control systems. phoebus aims to save and apply config files, both system and user files, across machines seemlessly.
Why phoebus
You might want to use phoebus if you want a tool to help you manage your config files that
- It's declarative: one TOML file to manage all your config files
- It's reproducible and automatic: with one command phoebus can recreate all you config files on a new machine
- It's easy to use, minimal but extensible: no unecessary fuss, but you can tune it to your needs
- Has zero interference with other users or with the rest of system
- Integrates with your existing workflow and tools, without requiring you to change them
- Has no lock-in: it takes you no more effort than copying some files to migrate to another tool and it can coexist with any other dotfile/config files management tool
Why not a git repo with symlinks
- symlinks can break: and leave you with a broken config.
- symlinks can affect other users: because you need to move (global) config files.
- phoebus requires less permissions. When you use phoebus to save your config files you just need read permissions, with symlinks you also need write permissions.
- Setting up config files with symlinks on a new machine requires a lot of, error prone, effort or custom scripts.
Installation
If you have cargo installed
cargo install phoebus
How it works
When phoebus is first setup, using phoebus init, it creates the phoebus config file, or simply the config file, if not already existing, and a backend directory; if specified in the config file also a frontend directory is created (you can always create it later).
When the user runs phoebus pull, all and only the files/directories in the backend directory that are mentioned in the phoebus config file are overwritten, the rest is left untouched (we will add some optional "garbage collection technique" in the future), .
When the user runs phoebus refresh, if also a frontend directory is specified in the phoebus config file, then its contents are erased and populated again with symlinks to the files referenced in the phoebus config file.
The directory trees of both the backend directory and the frontend directory is defined in the phoebus config file.
On the contrary, when the user runs phoebus push, the contents of the backend directory overwrite the contents of the files specified in the phoebus config file.
In the config file it's possible to specify some files to ignore in the backend directory (both during phoebus pull and phoebus push operations), while the frontend directory remains uneffected.
So generally speaking, the backend directory stores a copy (more or less updated) of the files specified in the phoebus config file, the frontend directory is a directory that contains symlinks to all the config files and it's used by the user for convenience to read, add and edit config files more easily.
To know more about the commands available run phoebus --help.
Usage
A typical use case is using the backend directory as a version controlled repo, for example using git.
To setup phoebus for the first time, run phoebus init, then run phoebus info to see where are the backend directory and phoebus config file.
Edit the phoebus config file by uncommenting the line of the frontend directory (almost all users would find this feature useful) and choose a path that you know it doesn't contain, and won't contain in the future, any useful file/directory. For example, some good paths are ~/phoebus, ~/my-config-files and /etc/our-config-files, some bad paths are ~/Documents, /tmp/phoebus (using temporary directories it's not recommended because then you have to regenerate the frontend directory after every boot and that's unconvenient).
In the repos list, add a repo entry (the name "repo" is generic here, we're not talking about git repos), for a config file/directory you want phoebus to track, for example to track some bash files you can use these entries (see the default phoebus config file for more)
repos = [
{ source = "~/.bashrc", repo = "shell/bash/bashrc" },
{ source = "~/.bash_profile", repo = "shell/bash/bash_profile" }
]
Now run phoebus pull and the backend directory will have a shell/bash directory containing copies of ~/.bashrc and ~/.bash_profile, named, respectively, bashrc and bash_profile. You can now commit the changes in the backend directory.
Let's say now you edited your config files in your git repo remotely, you do a git pull in the backend directory and you want to update your config files, you can do it with a simple phoebus push.
Notes
- The backend dir is created by symlinking files recursively, while the frontend dir is created by symlinking files and dirs with the first match.
TODO
Bugs
Enhancements
Here are some ideas to improve phoebus, not all of them have to be done or make sense to be done, this is more a brainstorming place.
- Add the possibility to add git repos URLs in the config file, this way updates can be downloaded automatically when running phoebus
- You can temporarly delete all the repos in the backend (preserving the ignored files) as a temp fix for keeping the backend repo "in sync", in the future you should be able to do it with a single repo
- Add post- and pre- hooks (to config
gitautomations likegit pullwhen runningphoebus push, for example) - Add the possibility for extra configurations (not just copying files): set permissions to a file, create symlinks (this is sometimes needed for some programs to be configured, for example to set up NetworkManager with systemd-resolved)
- Rename the backend and frontend directories to something more intuitive (ex: backend -> repos directory)
Dependencies
~7–13MB
~262K SLoC