|
| 1 | +#!/bin/sh |
| 2 | +# This file is part of KASLD - https://github.com/bcoles/kasld |
| 3 | +# |
| 4 | +# check-env-docs — every environment variable the code reads is documented in |
| 5 | +# kasld(1) ENVIRONMENT, and every one documented there is actually read. |
| 6 | +# |
| 7 | +# The audit that prompted this found the environment surface had grown to twelve |
| 8 | +# variables while the design notes described four. Two of them -- KASLD_EXEC_WRAPPER |
| 9 | +# and KASLD_COMPONENT_DIR -- name programs kasld will execute, so an undocumented |
| 10 | +# one is not merely untidy: it is an execution knob nobody reviewing a sudoers |
| 11 | +# rule or a packaging script can see. |
| 12 | +# |
| 13 | +# The same parity check check-manpages applies to flags, applied to getenv(). |
| 14 | +# Documentation alone fixes a surface once; this is what keeps it fixed as the |
| 15 | +# surface grows. |
| 16 | +# |
| 17 | +# A variable counts as documented when it appears in a .B / .BR request inside |
| 18 | +# the ENVIRONMENT section -- an entry, not a passing mention in prose, since the |
| 19 | +# section's own introduction names two of them. |
| 20 | +# |
| 21 | +# Pure text, so it needs no build. |
| 22 | +# --- |
| 23 | +# <bcoles@gmail.com> |
| 24 | + |
| 25 | +set -u |
| 26 | +ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) |
| 27 | +MAN="$ROOT/man/kasld.1" |
| 28 | + |
| 29 | +if [ -t 1 ]; then |
| 30 | + RED=$(printf '\033[31m') |
| 31 | + GREEN=$(printf '\033[32m') |
| 32 | + RESET=$(printf '\033[0m') |
| 33 | +else |
| 34 | + RED= |
| 35 | + GREEN= |
| 36 | + RESET= |
| 37 | +fi |
| 38 | + |
| 39 | +fail=0 |
| 40 | +note() { |
| 41 | + printf '%scheck-env-docs: FAIL%s — %s\n' "$RED" "$RESET" "$1" >&2 |
| 42 | + fail=1 |
| 43 | +} |
| 44 | + |
| 45 | +[ -f "$MAN" ] || { |
| 46 | + note "man/kasld.1 is missing" |
| 47 | + exit 1 |
| 48 | +} |
| 49 | + |
| 50 | +code=$(mktemp) || exit 1 |
| 51 | +documented=$(mktemp) || exit 1 |
| 52 | +trap 'rm -f "$code" "$documented"' EXIT INT TERM |
| 53 | + |
| 54 | +# The variables kasld(1) is answerable for: those read anywhere OUTSIDE |
| 55 | +# src/components/. A component is a standalone program with its own debugging |
| 56 | +# knobs -- KASLD_ZOMBIELOAD_DEBUG, MALI_MIN_COUNT -- and those belong to it, not |
| 57 | +# to the orchestrator's interface. Documenting them here would put 113 |
| 58 | +# components' internals in one page and oblige it to track every one. |
| 59 | +# |
| 60 | +# A variable read in a component AND elsewhere (KASLD_EXPERIMENTAL, |
| 61 | +# KASLD_SYSROOT) is still part of the surface: it is picked up from the |
| 62 | +# non-component reader. Only component-EXCLUSIVE variables are private. |
| 63 | +# |
| 64 | +# src/ only in either case: tests and dev harnesses set these, they do not |
| 65 | +# define them. |
| 66 | +find "$ROOT/src" -name '*.c' -o -name '*.h' | |
| 67 | + grep -v '/components/' | |
| 68 | + xargs grep -hoE 'getenv\("[A-Z_][A-Z_0-9]*"\)' | |
| 69 | + sed 's/getenv("//; s/")//' | sort -u >"$code" |
| 70 | + |
| 71 | +# Names given an ENTRY in the ENVIRONMENT section -- the tag line directly after |
| 72 | +# a .TP. Deliberately not every .B in the section: its introduction names two |
| 73 | +# variables in prose and entries cross-reference other sections, and neither is |
| 74 | +# a definition. One tag may carry several (`.BR CLICOLOR ", " CLICOLOR_FORCE`), |
| 75 | +# so take every uppercase token on that line. |
| 76 | +awk '/^\.SH ENVIRONMENT/ { inb = 1; next } |
| 77 | + /^\.SH / { inb = 0 } |
| 78 | + inb && tag { print; tag = 0 } |
| 79 | + inb && /^\.TP[[:space:]]*$/ { tag = 1 }' "$MAN" | |
| 80 | + grep -oE '[A-Z_][A-Z_0-9]{2,}' | sort -u >"$documented" |
| 81 | + |
| 82 | +n=0 |
| 83 | +while IFS= read -r v; do |
| 84 | + [ -n "$v" ] || continue |
| 85 | + n=$((n + 1)) |
| 86 | + grep -qxF "$v" "$documented" || |
| 87 | + note "$v is read by src/ but has no kasld(1) ENVIRONMENT entry" |
| 88 | +done <"$code" |
| 89 | + |
| 90 | +while IFS= read -r v; do |
| 91 | + [ -n "$v" ] || continue |
| 92 | + grep -qxF "$v" "$code" || |
| 93 | + note "$v has a kasld(1) ENVIRONMENT entry but nothing in src/ reads it" |
| 94 | +done <"$documented" |
| 95 | + |
| 96 | +if [ "$fail" -ne 0 ]; then |
| 97 | + exit 1 |
| 98 | +fi |
| 99 | +printf '%scheck-env-docs: OK%s (%s environment variables, code and kasld(1) agree)\n' \ |
| 100 | + "$GREEN" "$RESET" "$n" |
0 commit comments