From 0c13293f431f0e2379ea062db1abd04484f92ef2 Mon Sep 17 00:00:00 2001 From: E Date: Mon, 3 May 2021 11:24:35 -0400 Subject: [PATCH] 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 --- .luacheck.head | 17 +++++++ tools/make-luacheck-files.sh | 95 ++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 .luacheck.head create mode 100755 tools/make-luacheck-files.sh diff --git a/.luacheck.head b/.luacheck.head new file mode 100644 index 00000000..bf49be42 --- /dev/null +++ b/.luacheck.head @@ -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"}}, +} + diff --git a/tools/make-luacheck-files.sh b/tools/make-luacheck-files.sh new file mode 100755 index 00000000..fa954ff7 --- /dev/null +++ b/tools/make-luacheck-files.sh @@ -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