tools: add a luacheckrc generator

tools/make-luacheck-files.sh will generate a .luacheckrc with the
following rules:
 - any rules set in the project header (.luacheck.head)
 - each mod is allowed to use a single global sharing its mod name
 - mod dependency information is parsed, and those mods' globals are
   permitted for read access
master
E 2021-05-03 11:24:35 -04:00
parent 3ee2ef0618
commit 0c13293f43
2 changed files with 112 additions and 0 deletions

17
.luacheck.head Normal file
View File

@ -0,0 +1,17 @@
std = "min"
read_globals = {
"ItemStack",
"dump", "dump2",
"vector",
"VoxelArea",
"minetest",
"PseudoRandom",
"PerlinNoise",
"PcgRandom",
string = {fields = {"split", "trim"}},
table = {fields = {"copy", "getn", "indexof", "insert_all"}},
math = {fields = {"hypot", "round"}},
}

95
tools/make-luacheck-files.sh Executable file
View File

@ -0,0 +1,95 @@
#!/bin/sh
#
# make-luacheck-files.sh
# v1 - E - Initial version
set -ue
if [ ! -d "mods" ] || [ ! -r ".luacheck.head" ]; then
printf "error: this script needs to be run from the mineclonia project root\n" 1>&2
exit 1
fi
# We need these to be explicitly NOT expanded.
# shellcheck disable=2016
{
# This creates a luacheckrc-compatible line from a mod (supplied on
# the command line with -v MOD="mod_name"), a directory (-v DIR="..."),
# and a list of dependencies (via STDIN). The `read_globals` section is
# skipped if there are no dependencies (-v EMPTY=1).
AWK_DEPS2LCHECK='
BEGIN {
printf("files[\"" DIR "\"] = { globals = { \"" MOD "\" }");
if (!EMPTY) {
printf(", read_globals = { ");
}
};
# Without a pattern, this will match on empty lines
# and mess up the entry. We clean up the extra commas
# later in the script.
/.+/{
sub("?$", "");
sub("\xd", "");
printf("\"" $1 "\", ");
};
END {
if (!EMPTY) {
printf("}");
}
printf(" }\n");
};'
# This takes any line that contains 'depends' and an equal sign
# and spits out each (comma-separated) entry on its own line.
SED_MODCONF2DEPS='
/depends *=/{
s/.*depends *=//;
s/, ?/\n/g;
p;
}'
HEADER='
-------------------------------------------------------------------
-- THIS FILE WAS AUTOGENERATED BY tools/make-luacheck-files.sh ! --
-- DO NOT EDIT BY HAND. YOUR CHANGES WILL BE LOST NEXT RUN! --
-------------------------------------------------------------------
'
}
find mods -type d -print | while read -r DIR; do
if [ -r "$DIR/depends.txt" ]; then
printf "found: %s (%s)\n" "$DIR" "depends.txt" 1>&2
# depends.txt is a simple newline-delimited file,
# so we can just read it in.
DEPS="$(cat "$DIR/depends.txt")"
elif [ -r "$DIR/mod.conf" ]; then
printf "found: %s (%s)\n" "$DIR" "mod.conf" 1>&2
# mod.conf needs some more help to get usable
# data out of it.
DEPS="$(sed -n -r -e "$SED_MODCONF2DEPS" "$DIR/mod.conf")"
else
# Empty dir, or not a mod dir.
continue
fi
EMPTY=0
if [ -z "$DEPS" ]; then
EMPTY=1
fi
# Get only the last chunk of the directory
# for the mod name.
MOD="${DIR##*/}"
# Now we run through it through the formatter,
# and remove any rogue trailing commas.
{ awk -v DIR="$DIR" -v EMPTY="$EMPTY" -v MOD="$MOD" -- "$AWK_DEPS2LCHECK" | sed -e "s/, }/ }/"; } <<-EOF
$DEPS
EOF
done > .luacheck.files
# Put the final thing together with the warning header
{ printf "%s" "$HEADER"; cat .luacheck.head .luacheck.files; } > .luacheckrc