2021-05-04 09:58:49 +02:00
|
|
|
#!/bin/bash
|
2021-05-05 07:53:30 +02:00
|
|
|
set -uo pipefail
|
2021-05-04 09:58:49 +02:00
|
|
|
|
2023-07-31 15:37:06 +02:00
|
|
|
# Install script dependencies
|
|
|
|
set -e
|
|
|
|
cd rspec-tools && pipenv install && cd ..
|
|
|
|
set +e
|
|
|
|
|
|
|
|
# This script runs all tests; it doesn't exit at the first failure.
|
|
|
|
exit_code=0
|
|
|
|
|
2022-05-23 14:14:57 +02:00
|
|
|
readonly ALLOWED_RULE_SUB_FOLDERS=['common'];
|
|
|
|
|
2023-07-31 15:37:06 +02:00
|
|
|
# Validate user-visible rule descriptions
|
|
|
|
# i.e., without rspecator-view.
|
|
|
|
./ci/generate_html.sh
|
2021-06-09 11:15:47 +02:00
|
|
|
cd rspec-tools
|
2023-07-31 15:37:06 +02:00
|
|
|
if pipenv run rspec-tools check-description --d ../out; then
|
|
|
|
echo "Rule descriptions are fine"
|
|
|
|
else
|
|
|
|
echo "ERROR: There are invalid rule descriptions"
|
|
|
|
exit_code=1
|
|
|
|
fi
|
2021-06-09 11:15:47 +02:00
|
|
|
cd ..
|
2021-05-04 09:58:49 +02:00
|
|
|
|
2021-06-09 11:15:47 +02:00
|
|
|
# Compute the set of affected rules
|
2022-02-01 13:25:23 +01:00
|
|
|
git fetch origin "$CIRRUS_DEFAULT_BRANCH"
|
2021-06-09 11:15:47 +02:00
|
|
|
branch_base_sha=$(git merge-base FETCH_HEAD HEAD)
|
|
|
|
echo "Comparing against the merge-base: $branch_base_sha"
|
2022-02-01 13:25:23 +01:00
|
|
|
changeset=$(git diff --name-only "$branch_base_sha"..HEAD)
|
2021-06-09 11:15:47 +02:00
|
|
|
affected_rules=$(printf '%s\n' "$changeset" | grep '/S[0-9]\+/' | sed 's:\(.*/S[0-9]\+\)/.*:\1:' | sort | uniq)
|
2023-07-31 15:37:06 +02:00
|
|
|
if printf '%s\n' "$changeset" | grep -qv '/S[0-9]\+/'; then
|
|
|
|
echo "Some rpec tools or shared_content changed, validating all rules"
|
|
|
|
affected_rules=rules/*
|
2021-06-09 11:15:47 +02:00
|
|
|
fi
|
|
|
|
|
2023-07-31 15:37:06 +02:00
|
|
|
# Validate some properties of the asciidoc:
|
2023-08-02 09:21:56 +02:00
|
|
|
#
|
|
|
|
# [properties validated only on affected rules]
|
2023-07-31 15:37:06 +02:00
|
|
|
# * Rules should have at least one language specification,
|
|
|
|
# unless they are closed or deprecated.
|
|
|
|
# * The include:: should have an empty line before and after them.
|
|
|
|
# * Only valid languages can be used as subdirectories in rule directories,
|
|
|
|
# with the exception of ALLOWED_RULE_SUB_FOLDERS.
|
|
|
|
# * Asciidoc files are free or errors and warnings.
|
2023-08-02 09:21:56 +02:00
|
|
|
#
|
|
|
|
# [properties validated always on all rules]
|
2023-07-31 15:37:06 +02:00
|
|
|
# * Rule descriptions can include other asciidoc files from the same rule
|
|
|
|
# directory or from shared_content.
|
|
|
|
# * All asciidoc files are used/included.
|
2021-05-04 09:58:49 +02:00
|
|
|
|
2022-02-03 13:21:42 +01:00
|
|
|
echo "Testing the following rules: ${affected_rules}"
|
2023-07-31 15:37:06 +02:00
|
|
|
supportedLanguages=$(sed 's/ or//' supported_languages.adoc | tr -d '`,')
|
2021-06-09 11:15:47 +02:00
|
|
|
for dir in $affected_rules
|
2020-06-23 11:33:04 +02:00
|
|
|
do
|
2021-06-09 11:15:47 +02:00
|
|
|
if [ ! -d "$dir" ]; then
|
|
|
|
echo "Apparently $dir is deleted, skipping"
|
|
|
|
continue
|
|
|
|
fi
|
2021-01-07 17:15:42 +01:00
|
|
|
dir=${dir%*/}
|
|
|
|
|
|
|
|
# check if there are language specializations
|
2023-07-31 15:37:06 +02:00
|
|
|
subdircount=$(find "$dir" -maxdepth 1 -mindepth 1 -type d | wc -l)
|
|
|
|
if [[ "$subdircount" -eq 0 ]]
|
2021-01-07 17:15:42 +01:00
|
|
|
then
|
|
|
|
# no specializations, that's fine if the rule is deprecated
|
2023-07-31 15:37:06 +02:00
|
|
|
if grep -Pq '"status": "(deprecated|closed)"' "$dir/metadata.json"; then
|
2021-06-08 14:23:48 +02:00
|
|
|
echo "INFO: deprecated generic rule $dir with no language specializations"
|
2020-06-23 11:33:04 +02:00
|
|
|
else
|
2021-06-08 14:23:48 +02:00
|
|
|
echo "ERROR: non-deprecated generic rule $dir with no language specializations"
|
|
|
|
exit_code=1
|
2020-06-23 11:33:04 +02:00
|
|
|
fi
|
2021-01-07 17:15:42 +01:00
|
|
|
else
|
2023-06-22 10:38:01 +02:00
|
|
|
# Make sure include:: clauses are always more than one line away from the previous content
|
|
|
|
# Detect includes stuck to the line before
|
|
|
|
find "$dir" -name "*.adoc" -execdir sh -c 'grep -Pzl "\S[ \t]*\ninclude::" $1 | xargs -r -I@ realpath "$PWD/@"' shell {} \; > stuck
|
|
|
|
# Detect includes stuck to the line after
|
|
|
|
find "$dir" -name "*.adoc" -execdir sh -c 'grep -Pzl "include::[^\[]+\[\]\n[ \t]*[^\n]" $1 | xargs -r -I@ realpath "$PWD/@"' shell {} \; >> stuck
|
|
|
|
if [ -s stuck ]; then
|
2023-07-31 15:37:06 +02:00
|
|
|
echo "ERROR: These adoc files contain an include that is stuck to other content."
|
|
|
|
echo "This may result in broken tags and other display issues."
|
|
|
|
echo "Make sure there is an empty line before and after each include:"
|
|
|
|
cat stuck
|
|
|
|
exit_code=1
|
2023-06-22 10:38:01 +02:00
|
|
|
fi
|
|
|
|
rm -f stuck
|
|
|
|
|
2023-07-31 15:37:06 +02:00
|
|
|
for language in "${dir}"/*/
|
2021-01-07 17:15:42 +01:00
|
|
|
do
|
|
|
|
language=${language%*/}
|
2022-02-01 13:25:23 +01:00
|
|
|
if [[ ! "${supportedLanguages[*]}" == *"${language##*/}"* ]]; then
|
2022-05-23 14:14:57 +02:00
|
|
|
if [[ ! "${ALLOWED_RULE_SUB_FOLDERS[*]}" == *"${language##*/}"* ]]; then
|
|
|
|
echo "ERROR: ${language##*/} is not a supported language"
|
|
|
|
exit_code=1
|
|
|
|
fi
|
2021-01-07 17:15:42 +01:00
|
|
|
else
|
2022-05-23 14:14:57 +02:00
|
|
|
RULE="$language/rule.adoc"
|
|
|
|
if test -f "$RULE"; then
|
2023-07-31 15:37:06 +02:00
|
|
|
# Errors emitted by asciidoctor don't include the full path.
|
|
|
|
# https://github.com/asciidoctor/asciidoctor/issues/3414
|
|
|
|
# To ease debugging, we copy the rule.adoc into tmp_SXYZ_language.adoc
|
|
|
|
# and run asciidoctor on them instead.
|
|
|
|
# We add the implicit header "Description" to prevent an asciidoctor warning.
|
2022-05-23 14:14:57 +02:00
|
|
|
TMP_ADOC="$language/tmp_$(basename "${dir}")_${language##*/}.adoc"
|
|
|
|
echo "== Description" > "$TMP_ADOC"
|
|
|
|
cat "$RULE" >> "$TMP_ADOC"
|
|
|
|
else
|
|
|
|
echo "ERROR: no asciidoc file $RULE"
|
|
|
|
exit_code=1
|
|
|
|
fi
|
2021-01-07 17:15:42 +01:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
2020-06-23 11:33:04 +02:00
|
|
|
done
|
|
|
|
|
2023-07-31 15:37:06 +02:00
|
|
|
# Run asciidoctor and fail if a warning is emitted.
|
|
|
|
# Use the tmp_SXYZ_language.adoc files (see note above).
|
2022-02-07 18:22:30 +01:00
|
|
|
ADOC_COUNT=$(find rules -name "tmp*.adoc" | wc -l)
|
2022-02-08 11:00:03 +01:00
|
|
|
if (( ADOC_COUNT > 0 )); then
|
2022-02-07 18:22:30 +01:00
|
|
|
if asciidoctor --failure-level=WARNING -o /dev/null rules/*/*/tmp*.adoc; then
|
2023-07-31 15:37:06 +02:00
|
|
|
if asciidoctor -a rspecator-view --failure-level=WARNING -o /dev/null rules/*/*/tmp*.adoc; then
|
|
|
|
echo "${ADOC_COUNT} documents checked with success"
|
|
|
|
else
|
|
|
|
echo "ERROR: malformed asciidoc files in rspecator-view"
|
|
|
|
exit_code=1
|
|
|
|
fi
|
2022-02-07 18:22:30 +01:00
|
|
|
else
|
|
|
|
echo "ERROR: malformed asciidoc files"
|
|
|
|
exit_code=1
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo "No new asciidoc file changed"
|
|
|
|
fi
|
2023-07-20 12:17:32 +02:00
|
|
|
find rules -name "tmp*.adoc" -delete
|
|
|
|
|
2023-08-03 17:21:40 +02:00
|
|
|
# Validate file inclusion, cross-references, and other properties.
|
2023-08-02 09:21:56 +02:00
|
|
|
#
|
2023-08-03 17:21:40 +02:00
|
|
|
# This part of the validation is extracted in a separate script,
|
|
|
|
# which is covered by tests unlike what is above this line.
|
|
|
|
TOPLEVEL=. ./ci/asciidoc_validation/validate.sh || exit_code=1
|
2023-08-02 09:21:56 +02:00
|
|
|
|
2022-02-01 13:25:23 +01:00
|
|
|
if (( exit_code == 0 )); then
|
2023-07-31 15:37:06 +02:00
|
|
|
echo "Success"
|
2021-06-09 11:15:47 +02:00
|
|
|
else
|
2023-07-31 15:37:06 +02:00
|
|
|
echo "There were errors"
|
2021-06-09 11:15:47 +02:00
|
|
|
fi
|
2021-05-03 21:31:58 +02:00
|
|
|
exit $exit_code
|