Checks Enma scripts and the C++ host that embeds them against the Enma Style Guide and reports every finding with its rule ID, linked to the rule:
scripts/Gameplay/Spawner.em:12:3: MUST ENMA-06.1: `unsigned` is not an Enma type; use a sized type (int16, int64, uint32, ...) [chopper]
Project/src/Project/Scripting/ScriptEngine.cpp:58:5: MUST ENMA-13.2: configure the engine before the first compile, not enma::add_module_path after it [chopper]
It runs two kinds of check:
- clang-format over
.emscripts and host sources, with the repository's.clang-format(chapter 5: scripts use the host's config). Lines inside amatchexpression are left alone, since the formatter mangles=>; format those by hand or between// clang-format offand// clang-format on. - The guide's own checks. In scripts: naming, sized types and casts, strings and literals, imports, namespaces and macros,
new/deletepairing, exceptions, annotations, tests (Test*functions,heap_count(), asserts with messages), the entry module, and Perception scripts (routines, process access and permissions, render handles, absolute addresses and signature tables). In the host: native registration (ENMA_SIG, sized signatures, area names,noexcept, argument checks, theNatives/folder), addons, checked SDK results, engine configuration and teardown order, permissions, and the premake build (CRT library,/STACK, addon sources).checks.jsonlists them all.
General C++ style for the host (formatting details, clang-tidy, headers, naming) is the C++ guide's: run the C++ kit (carson-hopper/chopper.dev/content/styleguides/cpp/lint) on the host too, and pass --no-host-format here so the host is not formatted twice. The guide names no Enma linter of its own; compiler and language-server diagnostics (ENMA-05.2, ENMA-05.3) come from compiling every script in CI, as the template's tests do.
Run it
Needs Python 3.9+, and clang-format for the formatting check (the template pins 19.1.7: pip install clang-format==19.1.7).
python3 chopper_lint.py # the current folder
python3 chopper_lint.py scripts Project/src # some folders
python3 chopper_lint.py --code PRJ --strict # set the host's macro prefix; fail on SHOULD too
python3 chopper_lint.py --no-host-format # format only .em files
python3 chopper_lint.py --list-checks # what it checks
The host's macro prefix (for ENMA-11.10) is the most common prefix in the host's #defines unless --code sets it. Folders named vendor, third_party, external, build, bin and bin-int are skipped. Committed .emb files and the premake checks are looked for only when the repository root is linted.
Exit status: 1 when a MUST or MUST NOT rule is broken (any finding with --strict), else 0.
In GitHub Actions
- uses: actions/checkout@v4
- uses: carson-hopper/chopper.dev/content/styleguides/enma/lint@main
# with:
# paths: scripts Project/src
# code: PRJ
Findings appear as annotations on the pull request. Pin @main to a commit SHA for reproducible runs.
Silencing a finding
On the same line or the line above, with a reason:
[[dll("kernel32.dll")]] extern uint32 GetTickCount(); // chopper-lint: allow ENMA-12.5 (tooling host, PERM_FFI)
For a whole file: // chopper-lint: allow-file ENMA-12.5.