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>
This commit is contained in:
commit
88139fc0fc
7 changed files with 2436 additions and 0 deletions
60
README.md
Normal file
60
README.md
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# Crafter.LintRules
|
||||
|
||||
The Catcrafts house-style lint rules for [crafter-build](https://forgejo.catcrafts.net/Catcrafts/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`:
|
||||
|
||||
```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:
|
||||
|
||||
```cpp
|
||||
#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`.
|
||||
Loading…
Reference in a new issue