From 3b2beec0ca95ce863a6cd4f7bf7be24247f96acd Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Wed, 13 May 2026 13:43:21 +0100 Subject: refactor(etc): narrow etc-status to tracked-file drift The old etc-status scanned all of /etc (pacman -Qkk for modified backup configs, then 'find /etc | xargs pacman -Qo' for unowned files), producing a discovery report of things we might want to track. That was useful when seeding the repo but is slow and misaligned with dotfiles-status, which only reports drift on files chezmoi already manages. Rewrite etc-status to mirror that model: iterate etc/, render .tmpl sources, and cmp against the live /etc file. Report 'modified' or 'missing' per tracked path. Runs in under a second and matches the semantics of 'just status'. Drop the now-unused etc/.ignore and update README. --- justfile | 48 +++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) (limited to 'justfile') diff --git a/justfile b/justfile index 32d831e..0a74263 100644 --- a/justfile +++ b/justfile @@ -566,42 +566,28 @@ unit-forget group +units: # /etc domain # ═══════════════════════════════════════════════════════════════════ -# Show /etc drift: package configs modified from defaults, plus user-created files +# Show /etc drift: repo-tracked files that differ from or are missing on the host etc-status: #!/usr/bin/env bash set -eo pipefail tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT - - find etc -type f ! -name .ignore 2>/dev/null \ - | sed 's|^etc/|/etc/|; s|\.tmpl$||' | sort -u > "$tmp/managed" - - patterns=() - if [ -f etc/.ignore ]; then - while IFS= read -r line; do - [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue - patterns+=("$line") - done < etc/.ignore - fi - - keep() { - local path=$1 - grep -qxF "$path" "$tmp/managed" && return 1 - for pat in ${patterns[@]+"${patterns[@]}"}; do - [[ "$path" == $pat ]] && return 1 - done - return 0 - } - echo "=== /etc drift ===" - echo "--- modified package configs ---" - { pacman -Qkk 2>/dev/null | grep -oP '^backup file:\s+[^:]+:\s+\K/etc/\S+' || true; } | sort -u \ - | while IFS= read -r p; do keep "$p" && echo " modified: $p"; :; done - - echo "--- user-created (no owning package) ---" - { find /etc -xdev -type f -print0 2>/dev/null \ - | xargs -0 pacman -Qo 2>&1 >/dev/null \ - | sed -n 's/^error: No package owns //p' || true; } | sort -u \ - | while IFS= read -r p; do keep "$p" && echo " unowned: $p"; :; done + while IFS= read -r repo; do + live=/etc/${repo#etc/}; live=${live%.tmpl} + if [ "${repo%.tmpl}" != "$repo" ]; then + src=$tmp/rendered + chezmoi execute-template <"$repo" >"$src" + else + src=$repo + fi + if [ -r "$live" ]; then + cmp -s "$src" "$live" || echo " modified: $live" + elif doas test -f "$live" 2>/dev/null; then + doas cat "$live" | cmp -s "$src" - || echo " modified: $live" + else + echo " missing: $live" + fi + done < <(find etc -type f ! -name .ignore | sort) # Diff repo-managed etc/ against live /etc/ (all managed files if no args) etc-diff *paths: -- cgit v1.3.1