#!/usr/bin/env bash # One command, whole answer: is this machine's dotfiles state committed, # pushed, and does the package manifest still match reality? # # With --nag it prints nothing when everything is clean. That silence is the # point: a login banner that always fires is a banner you stop reading. set -uo pipefail REPO="${DOTFILES:-$HOME/.dotfiles}" HOST="${DOTFILES_HOST:-$(hostname | tr '[:upper:]' '[:lower:]')}" NAG=0; [[ "${1:-}" == "--nag" ]] && NAG=1 cd "$REPO" 2>/dev/null || exit 0 dirty=$(git status --porcelain 2>/dev/null | wc -l) ahead=0; behind=0 if git rev-parse --abbrev-ref '@{u}' >/dev/null 2>&1; then read -r behind ahead < <(git rev-list --left-right --count '@{u}...HEAD' 2>/dev/null || echo "0 0") fi pkgdrift=0 tmp=$(mktemp) if command -v pacman >/dev/null 2>&1; then pacman -Qqen | sort > "$tmp" [[ -f "packages/${HOST}.pacman" ]] && ! diff -q "$tmp" "packages/${HOST}.pacman" >/dev/null && pkgdrift=1 elif command -v apt-mark >/dev/null 2>&1; then apt-mark showmanual | sort > "$tmp" [[ -f "packages/${HOST}.apt" ]] && ! diff -q "$tmp" "packages/${HOST}.apt" >/dev/null && pkgdrift=1 fi rm -f "$tmp" if (( NAG )); then (( dirty == 0 && ahead == 0 && behind == 0 && pkgdrift == 0 )) && exit 0 printf '\033[33mdotfiles:\033[0m' (( dirty )) && printf ' %d uncommitted' "$dirty" (( ahead )) && printf ' %d to push' "$ahead" (( behind )) && printf ' %d to pull' "$behind" (( pkgdrift )) && printf ' packages changed' printf ' \033[2m(dots)\033[0m\n' exit 0 fi echo "repo: $REPO [$HOST]" echo "branch: $(git rev-parse --abbrev-ref HEAD) ahead $ahead, behind $behind" echo "dirty: $dirty file(s)" echo "packages: $( ((pkgdrift)) && echo 'manifest is stale — run pkg-snapshot' || echo 'manifest matches' )" (( dirty )) && { echo; git status --short; } exit 0