#!/usr/bin/env bash set -euo pipefail root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${root}" min_id="${EVERY_CHANNEL_ECP_LINT_MIN_ID:-63}" files=() if [[ "$#" -gt 0 ]]; then for arg in "$@"; do files+=("${arg}") done else while IFS= read -r f; do files+=("${f}") done < <(find evolution/proposals -maxdepth 1 -type f -name 'ECP-*.md' | sort) fi if [[ "${#files[@]}" -eq 0 ]]; then echo "ecp-lint: no ECP files found" exit 0 fi errors=0 check_pattern() { local file="$1" local regex="$2" local message="$3" if ! rg -q --pcre2 "${regex}" "${file}"; then echo "ecp-lint: ${file}: ${message}" >&2 errors=$((errors + 1)) fi } for file in "${files[@]}"; do [[ -f "${file}" ]] || continue base="$(basename "${file}")" if [[ ! "${base}" =~ ^ECP-([0-9]{4})- ]]; then continue fi id=$((10#${BASH_REMATCH[1]})) if (( id < min_id )); then continue fi check_pattern "${file}" '^# ECP-[0-9]{4}:' "missing or invalid title" check_pattern "${file}" '^Status: (Draft|Accepted|Implemented|Superseded|Rejected)$' "missing or invalid Status line" check_pattern "${file}" '^## (Problem|Context|Motivation)\b' "missing Problem/Context/Motivation section" check_pattern "${file}" '^## Decision\b' "missing Decision section" check_pattern "${file}" '^## (Alternatives considered|Alternatives)\b' "missing Alternatives considered section" check_pattern "${file}" '^## (Rollout / teardown|Rollout / teardown plan|Rollout / Reversibility|Rollout|Reversibility)\b' "missing Rollout/teardown (or Reversibility) section" done if (( errors > 0 )); then echo "ecp-lint: failed with ${errors} issue(s)" >&2 exit 1 fi echo "ecp-lint: ok"