
The validation is not yet enabled on CI checks because there exist too many errors in existing rule descriptions at the moment.
90 lines
3.3 KiB
Bash
Executable File
90 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Validate file inclusion and cross-references.
|
|
#
|
|
# This script is parametrized by this environment variable:
|
|
# * TOPLEVEL: $TOPLEVEL/rules and $TOPLEVEL/shared_content will be validated.
|
|
#
|
|
# The script exists with a non-zero value when an unexpected error happened or
|
|
# there are asciidoc validation errors.
|
|
#
|
|
# Validation errors are reported on stderr.
|
|
#
|
|
# Implementation details:
|
|
#
|
|
# The validation of file inclusion and cross-references needs to be done
|
|
# on all rule descriptions, including the default, language-agnostic
|
|
# description, with rspecator-view. Otherwise, a rule could drop an include
|
|
# of a shared_content asciidoc and that file could become unused.
|
|
#
|
|
# We use a custom asciidoctor with extra logging for this purpose.
|
|
# The format for the interesting log entries are:
|
|
# asciidoctor: INFO: ASCIIDOC LOGGER MAIN FILE: $PATH
|
|
# asciidoctor: INFO: ASCIIDOC LOGGER INCLUDED: $PATH
|
|
# asciidoctor: INFO: ASCIIDOC LOGGER CROSSREFERENCE: $RULEID cross-references $PATH
|
|
# asciidoctor: INFO: ASCIIDOC LOGGER DIFF: $VALIDATION_FAILURE_MESSAGE
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
|
|
TOPLEVEL="$(realpath "${TOPLEVEL}")"
|
|
RULES_DIR="${TOPLEVEL}/rules"
|
|
SHARED_CONTENT_DIR="${TOPLEVEL}/shared_content"
|
|
TMPOUT_DIR="$(mktemp -d)"
|
|
|
|
exit_code=0
|
|
|
|
grep_nofail() {
|
|
# Grep but always exit with 0 when there are no matches.
|
|
# Yet, exit with non-zero if an error occured.
|
|
grep "$@" || [ "$?" == "1" ]
|
|
}
|
|
|
|
extract_messages_from_log() {
|
|
# The first 3 columns of the log are not relevant.
|
|
# The 4th (and any that follows if ':' is used in the message)
|
|
# provides the relevant validation error message.
|
|
cut -d ':' -f 4- | sort -u
|
|
}
|
|
|
|
find "${RULES_DIR}" -name 'rule.adoc' \
|
|
| xargs "${SCRIPT_DIR}/custom-asciidoctor" -a rspecator-view --verbose -R "${RULES_DIR}" -D "${TMPOUT_DIR}" 2>&1 \
|
|
| grep_nofail -e 'ASCIIDOC LOGGER' \
|
|
> "${TMPOUT_DIR}/asciidoc_introspection"
|
|
|
|
cross_references=$(grep_nofail -e 'CROSSREFERENCE' "${TMPOUT_DIR}/asciidoc_introspection" | extract_messages_from_log)
|
|
if [[ -n "$cross_references" ]]; then
|
|
echo >&2 'ERROR: Some rules try to include content from unallowed directories.'
|
|
echo >&2 'To share content between rules, you should use the "shared_content" folder at the root of the repository.'
|
|
echo >&2 'List of errors:'
|
|
echo >&2 "${cross_references}"
|
|
exit_code=1
|
|
fi
|
|
|
|
grep_nofail -Pe '(INCLUDE|MAIN FILE)' "${TMPOUT_DIR}/asciidoc_introspection" \
|
|
| extract_messages_from_log \
|
|
> "${TMPOUT_DIR}/used_asciidoc_files"
|
|
|
|
git ls-files --cached -- "${RULES_DIR}/**.adoc" "${SHARED_CONTENT_DIR}/**.adoc" \
|
|
| xargs realpath \
|
|
> "${TMPOUT_DIR}/all_asciidoc_files"
|
|
|
|
orphans=$(comm -1 -3 <(sort -u "${TMPOUT_DIR}/used_asciidoc_files") <(sort -u "${TMPOUT_DIR}/all_asciidoc_files"))
|
|
if [[ -n "$orphans" ]]
|
|
then
|
|
printf >&2 'ERROR: These adoc files are not included anywhere:\n-----\n%s\n-----\n' "$orphans"
|
|
exit_code=1
|
|
fi
|
|
|
|
bad_diffs=$(grep_nofail -e 'DIFF' "${TMPOUT_DIR}/asciidoc_introspection" | extract_messages_from_log)
|
|
if [[ -n "$bad_diffs" ]]
|
|
then
|
|
printf >&2 'ERROR: Diff highlighting is used incorrectly:\n-----\n%s\n-----\n' "$bad_diffs"
|
|
if [[ -n "${RUNNING_CI_INTEGRATION_TEST:-}" ]]
|
|
then
|
|
exit_code=1 # FIXME: there are currently validation errors in the repo. Unconditionally enable this line when they are all fixed.
|
|
fi
|
|
fi
|
|
|
|
exit $exit_code
|