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")