#!/usr/bin/env bash # Сторож документации. # # README устаревает молча: порт поменяли в compose.yaml, а в описании остался # старый — и это выясняется через месяц, когда кто-то по нему подключается. # Здесь собраны утверждения README, которые дёшево проверить текстом и дорого # обнаружить сломанными. Стенд поднимать не нужно; запускается в составе # `make config-test`. # # Чего сторож НЕ делает: он не проверяет, что README понятен или полон. Только # то, что перечисленные ниже факты не разошлись с кодом. # # Добавляя проверку, формулируй утверждение так, как оно должно читаться в # отчёте: строка печатается и при успехе, и при провале, поэтому по красной # строке сразу видно, что именно перестало быть правдой. set -euo pipefail readonly ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" readonly README="$ROOT_DIR/README.md" readonly SMOKE="$ROOT_DIR/scripts/stand-smoke.sh" passed=0 fail() { printf 'ОШИБКА: %s\n' "$1" >&2 exit 1 } # check «утверждение» команда... — запускает команду и считает результат. # Успех: «ЗЕЛЁНО: утверждение». Провал: «ОШИБКА: не подтвердилось: утверждение» # и выход с кодом 1. Раньше проверки падали через `set -e` молча: код возврата # был единственным следом, и какая именно проверка не прошла — не сообщалось. check() { local claim="$1" shift if "$@"; then passed=$((passed + 1)) printf 'ЗЕЛЁНО: %s\n' "$claim" else fail "не подтвердилось: $claim" fi } # Порты обеих нод. Ломается ровно тогда, когда порт поменяли в compose.yaml и # забыли документацию — самая частая причина расхождения. ports_documented() { grep -Eq 'нода 1.*28123.*29000' "$README" && grep -Eq 'нода 2.*28124.*29001' "$README" } # Совет про сброс томов. Пароли Postgres и Grafana применяются при создании # тома: без `make clean` смена значений в .env ничего не даёт, и человек # полчаса ищет, почему его не пускает. clean_advice_present() { grep -Eq 'После первого запуска.*`make clean`' "$README" } # Список портов остаётся единым списком. Совпадение точное намеренно: проверка # стережёт не сам факт (он проверен выше), а то, что строку не выдернули из # списка в отдельный абзац при правке соседнего текста. ports_stay_one_list() { grep -Fxq -- '- нода 2 — `http://127.0.0.1:28124`, нативный порт `29001`;' "$README" } # Состав `make config-test`. Разбор пробников добавлен в него отдельной # проверкой, и README должен называть её: иначе читатель считает, что дешёвая # ступень трогает только Compose, и гоняет полный стенд ради того, что видно # без него. Проверка стоит на двух соседних строках — см. ниже про перенос. probe_checks_documented() { awk ' previous == "`make config-test` проверяет Compose, синтаксис Bash и Python, малые проверки" && $0 == "логики пробников и пробельные ошибки в diff без запуска стенда." { found = 1 } {previous = $0} END {exit !found} ' "$README" } # Урок из предшественника: `make up` не трогает уже созданные контейнеры, и # после правки настройки метрик серверы молча работают со старой # конфигурацией. README обязан требовать явный перезапуск. Проверка сверяет # две соседние строки целиком, а не подстроку: так фразу нельзя незаметно # разорвать переносом или переписать наполовину. restart_lesson_present() { awk ' previous == "После изменения `infra/clickhouse/config.d/prometheus.xml` выполните" && $0 == "`docker compose restart clickhouse-01 clickhouse-02`: обычный `make up` не" { found = 1 } {previous = $0} END {exit !found} ' "$README" } # Единица памяти в отчёте проверки — русская «ГБ», а не латинская «GB» # (контракт языка из AGENTS.md). Здесь успех — это отсутствие образца, поэтому # код возврата grep разбирается вручную: 1 — не нашли, и это хорошо; 0 — нашли # латинское; больше 1 — сам grep не отработал, и молчать об этом нельзя. smoke_uses_russian_unit() { local status=0 grep -q '3,4 GB' "$SMOKE" || status=$? case "$status" in 1) return 0 ;; 0) return 1 ;; *) fail "не удалось проверить обозначение единицы памяти в $SMOKE" ;; esac } check 'README перечисляет HTTP- и нативные порты обеих нод' ports_documented check 'README объясняет сброс томов после смены исходных учётных данных' clean_advice_present check 'список портов остаётся единым списком' ports_stay_one_list check 'README перечисляет малые проверки пробников в составе config-test' probe_checks_documented check 'README требует перезапуск ClickHouse после изменения настройки метрик' restart_lesson_present check 'отчёт проверки использует русское обозначение ГБ' smoke_uses_russian_unit printf 'ИТОГ: пройдено %d, ошибок 0\n' "$passed"