The linter rules all catcrafts projects use
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jorijn van der Graaf 88139fc0fc
Initial import: the house-style lint rules as a crafter-build module
Moved out of Crafter.Build's lint-rules.h so a project.cpp pulls them in
with `#pragma crafter dependency` + `import Crafter.LintRules;` instead of
copying a header. The rule bodies are unchanged; format-concat now sits
with the other transforms (it rewrites, it was registered as a report),
and the helpers are module-internal. tests/HouseRules moved along with
the rules and links crafter-build from git, or the sibling checkout with
--local.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 20:03:24 +02:00
interfaces Initial import: the house-style lint rules as a crafter-build module 2026-10-02 20:03:24 +02:00
tests/HouseRules Initial import: the house-style lint rules as a crafter-build module 2026-10-02 20:03:24 +02:00
.gitignore Initial import: the house-style lint rules as a crafter-build module 2026-10-02 20:03:24 +02:00
LICENSE Initial import: the house-style lint rules as a crafter-build module 2026-10-02 20:03:24 +02:00
LICENSE.GPL Initial import: the house-style lint rules as a crafter-build module 2026-10-02 20:03:24 +02:00
project.cpp Initial import: the house-style lint rules as a crafter-build module 2026-10-02 20:03:24 +02:00
README.md Initial import: the house-style lint rules as a crafter-build module 2026-10-02 20:03:24 +02:00

Crafter.LintRules

The Catcrafts house-style lint rules for crafter-build, packaged as one C++ module. Naming conventions, K&R braces, enum class, std::println over iostream, fixed-width integer types, std::format over concatenation, line wrapping, whitespace hygiene and a few AST-backed checks (const locals, constexpr constants, no char*). Most rules are transforms, so crafter-build format applies them.

Use

In a project.cpp:

import std;
import Crafter.Build;
#pragma crafter dependency "https://forgejo.catcrafts.net/Catcrafts/Crafter.LintRules.git"
import Crafter.LintRules;
using namespace Crafter;

extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> args) {
    Configuration cfg;
    // ...
    LintRules::AddRules(cfg);
    return cfg;
}

Then crafter-build lint reports, crafter-build format rewrites, and crafter-build format --check gates CI. Pin a revision for reproducible builds:

#pragma crafter dependency "https://forgejo.catcrafts.net/Catcrafts/Crafter.LintRules.git" commit "<sha>"

Suppress a finding with // lint-disable-next-line <rule> or a whole file with // lint-disable-file <rule>.

Rules

Rule Kind What it wants
spdx-header report // SPDX-License-Identifier: on line 1, // SPDX-FileCopyrightText: on line 2, blank line 3
no-tabs report spaces
naming report, AST PascalCase types, functions, statics and constants; camelCase variables
enum-class report enum class, never a plain enum
no-iostream-print report std::println instead of std::cout/std::cerr streaming
no-char-pointer report, AST std::string / std::string_view over char* outside C interop
const-local report, AST const on a scalar local that is never written
constexpr-constant report, AST constexpr on a constant with a constant initialiser
format-concat transform std::format instead of + with string literals
fixed-width-types transform, AST std::int32_t and friends instead of int, long, …
single-declaration transform, AST one declaration per statement
brace-style transform K&R braces
if-single-line transform if (x) return; on one line when it fits
wrap-join transform join wrapped statements that fit on one line
paren-spacing transform if ( and for (, no space before a call's (
trim-trailing-ws transform no trailing whitespace
final-newline transform files end with a newline

Tests

tests/HouseRules exercises every rule against small inputs. It links crafter-build to run the linter in-process, so it fetches and builds it from git; with a sibling checkout at ../Crafter.Build use crafter-build test --local.

Building for other targets

The module imports Crafter.Build, which only exists for the host. That is all a rule ever needs: rules run inside the crafter-build process that loads your project.cpp.