Goal: one source of truth per thing. Kill copy / dual-maintenance. Right tool per scope.
- chezmoi source:
~/.local/share/chezmoi(git repo) — manages$HOMEdotfiles. Keep. .chezmoiscripts/— ~25run_*scripts. Mix of system-scope and user-scope.00-clone-repos.sh.tmplclones repos with an:up/:downconvention::up→~/Projects/<host>/<owner>/<repo>(development clone):down→~/.local/share/own-scripts/<host>/<owner>/<repo>(runtime clone, script repos):down→~/.config/...(config repos: hypr, nvim — single clone, fine)
- Dual-cloned repos (the pain):
scripts,dofus-scripts,security-and-privacy— each cloned twice. Edit in:up, push,:downpulls. Two working copies. ~/.local/binis on PATH — holdswm(chezmoi-managed) + venv shims. Your script repos are NOT on PATH.- PATH exports live in
.zshrc(interactive only) — not.zshenv. systemd user units / hyprexecdon't see custom PATH. - No
.chezmoiignore.
Each owned script repo is cloned twice. Collapse to ONE.
- Pick single home per repo:
~/Projects/<host>/<owner>/<repo>. That clone = dev and runtime. - Affected repos:
scripts,dofus-scripts,security-and-privacy. - Edit
00-clone-repos.sh.tmpl: drop the:up/:downsplit. One entry per repo, one target dir. - Delete
~/.local/share/own-scripts/once nothing references it. - Result: edit → commit → push = done. No second clone, no
git pullof a deployed copy.
- In each script repo, put executables in a
bin/subdir (keep README,lib/, tests OFF PATH). - Split sourced libs (functions/aliases/env — must be
sourced) into ashell/dir. - Move ALL
export PATH=lines from.zshrc→.zshenv, so hyprexec, systemd user units, cron see them. Use array form:typeset -U path path=( "$HOME/Projects/github/quantumfate/scripts/bin" $path )
- Add each repo's
bin/to PATH the same way. - One source loop in
.zshrcreplaces all manual sourcing:for f in "$HOME/Projects/github/quantumfate/scripts/shell/"*.zsh(N); do source "$f"; done
- Confirm executable bit is committed (
chmod +xbefore commit; fresh clone must stay executable).
PATH = first match wins. Prevent personal scripts shadowing system binaries (e.g. nvim).
- Prefix all personal executables with
,(comma) —,backup,,tag-photos. No system binary starts with,→ zero shadow risk + own Tab-completion namespace. - Alternative/extra: append script
bin/to PATH (system binary wins on collision). - Optional: pre-commit hook in script repos that flags any script name already on PATH.
System-scope .chezmoiscripts are out of chezmoi's scope. Move to an Ansible localhost playbook — modules give idempotency for free, deletes hand-rolled guards.
System-scope scripts to convert:
00-install-sudoers, 01-install-layout, 01-install-ssh-keys, 05-install-yay,
06-install-dev-env-packages, 07-install-cockpit-vm-kvm, 08-configure-tty,
09-change-login-shell, 11-setup-docker, 12-install-dms-greeter,
12-install-epp-performance, 13-install-clight-geoclue, 14-restart-clight, install-packages
- New repo (or dir)
system/withplaybook.yml. - Map each to real modules:
- login shell →
ansible.builtin.user:(shell:) - services / display manager →
ansible.builtin.systemd:(enabled/state) - packages →
community.general.pacman: /etcfiles →ansible.builtin.copy/template/lineinfile/blockinfile- yay / AUR helper bootstrap →
ansible.builtin.git:+ build step
- login shell →
- Genuinely odd one-shots that don't map to a module →
ansible.builtin.script:wrapping the existing script. - Track packages:
pacman -Qqe > packages.txt, restore via apacman:task. - Run:
ansible-pull -U <system-repo> playbook.yml --ask-become-pass.
A script that just writes/edits a config file is a smell — let chezmoi own the file instead, then delete the script.
- Review:
02-xdg,03-install-user-units,04-install-desktop-entries,05-install-userjs-for-browser,05-prepare-nvim-deps,00-finalise-theme,20-do-additional-theming. - Each: writes a static file → make it a chezmoi-managed file. Genuine action → keep as
run_onchange_.
Fresh machine:
pacman -S ansible chezmoi gitansible-pull -U <system-repo> playbook.yml --ask-become-pass→ system / distro scopechezmoi init --apply <dotfiles-repo>→$HOMEscope (clones script repos once, onto PATH)
- chezmoi →
$HOMEdotfiles only. - Ansible → system / distro scope.
- Script repos → single clone,
bin/on PATH,,-prefixed, no manual sourcing. - Deleted:
~/.local/share/own-scripts/,:up/:downlogic, hand-rolled idempotency guards, dual-maintenance.