diff options
| author | 2026-04-21 01:23:56 +0100 | |
|---|---|---|
| committer | 2026-04-21 01:23:56 +0100 | |
| commit | a26b26c3750723d7aba9a2e22554afff5218f39c (patch) | |
| tree | 5b97cdfe7773cd7de9d43d93d48cc76dc5718623 | |
| parent | 8b070be38755f1af9e340dae84f1a74017efd810 (diff) | |
| download | dotfiles-a26b26c3750723d7aba9a2e22554afff5218f39c.tar.gz dotfiles-a26b26c3750723d7aba9a2e22554afff5218f39c.tar.bz2 dotfiles-a26b26c3750723d7aba9a2e22554afff5218f39c.zip | |
feat(etc,readd): rename etc-drift to etc; add etc-readd + readd
- etc-drift → etc (the main entry point to the /etc subsystem).
- New etc-readd: pull changes from live /etc back into tracked
repo files (the /etc analog of 'chezmoi re-add'). No args
refreshes all tracked files; explicit paths error if the file
isn't already tracked (use etc-add to adopt). Skips unchanged
files silently; runs 'just apply' only when something changed.
- New top-level readd: 'chezmoi re-add' + 'just etc-readd'.
One command to mirror live state back into the repo.
| -rw-r--r-- | .github/copilot-instructions.md | 2 | ||||
| -rw-r--r-- | justfile | 56 |
2 files changed, 54 insertions, 4 deletions
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 2a6fbdb..a72ec26 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -21,7 +21,7 @@ The repo root is a chezmoi source directory. Files targeting `$HOME` use chezmoi - `bootstrap.sh` at the repo root is a POSIX shell script that takes a fresh minimal Arch install (only `base`) to a fully deployed state. It installs prerequisites, enables `%wheel` sudoers, bootstraps `paru-bin` from the AUR, clones the repo, runs `just init`, and optionally invokes `create-efi`. Designed to be curlable: `curl -fsSL .../bootstrap.sh | sh`. - `.chezmoiignore` excludes non-home files (`etc/`, `meta/`, `systemd-units/`, `firefox/`, docs) from deployment to `$HOME`. - `.githooks/` contains git hooks (notably `post-commit` which runs `chezmoi apply`). Activated by `just init`. -- `justfile` provides recipes: `init` (first-time setup), `sync` (apply + fix), `apply`, `fix`, `status`, `pkg-drift`, `dotfile-drift`, `undeclared`, `diff`, `merge`, `groups`, `install`, `install-all`, `add`, `remove`, `services`, `services-enable`, `services-drift`, `etc-drift`, `etc-diff`, `etc-upstream-diff`, `etc-add`, `etc-rm`, `etc-reset`, `etc-untrack`. Run `just` or `just --list` to see them. +- `justfile` provides recipes: `init` (first-time setup), `sync` (apply + fix), `apply`, `readd`, `fix`, `status`, `pkg-drift`, `dotfile-drift`, `undeclared`, `diff`, `merge`, `groups`, `install`, `install-all`, `add`, `remove`, `services`, `services-enable`, `services-drift`, `etc`, `etc-diff`, `etc-upstream-diff`, `etc-add`, `etc-readd`, `etc-rm`, `etc-reset`, `etc-untrack`. Run `just` or `just --list` to see them. ## Window manager @@ -20,6 +20,11 @@ sync: apply fix apply: chezmoi apply -S . +# Re-add changes from live files back into the repo (chezmoi re-add + etc-readd) +readd: + chezmoi re-add + just etc-readd + # Top up missing packages in groups that are already ≥50% installed (never installs new groups) fix: #!/bin/sh @@ -41,8 +46,8 @@ fix: # Inspection # ═══════════════════════════════════════════════════════════════════ -# Show package and dotfile drift (runs pkg-drift + dotfile-drift + etc-drift) -status: dotfile-drift pkg-drift etc-drift +# Show package and dotfile drift (runs pkg-drift + dotfile-drift + etc) +status: dotfile-drift pkg-drift etc # Show package drift: missing packages in adopted groups + undeclared installed packages pkg-drift: @@ -189,7 +194,7 @@ services-drift: # ═══════════════════════════════════════════════════════════════════ # Show /etc drift: package configs modified from defaults, plus user-created files -etc-drift: +etc: #!/usr/bin/env bash set -eo pipefail tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT @@ -334,6 +339,51 @@ etc-add +paths: echo echo "Run 'chezmoi apply' to sync (no-op content-wise, refreshes deploy hash)." +# Re-add changes from live /etc back into the repo (no args = all tracked files) +etc-readd *paths: + #!/usr/bin/env bash + set -eo pipefail + # Build target list: explicit paths, or every tracked repo file. + targets=() + if [ -n "{{ paths }}" ]; then + for raw in {{ paths }}; do + case "$raw" in + *..*|*/./*|./*|../*) echo "error: unsafe path: $raw" >&2; exit 1 ;; + esac + p=${raw#/}; p=${p#etc/} + [ -f "etc/$p" ] || { echo "error: etc/$p is not tracked; use 'just etc-add' to adopt" >&2; exit 1; } + targets+=("$p") + done + else + while IFS= read -r f; do + targets+=("${f#etc/}") + done < <(find etc -type f ! -name .ignore | sort) + fi + changed=0 + for p in "${targets[@]}"; do + live=/etc/$p + repo=etc/$p + [ -e "$live" ] || { echo " missing live: $live (skipped)"; continue; } + [ -f "$live" ] || { echo " not a regular file: $live (skipped)"; continue; } + if [ -r "$live" ]; then + cat -- "$live" > "$repo.tmp" + else + doas cat -- "$live" > "$repo.tmp" + fi + if cmp -s "$repo" "$repo.tmp"; then + rm -f "$repo.tmp" + else + mv "$repo.tmp" "$repo" + echo "re-added: $live -> $repo" + changed=$((changed + 1)) + fi + done + if [ $changed -eq 0 ]; then + echo "no changes" + else + just apply + fi + # Remove one or more files from the repo's etc/ tree (leaves live /etc untouched) etc-rm +paths: #!/usr/bin/env bash |
