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
2022-05-23 14:14:57 +02:00
readonly ALLOWED_RULE_SUB_FOLDERS = [ 'common' ] ;
2023-07-31 15:11:14 +02:00
# Install script dependencies
2021-06-09 11:15:47 +02:00
cd rspec-tools
2023-07-31 15:11:14 +02:00
pipenv install
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:11:14 +02:00
affected_tooling = $( printf '%s\n' " $changeset " | grep -v '/S[0-9]\+/' )
if [ -n " $affected_tooling " ] ; then
echo "Some rpec tools are changed, validating all rules"
affected_rules = rules/*
2021-06-09 11:15:47 +02:00
fi
2023-07-31 15:11:14 +02:00
exit_code = 0
./ci/generate_html.sh
PATH_WITH_VARIABLE = " $( realpath ./ci/replace_variables_in_path.sh) "
cd rspec-tools
if pipenv run rspec-tools check-description --d ../out; then
echo "rule.adoc is fine"
else
echo "ERROR: There are invalid rule.adoc"
exit_code = 1
fi
cd ..
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:11:14 +02:00
readonly ROOT = $PWD
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 %*/ }
2023-07-31 15:11:14 +02:00
subdircount = $( find " $dir " -maxdepth 1 -type d | wc -l)
2021-01-07 17:15:42 +01:00
# check if there are language specializations
2023-07-31 15:11:14 +02:00
if [ [ " $subdircount " -eq 1 ] ]
2021-01-07 17:15:42 +01:00
then
# no specializations, that's fine if the rule is deprecated
2023-07-31 15:11:14 +02:00
if grep -q '"status": "deprecated"\|"status": "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-07-31 15:11:14 +02:00
#validate asciidoc
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:11:14 +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:11:14 +02:00
supportedLanguages = $( sed 's/ or//' supported_languages.adoc | tr -d '`,' )
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:11:14 +02:00
# We build this filename that describes the path to workaround the fact that asciidoctor will not tell
# us the path of the file in case of error.
# We can remove it if https://github.com/asciidoctor/asciidoctor/issues/3414 is fixed.
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
2022-02-07 18:22:30 +01:00
2022-02-01 13:25:23 +01:00
# Check that all adoc are included
2023-06-02 19:10:20 +02:00
2023-06-22 11:45:41 +02:00
# Files can be included through variables. We create a list of variables
2023-06-02 19:10:20 +02:00
# These paths are relative to the file where they are _included_, not where they are _declared_
# Which is why we need to create this list and cannot do anything with the paths it contains until we find the corresponding include
2023-07-20 12:17:32 +02:00
find " $dir " -name "*.adoc" ! -name 'tmp_*.adoc' -execdir sed -r -n -e 's/^:(\w+):\s+([A-Za-z0-9\/._-]+)$/\1\t\2/p' { } \; > vars
2023-06-02 19:10:20 +02:00
# Directly included
2023-07-20 12:17:32 +02:00
find " $dir " -name "*.adoc" ! -name 'tmp_*.adoc' -execdir sh -c 'grep -h "include::" "$1" | grep -Ev "{\w+}" | grep -v "rule.adoc" | sed -r "s/include::(.*)\[\]/\1/" | xargs -r -I@ realpath "$PWD/@"' shell { } \; > included
2023-06-02 19:10:20 +02:00
# Included through variable
2023-07-31 15:11:14 +02:00
VARS_FULL_PATH = $( realpath vars) PATH_WITH_VARIABLE = ${ PATH_WITH_VARIABLE } find " $dir " ! -name 'tmp_*.adoc' -name "*.adoc" -execdir sh -c 'grep -Eh "include::.*\{" "$1" | xargs -r -I@ $PATH_WITH_VARIABLE $VARS_FULL_PATH "@" | xargs -r -I@ realpath "$PWD/@"' shell { } \; >> included
2023-07-20 12:17:32 +02:00
# We should only include documents from the same rule or from shared_content
cross_references = $( grep -vEh " ${ ROOT } \/ ${ dir } \/| ${ ROOT } \/shared_content\/ " included)
if [ [ -n " $cross_references " ] ] ; then
2023-07-31 15:11:14 +02:00
printf 'ERROR: Rule %s tries to include content from unallowed directory:\n%s\nTo share content between rules, you should use the "shared_content" folder at the root of the repository\n' " $dir " " $cross_references "
exit_code = 1
2023-07-20 12:17:32 +02:00
fi
2022-02-07 18:22:30 +01:00
find " $dir " -name "*.adoc" ! -name 'rule.adoc' ! -name 'tmp*.adoc' -exec sh -c 'realpath $1' shell { } \; > created
2022-02-01 13:25:23 +01:00
orphans = $( comm -1 -3 <( sort -u included) <( sort -u created) )
if [ [ -n " $orphans " ] ] ; then
2023-07-31 15:11:14 +02:00
printf 'ERROR: These adoc files are not included anywhere:\n-----\n%s\n-----\n' " $orphans "
exit_code = 1
2022-02-01 13:25:23 +01:00
fi
2023-06-02 19:10:20 +02:00
rm -f included created vars
2021-01-07 17:15:42 +01:00
fi
2020-06-23 11:33:04 +02:00
done
2022-02-07 18:22:30 +01:00
ADOC_COUNT = $( find rules -name "tmp*.adoc" | wc -l)
2023-07-31 15:11:14 +02:00
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:11:14 +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-31 15:11:14 +02:00
2023-07-20 12:17:32 +02:00
find rules -name "tmp*.adoc" -delete
2022-02-01 13:25:23 +01:00
if ( ( exit_code = = 0 ) ) ; then
2023-07-31 15:11:14 +02:00
echo "Success"
2021-06-09 11:15:47 +02:00
else
2023-07-31 15:11:14 +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