diff --git a/.github/workflows/validate-content.yml b/.github/workflows/validate-content.yml new file mode 100644 index 000000000..0a50cbd98 --- /dev/null +++ b/.github/workflows/validate-content.yml @@ -0,0 +1,28 @@ +name: Validate content +on: + push: + pull_request: + branches: [master, release/*] + schedule: + - cron: '0 5 * * 1' # Every Monday 5 AM UTC + +jobs: + validate-flags: + name: Validate flags + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + - os: macos-latest + - os: windows-latest + runs-on: ${{ matrix.os }} + steps: + - name: Download source + uses: actions/checkout@v4 + - name: Install Crystal + uses: crystal-lang/install-crystal@v1 + with: + crystal: nightly + - name: Run test script + run: scripts/validate-flags.sh diff --git a/scripts/validate-flags.sh b/scripts/validate-flags.sh new file mode 100755 index 000000000..e5aafdfad --- /dev/null +++ b/scripts/validate-flags.sh @@ -0,0 +1,32 @@ +#! /bin/sh + +set -eu + +CRYSTAL=${CRYSTAL:-crystal} +CRYSTAL_PATH="$($CRYSTAL env CRYSTAL_PATH)" +STDLIB_SRC="${CRYSTAL_PATH#*:}" # stdlib source directory is the last entry in CRYSTAL_PATH + +filter_missing() { + missing=0 + + while read -r word; do + grep -q "\`$word\`" docs/syntax_and_semantics/compile_time_flags.md || { + [ ${missing} -eq 0 ] && echo "# Missing ${1} flags:" + echo "$word" + missing=1 + } + done + return ${missing} +} + +status=0 +find "${STDLIB_SRC}" -name '*.cr' -type f -not -path "${STDLIB_SRC}/compiler/**" -print0 \ + | xargs -0 "${CRYSTAL}" tool flags \ + | filter_missing "stdlib" || status=1 + +{ + ${CRYSTAL} tool flags "${STDLIB_SRC}/compiler" + grep --no-file -o -R -P '(?<=has_flag\?[( ]")[^"]+' "${STDLIB_SRC}/compiler" +} | sort -u | filter_missing "compiler" || status=1 + +exit ${status}