From 74eeb411ba4c6d2e250db550c64508d21f9e0e02 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 31 Jul 2026 14:35:40 +0000 Subject: [PATCH] Add luacheck config + lint script Introduce a tuned .luacheckrc and scripts/lint.sh so the engine has a standing static-analysis baseline -- the tool that would have caught both bugs in the previous commit before they shipped. The config is high-signal by design: it keeps the categories that catch real defects (undefined globals/locals, unused values, unreachable code) and mutes the cosmetic ones the codebase deliberately lives with (a self/dt an interface requires but a method ignores, documented empty fall-through branches, long lines). It marks `love` mutable (games assign callbacks onto it) and teaches it LuaJIT's table.unpack. .luacheckrc is tracked via a .gitignore exception, matching how .github and .gitignore opt out of the blanket dotfile ignore. `luacheck src` now reports 7 benign warnings and 0 errors, down from 185. Also drop one dead `require` (ItemEffects loaded src.pokemon.Pokemon and never used it). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Q6bFAiQyZ5jDmewsbB4LG9 --- .gitignore | 1 + .luacheckrc | 43 +++++++++++++++++++++++++++++++++++ scripts/lint.sh | 23 +++++++++++++++++++ src/inventory/ItemEffects.lua | 1 - 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 .luacheckrc create mode 100755 scripts/lint.sh diff --git a/.gitignore b/.gitignore index ab7ceda5..59022aa0 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ __pycache__/ .* !.github/ !.gitignore +!.luacheckrc # Android build outputs / local SDK path / packaged payload (keep love-android sources) mobile/android/app/build/ diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 00000000..3d7f91a1 --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,43 @@ +-- Static-analysis config for `luacheck` (https://luacheck.readthedocs.io). +-- +-- Run it over the engine with: luacheck src (or scripts/lint.sh) +-- +-- The point is a high-signal baseline: the categories left on are the ones +-- that catch real defects -- undefined globals/locals (the class that hid a +-- `music.volume` crash: applyVolume read a `state` that was still the nil +-- global), unused values, unreachable code, redefinitions. The cosmetic +-- categories the codebase deliberately lives with (a `self`/`dt` an +-- interface requires but a given method ignores, documented empty +-- fall-through branches, the odd long line) are muted so they don't drown +-- the signal. + +std = "luajit" + +-- LÖVE exposes `love` as a mutable table: games assign their callbacks onto +-- it (love.wheelmoved, love.run, ...), so it is a regular global, not +-- read-only -- otherwise every callback registration reads as a violation. +globals = { "love" } + +read_globals = { + "jit", + -- LuaJIT 2.1 ships table.unpack even though the bare 5.1 `table` std lacks + -- it; without this, every `table.unpack` reads as an undefined field. + table = { fields = { "unpack" } }, +} + +-- Vendored/native trees and the test suites have their own conventions. +exclude_files = { + "mobile/", + "tests/", + "tools/save-editor/", +} + +ignore = { + "212", -- unused argument -- self/dt kept for a shared method signature + "213", -- unused loop variable -- `for _, v in` where only v is wanted + "421", -- shadowing a local -- deliberate re-use in a few tight scopes + "431", -- shadowing an upvalue + "432", -- shadowing an argument + "542", -- empty if branch -- documented fall-throughs, not gaps + "631", -- line is too long +} diff --git a/scripts/lint.sh b/scripts/lint.sh new file mode 100755 index 00000000..bf2ece34 --- /dev/null +++ b/scripts/lint.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# Static analysis for the engine Lua (config: .luacheckrc). +# +# Complements scripts/test.sh: the tests prove behavior, luacheck catches the +# defects that never run in a green test -- undefined globals/locals (the +# class that hid a music.volume crash: a hook read a `state` that was still +# the nil global), unused values, unreachable code. The .luacheckrc mutes the +# cosmetic categories the codebase lives with, so what prints is worth a look. +# +# scripts/lint.sh lint src/ +# scripts/lint.sh src tools lint specific paths +# +# Install once with: luarocks install luacheck + +set -uo pipefail +cd "$(dirname "$0")/.." + +if ! command -v luacheck >/dev/null 2>&1; then + echo "luacheck not found on PATH (install: luarocks install luacheck)" >&2 + exit 2 +fi + +luacheck "${@:-src}" diff --git a/src/inventory/ItemEffects.lua b/src/inventory/ItemEffects.lua index 50d40b71..a7bb8588 100644 --- a/src/inventory/ItemEffects.lua +++ b/src/inventory/ItemEffects.lua @@ -10,7 +10,6 @@ -- "ball" caller must throw it (battle only) -- "learn", moveId caller must run the learn-move flow -local Pokemon = require("src.pokemon.Pokemon") local Flags = require("src.script.Flags") local Strings = require("src.core.Strings")