#!/usr/bin/env bash # Every directory under config/dot is claimed by exactly one of # link-dotfiles' three lists -- universal (both roles), desktop, or handled # (linked or consumed some other way in that script). The failure this # prevents is quiet: a new dot directory added to the repo but classified # nowhere links on no server, or on every server, depending on which list the # author forgot -- and nothing says so until a machine is missing its config. # # The lists are lifted from the script itself rather than restated here, so # renaming them fails loudly instead of freezing a stale copy. set -uo pipefail repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" link_dotfiles="$repo_dir/setup/scripts/link-dotfiles" dot_dir="$repo_dir/config/dot" findings=() note() { findings+=("$1"); } lists="$(sed -n '/^universal_dirs=(/,/^handled_dirs=(.*)$/p' "$link_dotfiles")" if [[ -z "$lists" ]]; then printf 'dotfile classification contract: link-dotfiles no longer defines the three lists\n' >&2 exit 1 fi eval "$lists" claimed=("${universal_dirs[@]}" "${desktop_dirs[@]}" "${handled_dirs[@]}") for dir in "$dot_dir"/*/; do name="$(basename "$dir")" hits=0 for entry in "${claimed[@]}"; do [[ "$entry" == "$name" ]] && hits=$((hits + 1)) done if (( hits == 0 )); then note "config/dot/$name is claimed by no list, so servers silently skip or acquire it" elif (( hits > 1 )); then note "config/dot/$name is claimed by $hits lists" fi done for entry in "${claimed[@]}"; do [[ -d "$dot_dir/$entry" ]] \ || note "link-dotfiles classifies '$entry', which config/dot does not contain" done if (( ${#findings[@]} > 0 )); then mapfile -t findings < <(printf '%s\n' "${findings[@]}" | sort -u) printf 'dotfile classification contract: %d finding(s)\n' "${#findings[@]}" >&2 printf ' - %s\n' "${findings[@]}" >&2 exit 1 fi printf 'dotfile classification contract: PASS (%d directories classified)\n' "${#claimed[@]}"